[카테고리:] 생활코딩

  • 화면 보호기 동작 방지 with PowerShell

    화면 보호기를 막아야 할 필요가 있다. 아래 링크에서 관련 자료를 얻었다.

    https://codingpark.tistory.com/44
    https://gupu.tistory.com/1

    출처가 설명을 제대로 하지 않아, 적용하기 어려웠다. PowerShell에 최대한 짧게 입력했다. scroll lock키를 무한 동작

    $wshell=New-Object -ComObject wscript.shell; //이거 없으면 키 입력을 만들 수 없음.
    while($true)
    {
    $wshell.sendkeys("{SCROLLLOCK}");  //키 값 확인.
    Start-Sleep -Seconds 100;
    }
  • 5장 인터럽트, p345 실습

    책이 dwc_otg_driver.c의 request_irq로 인터럽트를 등록을 설명했다. 그러나, 라즈베리 파이4가 dwc-otg_driver.c 함수를 사용하지 않는다. 있긴 있는데, 4로 오면서 의도적으로 사용하지 않는 듯 하다. 아무리 찾아봐도 request_irq를 dump_stack 메세지에서 찾을 수 없다. 내가 본 메세지는 다음과 같다.

    Jun 14 07:38:24 raspberrypi kernel: [    0.547246] xhci_hcd 0000:01:00.0: hcc params 0x002841eb hci version 0x100 quirks 0x0000001000000890
    Jun 14 07:38:24 raspberrypi kernel: [    0.550250] [+][irq_debug] irq_num: 53, func: request_threaded_irq, line: 1888, caller: xhci_run+0x240/0x670
    Jun 14 07:38:24 raspberrypi kernel: [    0.552941] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.19.127-v7l+ #78
    Jun 14 07:38:24 raspberrypi kernel: [    0.555588] Hardware name: BCM2835
    Jun 14 07:38:24 raspberrypi kernel: [    0.558290] [<c0212dd8>] (unwind_backtrace) from [<c020d3ec>] (show_stack+0x20/0x24)
    Jun 14 07:38:24 raspberrypi kernel: [    0.561023] [<c020d3ec>] (show_stack) from [<c09c01dc>] (dump_stack+0xd8/0x11c)
    Jun 14 07:38:24 raspberrypi kernel: [    0.563706] [<c09c01dc>] (dump_stack) from [<c0285ae0>] (request_threaded_irq+0x1b4/0x1b8)
    Jun 14 07:38:24 raspberrypi kernel: [    0.566425] [<c0285ae0>] (request_threaded_irq) from [<c07b4530>] (xhci_run+0x240/0x670)
    Jun 14 07:38:24 raspberrypi kernel: [    0.569178] [<c07b4530>] (xhci_run) from [<c079bd6c>] (usb_add_hcd+0x324/0x7ac)
    Jun 14 07:38:24 raspberrypi kernel: [    0.571892] [<c079bd6c>] (usb_add_hcd) from [<c07afa84>] (usb_hcd_pci_probe+0x278/0x398)
    Jun 14 07:38:24 raspberrypi kernel: [    0.574625] [<c07afa84>] (usb_hcd_pci_probe) from [<c07cc760>] (xhci_pci_probe+0x3c/0x180)
    Jun 14 07:38:24 raspberrypi kernel: [    0.577382] [<c07cc760>] (xhci_pci_probe) from [<c067d008>] (pci_device_probe+0xb0/0x138)
    Jun 14 07:38:24 raspberrypi kernel: [    0.580118] [<c067d008>] (pci_device_probe) from [<c0718f3c>] (really_probe+0x20c/0x2cc)
    Jun 14 07:38:24 raspberrypi kernel: [    0.582911] [<c0718f3c>] (really_probe) from [<c07191d0>] (driver_probe_device+0x70/0x188)
    Jun 14 07:38:24 raspberrypi kernel: [    0.585734] [<c07191d0>] (driver_probe_device) from [<c07193e4>] (__driver_attach+0xfc/0x100)
    Jun 14 07:38:24 raspberrypi kernel: [    0.588587] [<c07193e4>] (__driver_attach) from [<c0716e48>] (bus_for_each_dev+0x84/0xc4)
    Jun 14 07:38:24 raspberrypi kernel: [    0.591438] [<c0716e48>] (bus_for_each_dev) from [<c07187c8>] (driver_attach+0x2c/0x30)
    Jun 14 07:38:24 raspberrypi kernel: [    0.594277] [<c07187c8>] (driver_attach) from [<c0718248>] (bus_add_driver+0x1d0/0x214)
    Jun 14 07:38:24 raspberrypi kernel: [    0.597086] [<c0718248>] (bus_add_driver) from [<c0719bc4>] (driver_register+0x84/0x118)
    Jun 14 07:38:24 raspberrypi kernel: [    0.599945] [<c0719bc4>] (driver_register) from [<c067c2e0>] (__pci_register_driver+0x58/0x5c)
    Jun 14 07:38:24 raspberrypi kernel: [    0.602852] [<c067c2e0>] (__pci_register_driver) from [<c0e3f6cc>] (xhci_pci_init+0x68/0x6c)
    Jun 14 07:38:24 raspberrypi kernel: [    0.605785] [<c0e3f6cc>] (xhci_pci_init) from [<c0203004>] (do_one_initcall+0x50/0x220)
    Jun 14 07:38:24 raspberrypi kernel: [    0.608748] [<c0203004>] (do_one_initcall) from [<c0e01374>] (kernel_init_freeable+0x340/0x3e0)
    Jun 14 07:38:24 raspberrypi kernel: [    0.611723] [<c0e01374>] (kernel_init_freeable) from [<c09d5590>] (kernel_init+0x18/0x128)
    Jun 14 07:38:24 raspberrypi kernel: [    0.614684] [<c09d5590>] (kernel_init) from [<c02010ac>] (ret_from_fork+0x14/0x28)
    Jun 14 07:38:24 raspberrypi kernel: [    0.617678] Exception stack(0xefa61fb0 to 0xefa61ff8)
    • 일단 request_threaded_irq가 request_irq임은 확실하다.
    • xhci_run이 request_threaded_irq를 호출한다.
    • usb_add_hcd가 xhci_run을 호출한다.
    • … 이런 식으로 kernel_init로 간다.
    • 결국 시스템 시작할 때 인터럽트를 등록한다.

    문제가 책 예시와 다르게, 누가 request_irq를 실행하는지 모르는 점이다. dump_stack이 미리 정의되지 않은 함수는 보여주지 않는 듯 하다. 찾아보면 알겠지만 msi가 드라이버를 만들었다. xhci_run, usb_add_hcd, usb_hcd_pci_probe 등 여러 함수 중 request_irq를 콜하는 부분을 쉽게 찾을 수 없었다. 그러나 시간이 많은 나는 결국 xhci_run의 xhci_setup_msi가 requset_irq를 함을 찾아냈다.

    /*
     * Set up MSI
     */
    static int xhci_setup_msi(struct xhci_hcd *xhci)
    {
        int ret; 
        /*   
         * TODO:Check with MSI Soc for sysdev
         */
        struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
    
        ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
        if (ret < 0) { 
            xhci_dbg_trace(xhci, trace_xhci_dbg_init,
                    "failed to allocate MSI entry");
            return ret; 
        }    
    
        ret = request_irq(pdev->irq, xhci_msi_irq,
                    0, "xhci_hcd", xhci_to_hcd(xhci));
        //210611 irq 추가...
        interrupt_debug_irq_desc(pdev->irq);
    
    
        if (ret) {
            xhci_dbg_trace(xhci, trace_xhci_dbg_init,
                    "disable MSI interrupt");
            pci_free_irq_vectors(pdev);
        }    
    
        return ret; 
    }

    이렇게 설정 후 컴파일 하면, 메세지가 제대로 출력된다. 교재와 다르게 인터럽트 53번으로 설정한다.

    Jun 14 07:38:24 raspberrypi kernel: [    0.626769] 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000
    Jun 14 07:38:24 raspberrypi kernel: [    0.629855] genirq: irq_chip Brcm_MSI did not update eff. affinity mask of irq 53
    Jun 14 07:38:24 raspberrypi kernel: [    0.632884] [+] irq_desc debug start
    Jun 14 07:38:24 raspberrypi kernel: [    0.635920] irq num: 53 name: xhci_hcd
    Jun 14 07:38:24 raspberrypi kernel: [    0.638938] dev_id:0xefa55000
    Jun 14 07:38:24 raspberrypi kernel: [    0.641924] interrupt handler: xhci_msi_irq+0x0/0x20
    Jun 14 07:38:24 raspberrypi kernel: [    0.644914] [-] irq_desc debug end

    몇 번 해보면서 느꼈는데, 꼬리에 꼬리를 물어 원하는 부분을 찾아내는 능력이 필요해 보인다. 그래야 그 부분을 수정하여 원하는 기능을 구현할 수 있으니까.

  • 과학하고 앉아있네 podcast 다운로드 + plex 관리 스크립트

    과학하고 앉아있네 podcast 다운로드 + plex 관리 스크립트

    과거 쎈호스팅에서 mp3를 다운로드를 제공했었는데, 팟빵 앱으로 접근하지 않는 사용자들을 제약하려고 주소를 옮겼다. 겨우 찾았는데, 쎈호스팅과 과학과사람들이 어떤 일을 했는지 이후 다운로드 서비스도 하고 있지 않았다. 귀찮아 방치했는데, 하드디스크로 바꾼 기념으로 찾아보니, 홈페이지가 rss를 제공하고 있었다.

    bash로 xml을 parsing하기 힘들어 xpath 도움을 받았다. xpath를 쓰지 않았을 때 정규표현식으로 억지로 뽑아냈다. xmllint도 있는데, 맨 처음 한 개만 제대로 출력하고 이 후 정보를 무시해버려 시간만 날렸다. 몇 시간 노가다 끝에 다음 방식으로 정리했다. 과거 노가다보다 훨씬 정확하고 보람차다.

    #!/bin/bash
    #cron을 위한 cd
    cd ???
    
    echo "TEDTalks Downloader v0.1"
    echo "by Denver Gingerich (http://ossguy.com/)"
    
    
    which wget
    if [ $? -eq 0 ]; then
    	echo "Using wget..."
    	GET_CMD="wget --quiet -O"
    else
    	which curl
    	if [ $? -eq 0 ]; then
    		echo "Using curl..."
    		GET_CMD="curl -L -o"
    	else
    		echo "Could not find wget or curl"
    		exit 2
    	fi
    fi
    
    FEED=feed_podcast.xml
    URLS=urls_podcast
    DIRNAME=파토의과학
    
    rm -f ${FEED}
    rm -f ${URLS}
    
    #podcast_address=http://www.podbbang.com/ch/6205
    podcast_address=https://feeds.feedburner.com/sciencewithpeople
    ${GET_CMD} ${FEED} ${podcast_address}
    
    #xpath 
    #get nth item
    #xpath -e "//rss/channel/item[position()=2]/title" temp2.txt
    patoCouter=10;
    #과학과사람들fileInfo.txt 만듦.
    #filename, path, title, 업데이트일 순으로 정리
    for i in $(seq 1 $patoCouter);
    do
    	#echo $i
    	title=$(xpath -q -e "//rss/channel/item[position()=$i]/title" ${FEED})
    	title2=$(echo $title | sed 's/<title>//g' | sed 's/<\/title>//')
    	title3=$(echo $title2 | sed 's/  / /g' | sed 's/,/_/g')
    	#echo $title3
    
    	fileTmp=$(xpath -q -e "//rss/channel/item[position()=$i]/enclosure" ${FEED})
    	file=$(echo $fileTmp | cut -d'"' -f2)
    	#echo $file
    
    	pubTmp=$(xpath -q -e "//rss/channel/item[position()=$i]/pubDate" ${FEED})
    	pub=$(echo $pubTmp| sed 's/<pubDate>//g' | sed 's/<\/pubDate>//'| cut -d',' -f2 | cut -d' ' -f1-4 | sed 's/^ //g')
    	#monthtmp=$(echo $pub | cut -d'-' -f2)
    	#daytmp=$(echo $pub | cut -d'-' -f1)
    	#yeartmp=$(echo $pub | cut -d'-' -f3)
    	#echo $pubTmp
    	echo $pub
    	#echo $monthtmp
    	#from
        #https://www.unix.com/shell-programming-and-scripting/191527-converting-month-into-integer.html
        #M=1
        #for X in Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
        #do
    	#	[ "$monthtmp" = "$X" ] && break
    	#	M=`expr $M + 1`
    	#done
    	#myeardate=$(date --date="$(printf "%s" $yeartmp-$M-$daytmp)" +"%Y-%m-%d")
    	#echo $myeardate
    
    	printf "$title3" >> ${URLS}
    	printf "," >> ${URLS}
    	printf "$file" >> ${URLS}
    	printf "," >> ${URLS}
    	printf "$pub" >> ${URLS}
    	printf "\n" >> ${URLS}
    
    done
    
    cp ${URLS} ${DIRNAME}/파토가과학하고앉아있네FileAndTitle.txt
    
    mkdir -p ${DIRNAME}
    cd ${DIRNAME}
    for line in $(cat ../${URLS} | cut -d',' -f2);
    do
    	URL=$(echo ${line} | cut -d',' -f2)
    	FILENAME=`basename ${URL}|tr -d '\r'`
    	if [ ! -f "${FILENAME}" ]; then
    #	 || [ ${SIZE} -ne `ls -l "${FILENAME}" | awk '{print $5}'` ]; then
    		rm -f "${FILENAME}"
    		${GET_CMD} "${FILENAME}" "${URL}"
    	fi
    done

    plex media server가 정확하게 인식하도록 id3 태그를 각 파일에 입력했다.

    now0930@gen8:파토의과학$ ls -t
    파토가과학하고앉아있네FileAndTitle.txt  174371_1619141878558.mp3  174371_1621561758166.mp3  174371_1616052641424.mp3  174371_1617934621403.mp3  174371_1620965968488.mp3  details.txt
    174371_1616979006251.mp3                174371_1620359306326.mp3  174371_1622166509979.mp3  174371_1618471405918.mp3  174371_1617304165488.mp3  conver.jpg

    파토가과학하고앉아있네FileAndTitle.txt 파일은 id3를 입력할 수 있는 파일, 태그, 날자 데이터다.

    now0930@gen8:파토의과학$ cat 파토가과학하고앉아있네FileAndTitle.txt | head -10
    삼테성즈 S7E04 반도체 대란_ KF21 핵심기술 그리고 게임의 역사2!,https://cdn-cf.podty.me/meta/episode_audio/22286/174371_1622166509979.mp3,28 May 2021
    과학하고 앉아있네 S7E04 K박사 완전 복귀 특집! 암흑의 물질과 K박사의 어두운 미래,https://cdn-cf.podty.me/meta/episode_audio/22286/174371_1621561758166.mp3,21 May 2021
    격동 500년! S7E04 세계적인 나비박사 석주명 선생!,https://cdn-cf.podty.me/meta/episode_audio/22286/174371_1620965968488.mp3,14 May 2021
    뉴스룸! S7E04 생명연장의 시간표_ 그리고 나의 뇌를 다스리자! feat. 카이스트 김대수 교수,https://cdn-cf.podty.me/meta/episode_audio/22286/174371_1620359306326.mp3,07 May 2021
    삼테성즈 S7E03 화제의 메타버스 특집! Feat. 강원대 김상균 교수,https://cdn-cf.podty.me/meta/episode_audio/22286/174371_1619141878558.mp3,23 Apr 2021
    과학하고 앉아있네 S7E03 빛은 뭐고 LCD는 뭐고 OLED는 또 뭐냐? feat. 한림대 고재현 교수,https://cdn-cf.podty.me/meta/episode_audio/22286/174371_1618471405918.mp3,16 Apr 2021
    격동 500년! S7E03 태양의 정체를 밝히다! 세실리아 페인.,https://cdn-cf.podty.me/meta/episode_audio/22286/174371_1617934621403.mp3,09 Apr 2021
    뉴스룸! S7E03 화성 퍼시비어런스 엠바고 속보! 그리고 자연계 5번째의 힘 발견? feat. 박인규 교수,https://cdn-cf.podty.me/meta/episode_audio/22286/174371_1617304165488.mp3,02 Apr 2021
    (음질보정재업) 삼테성즈! S7E02 딥페이크_ 전기자동차_ NFT_ 비디오게임. Feat. K2박사_ 최팀장,https://cdn-cf.podty.me/meta/episode_audio/22286/174371_1616979006251.mp3,28 Mar 2021
    과학하고 앉아있네 S7E02 코로나백신 완전 털기! feat. 남재환 교수_ 김연희 기자,https://cdn-cf.podty.me/meta/episode_audio/22286/174371_1616052641424.mp3,19 Mar 2021

    details.txt 파일은 각 디렉토리별 어떻게 입력할지 대한 규칙이다. 각 폴더마다 스크립트를 다르게 사용할 수 없어, details.txt로 각 폴더 규칙을 정리했다.

    now0930@gen8:파토의과학$ cat details.txt 
    SONGEXP	$(cat $EXTRAINFO | grep $FILE | cut -d',' -f1)
    tmpSONGEXP	$(cat $EXTRAINFO | grep $FILE | cut -d$'\t' -f2)
    ARTISTEXP	"파토"
    ALBUMEXP	"파토가과학하고앉아있네"
    mYearDateEXPtmp	"2020-1-1"
    mYearDateEXP	$(cat $EXTRAINFO | grep $FILE | cut -d',' -f3)
    GENREEXP	"팟캐스트"
    FILETYPE	"mp3"
    PODCASTFILE	파토가과학하고앉아있네FileAndTitle.txt

    id3를 업데이트 하는 스크립트를 실행하면 각 폴더에 설정한 details.txt를 읽어 업데이트 한다. 이전에 이 내용을 포스트했다. 다 하고나니 이렇게까지 해야 하나 싶다. 관리하기 참 까다롭다. plex media server 스캐너까지 관리하고 싶은데, 어떻게 하는지 모르겠다. 모두 하면 다음과 같이 관리할 수 있다.

  • linux kernel 중 container_of 이해와 사용

    linux kernel 중 container_of 이해와 사용

    container_of를 사용하여 double linked list로 연결된 task_struct가 가진 다른 멤버에 접근할 수 있다. 자세한 원리는 모르겠지만, 컴파일러가 offset을 고정시키는데, 구조체를 미리 알고 있기때문에, 거꾸로 세어 나가는 원리인 듯 하다. 이것은 기술인가? 잔머리인가? 두 번 탐색하지 않아도 되기 때문에 많은 부분에서 사용된다 한다.

    유저 프로세스 raspbian_proc가 printf로 글자를 출력하고, sleep으로 3초동안 대기한다. 프린트 될 때 wake_up_process 함수를 실행한다. 이 부분에서 list_head로 연결된 next, prev task_struct를 보기로 했다. 잘 안된다.

    싱글 포인터를 사용하면 next 구조체로 접근할 수 없다. double 포인터로 어떻게 어떻게 잘 구해내야 한다. 커널 패치를 하다하다 안되어, 임시로 프로그램을 만들어 gdb로 파 보았다.

    #include <stdio.h>
    #include <stddef.h>
    
    // Copied from linux/kernel.h
    #define container_of(ptr, type, member) ({                      \
    		const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
    		(type *)( (char *)__mptr - offsetof(type,member) );})
    
    
    struct myStruct { int a, b; struct myStruct *next; struct myStruct *prev;char name[10];};
    
    
    
    //struct myStruct { int a, b; };
    
    int main()
    {
    
    	//.은 구조체 내부 멤버를 지칭.
    	struct myStruct var = {.a = 0, .b = 0, .next=NULL, .prev=NULL, .name="first"}; 
    	struct myStruct var2 = {.a = 2, .b = 2, .next=NULL, .prev=NULL, .name="second"}; 
    	struct myStruct var3 = {.a = 3, .b = 3, .next=NULL, .prev=NULL, .name="third"}; 
    
    
    	// next로 기본 값 되는 듯.
    	/*
    	var.ptr = (struct list_head*)&(var2.ptr);
    	var2.ptr = (struct list_head*)&(var3.ptr);
    	var3.ptr = (struct list_head*)&(var.ptr);
    	*/
    
    	var.next = &(var2);
    	var2.next = &(var3);
    	var3.next = &(var);
    
    	var.prev = &(var3);
    	var2.prev = &(var);
    	var3.prev = &(var2);
    
    
    	//var.ptr->prev = (struct list_head*)&(var3.ptr);
    	//var2.ptr->prev = (struct list_head*)&(var.ptr);
    	//var3.ptr->prev = (struct list_head*)&(var2.ptr);
    
    
    	//var2.ptr->prev= var3.ptr;
    	//
    	struct myStruct* target;
    	struct myStruct** tmp;
    	tmp = &(var2.next);
    	tmp = &(*tmp)->next;
    	printf("test name: %s, var address %p, a value = %d\n", (*tmp)->name, *tmp, (*tmp)->a);
    	//var2.next를 가리키는  var3
    	target=container_of((struct myStruct**)tmp, struct myStruct, next); 
    	printf("test2 name: %s, var address %p, a value = %d\n", target->name, target, target->a);
    
    
    	target=container_of(&var.next, struct myStruct, next); 
    	printf("name: %s, var address %p, a value = %d\n", target->name, target, target->a);
    
    	target=container_of(&var2.next, struct myStruct, next); 
    	printf("name: %s, var address %p, a value = %d\n", target->name, target, target->a);
    
    	target=container_of(&var3.next, struct myStruct, next); 
    	printf("name: %s, var address %p, a value = %d\n", target->name, target, target->a);
    
    
    	//prev로 검색.
    	target=container_of(&var.prev, struct myStruct, prev); 
    	printf("name: %s, var address %p, a value = %d\n", target->name, target, target->a);
    
    	target=container_of(&var2.prev, struct myStruct, prev); 
    	printf("name: %s, var address %p, a value = %d\n", target->name, target, target->a);
    
    	target=container_of(&var3.prev, struct myStruct, prev); 
    	printf("name: %s, var address %p, a value = %d\n", target->name, target, target->a);
    
    
    	//int *memberPointer = &var.b;
    //
    //	int *memberPointer = &var.a;
    //
    //	printf("Struct addr=%p\n", &var);
    //
    //	struct myStruct *newSp = container_of(memberPointer, struct myStruct, b); 
    //
    //	printf("Struct addr new=%p\n", newSp);
    //
    //	if(newSp == &var)
    //	{   
    //		printf("It's equal.\n");
    //	}   
    //
    	return 0;
    }
    pi@raspberrypi:~/RaspberryDebug/taskAddress $ ./a.out 
    test name: first, var address 0xbef413e0, a value = 0
    test2 name: third, var address 0xbef413a8, a value = 3
    name: first, var address 0xbef413e0, a value = 0
    name: second, var address 0xbef413c4, a value = 2
    name: third, var address 0xbef413a8, a value = 3
    name: first, var address 0xbef413e0, a value = 0
    name: second, var address 0xbef413c4, a value = 2
    name: third, var address 0xbef413a8, a value = 3

    struct myStruct** tmp;
    tmp = &(var2.next);
    tmp = &(*tmp)->next;

    tmp같이 이중 포인터로 접근해야 var2.next에 해당하는 var3을 target으로 받을 수 있다. 포인터 연산자 우선순위도 좀 신경써야 해서, (*tmp)를 먼저 쓰고 -> 로 next에 접근해야 한다. 너무 헷갈린다. list_head* next, prev도 더블 포인터다. 이를 gdb로 겨우 알아내고, 커널 core.c 코드를 좀 수정했다. 커널을 디버그하면 좋으나, 그런 방법은 없고, trace32나 kgdb등 방법을 찾아야 된다. 비싸거나 힘들다.

    [21:52:04]>cat linux/kernel/sched/core.c  | head -2180 | tail -50
    		ttwu_activate(rq, p, ENQUEUE_WAKEUP | ENQUEUE_NOCLOCK);
    	}
    
    	ttwu_do_wakeup(rq, p, 0, rf);
    	ttwu_stat(p, smp_processor_id(), 0);
    out:
    	raw_spin_unlock(&p->pi_lock);
    }
    
    /**
     * wake_up_process - Wake up a specific process
     * @p: The process to be woken up.
     *
     * Attempt to wake up the nominated process and move it to the set of runnable
     * processes.
     *
     * Return: 1 if the process was woken up, 0 if it was already running.
     *
     * This function executes a full memory barrier before accessing the task state.
     */
    int wake_up_process(struct task_struct *p)
    {
    	//2021. 5. 23추가
    	struct task_struct* tmp;
    	struct list_head **tmp2;
    	if ( !strcmp (p->comm, "raspbian_proc")) {
    		//printk("[+]test activated\n");
    		tmp2 = (struct list_head**)(p->tasks.next);
    		tmp = container_of(tmp2, struct task_struct, tasks.next);
    		printk("[=]pid[%d], [%s] point %p at %p \n",
    				p->pid, p->comm, p->tasks.next, &p->tasks.next);
    		printk("[+]%s point %p at %p\n", tmp->comm, tmp->tasks.next, &tmp->tasks.next);
    		printk("[-]%s point %p at %p\n", tmp->comm, tmp->tasks.prev, &tmp->tasks.prev);
    		//printk("[==]p->task.next: %p, p: %p\n", &p->tasks.next, &p);
    		//
    
    	}
    
    	//2021. 5. 16추가
    
    
    	return try_to_wake_up(p, TASK_NORMAL, 0);
    }
    EXPORT_SYMBOL(wake_up_process);
    
    int wake_up_state(struct task_struct *p, unsigned int state)
    {
    	return try_to_wake_up(p, state, 0);
    }
    pi@raspberrypi:~/RaspberryDebug/process $ ./raspbian_proc 
    raspbian tracing 
    raspbian tracing 
    raspbian tracing 
    [   12.482776] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
    [   12.482790] Bluetooth: BNEP filters: protocol multicast
    [   12.482811] Bluetooth: BNEP socket layer initialized
    [   12.602761] Bluetooth: hci0: unexpected event for opcode 0x0c52
    [   43.549185] [=]pid[659], [raspbian_proc] point fb675b81 at e45574a0 
    [   43.549191] [+]kworker/2:4 point 1d830555 at fb675b81
    [   43.549195] [-]kworker/2:4 point e45574a0 at 71182716
    [   46.549300] [=]pid[659], [raspbian_proc] point fb675b81 at e45574a0 
    [   46.549309] [+]kworker/2:4 point 1d830555 at fb675b81
    [   46.549317] [-]kworker/2:4 point e45574a0 at 71182716
    [   49.549442] [=]pid[659], [raspbian_proc] point fb675b81 at e45574a0 
    [   49.549452] [+]kworker/2:4 point 1d830555 at fb675b81
    [   49.549460] [-]kworker/2:4 point e45574a0 at 71182716

    여러 사이트를 참조 했다.

    https://kamang-it.tistory.com/entry/Cclangcontainerof%EC%99%80-offsetof%EB%A1%9C-%EB%A9%A4%EB%B2%84-%EB%B3%80%EC%88%98%EB%A1%9C-%ED%95%B4%EB%8B%B9-%EA%B5%AC%EC%A1%B0%EC%B2%B4-%EB%B0%98%ED%99%98%ED%95%98%EA%B8%B0
    https://digiconfactory.tistory.com/entry/C%EC%96%B8%EC%96%B4-%EC%9D%B4%EC%A4%91-%EC%97%B0%EA%B2%B0-%EB%A6%AC%EC%8A%A4%ED%8A%B8-Doubly-Linked-List-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0
    https://stackoverflow.com/questions/21398105/accessing-structure-elements-via-double-pointers-in-c
    https://doomsodradek.blogspot.com/2017/06/c-struct-warning-assignment-from.html
  • wifi 동글(ew-7811)로 내부 망 연결

    실습 라즈베리 파이를 전원만 붙여 책상에 올렸다. 처음에는 이미지를 잘못 뜨면 부팅되지 않을까 키보드, 마우스, 모니터가 필요하다 생각했다. 그러나 크로스 컴파일 삽질을 몇 번 해보니 부팅 이미지를 쉽게 만들 수 있었다. 공간(공간 = 돈)을 절약하고자 라즈베리 파이에 전원만 넣고 나머지를 싹 치웠다.

    커널 패닉을 몇 번이나 보겠어? 데스크탑에서 ssh로 라즈베리 파이에 접속하여 사용하기로 했다. 유선으로 연결하면 간단한데, 공유기는 거실에 있고, 데스크탑은 다른 방에 있어 지저분하다. 게다가 데스크탑에 랜포트가 하나라 인터넷용으로 할당해야 한다. usb용 와이파이 모듈로 붙이면 간단한데, 지금 사기 아깝다. 포기하려 했으나, 과거 레고 ev3에 연결했던 와이파이 동글을 찾아냈다. 당장 레고에서 적출하여 데스크탑에 꼽았다.

    https://www.edimax.com/edimax/merchandise/merchandise_detail/data/edimax/in/wireless_adapters_n150/ew-7811un/

    동글로 이렇게 연결했다.

    처음 동글을 연결하여, wifi login하면 내부 망으로 잘 연결된다. 문제는 이제부터..

    부팅할 때 network manager가 usb 동글을 연결할 때 까지 기다린다. 매 부팅시 약 30초 동안 지연된다. ssd를 사용하지만 체감은 하드디스크 수준이다. 그냥 쓰려 했으나, 남는게 시간이라 배워도 볼 겸, 고치기로 했다.

    [10:04:57]>dmesg 
    [ 732.893023] rtl_usb: reg 0x82, usbctrl_vendorreq TimeOut! status:0xffffff92 value=0xa200
    [ 743.132917] rtl_usb: reg 0x82, usbctrl_vendorreq TimeOut! status:0xffffff92 value=0xa300
    

    일단 사용하는 드라이버를 찾았다.

    [09:59:09]>lsusb
    ...
    Bus 001 Device 002: ID 7392:7811 Edimax Technology Co., Ltd EW-7811Un 802.11n Wireless Adapter [Realtek RTL8188CUS]

    realtek rtl8188cus 드라이버를 찾아야 한다. 인터넷에서 찾았지만 너무 오래되어 kernel 2.x대로 컴파일 해야한다. 무슨 헤더파일이 커널 업데이트 되면서 사라졌는데, 이 부분을 수정해야 컴파일 할 수 있을 것 같다. 누가??? 포기하고, rtl8188이 rtl8192 드라이버를 사용하는 듯 하여 이 드라이버를 찾아봤다.

    [09:59:10]>lsmod | grep rtl_usb
    rtl_usb                20480  1 rtl8192cu

    드라이버를 찾아보니 kenel 5.4버전에도 잘 들어가 있다. 하드웨어 특성인 듯 하다. 아예 모듈을 부팅할 때 로딩하지 않도록 blacklist로 넣어 주기로 했다.

    1. 의존성 작성.
    2. 블랙리스 작성.
    3. update.
    4. 수동으로 로딩.

    드라이버를 로딩 후 모듈 의존성을 만들었다. 수동으로 해야 하는지 모르겠으나, 아래 명령어로 했다.

    [10:48:28]>sudo depmod

    어느 모듈이 문제인지 몰라 블랙리스트에 모두 추가했다. 이후 이미지를 업데이트 했다. 해도, 안해도 상관없다는데 하는 게 좋단다.

    [10:04:57]>cat /etc/modprobe.d/blacklist-usbwifi.conf 
    #rtl_usb 로딩시 vendor timeout으로 부팅 지연.
    #해당 드라이버를 구할 수 없어 부팅시 언로드를 기본 설정.
    #로딩 후 모듈 추가.
    #
    blacklist rtl8192cu
    blacklist rtl8xxxu
    blacklist rtl8192c_common
    blacklist rtlwifi
    blacklist rtl_usb
    blacklist mac80211
    blacklist cfg80211
    # update-initramfs -u

    부팅은 빨리 된다. 부팅 후 필요할 때 modprobe로 로딩한다. insmod를 하면 순서대로 하지 않아 symbolic error를 낸다.

    [  228.936080] rtl_usb: Unknown symbol rtl_beacon_statistic (err -2)
    [  228.936107] rtl_usb: Unknown symbol ieee80211_free_hw (err -2)
    [  228.936123] rtl_usb: Unknown symbol ieee80211_register_hw (err -2)
    [  228.936141] rtl_usb: Unknown symbol rtl_ops (err -2)
    [  228.936153] rtl_usb: Unknown symbol ieee80211_tx_status_irqsafe (err -2)
    [  228.936175] rtl_usb: Unknown symbol rtl_init_rx_config (err -2)
    [  228.936187] rtl_usb: Unknown symbol rtl_lps_change_work_callback (err -2)
    [  228.936203] rtl_usb: Unknown symbol rtl_action_proc (err -2)
    [  228.936215] rtl_usb: Unknown symbol rtl_init_core (err -2)
    [  228.936231] rtl_usb: Unknown symbol ieee80211_alloc_hw_nm (err -2)
    [  228.936248] rtl_usb: Unknown symbol ieee80211_unregister_hw (err -2)
    [  228.936265] rtl_usb: Unknown symbol rtl_deinit_core (err -2)
    [  228.936277] rtl_usb: Unknown symbol rtl_deinit_deferred_work (err -2)
    [  228.936290] rtl_usb: Unknown symbol ieee80211_rx_napi (err -2)
    [  235.724425] rtl_usb: Unknown symbol rtl_beacon_statistic (err -2)
    [  235.724452] rtl_usb: Unknown symbol ieee80211_free_hw (err -2)
    [  235.724467] rtl_usb: Unknown symbol ieee80211_register_hw (err -2)
    [  235.724484] rtl_usb: Unknown symbol rtl_ops (err -2)
    [  235.724497] rtl_usb: Unknown symbol ieee80211_tx_status_irqsafe (err -2)
    [  235.724519] rtl_usb: Unknown symbol rtl_init_rx_config (err -2)
    [  235.724531] rtl_usb: Unknown symbol rtl_lps_change_work_callback (err -2)
    [  235.724546] rtl_usb: Unknown symbol rtl_action_proc (err -2)
    [  235.724558] rtl_usb: Unknown symbol rtl_init_core (err -2)
    [  235.724574] rtl_usb: Unknown symbol ieee80211_alloc_hw_nm (err -2)
    [  235.724591] rtl_usb: Unknown symbol ieee80211_unregister_hw (err -2)
    [  235.724608] rtl_usb: Unknown symbol rtl_deinit_core (err -2)
    [  235.724620] rtl_usb: Unknown symbol rtl_deinit_deferred_work (err -2)
    [  235.724633] rtl_usb: Unknown symbol ieee80211_rx_napi (err -2)
    
    [10:58:11]>sudo modprobe rtl8192cu
    [  171.425547] rtl8192cu: Chip version 0x10
    [  174.965957] rtl8192cu: Board Type 0
    [  174.974954] rtl_usb: rx_max_size 15360, rx_urb_num 8, in_ep 1
    [  174.974978] rtl8192cu: Loading firmware rtlwifi/rtl8192cufw_TMSC.bin
    [  174.975042] ieee80211 phy0: Selected rate control algorithm 'rtl_rc'
    [  174.975494] usbcore: registered new interface driver rtl8192cu
    [  174.981081] rtl8192cu 1-9:1.0 wlx801f02efe35d: renamed from wlan0
    [  175.036947] rtl8192cu: MAC auto ON okay!
    [  176.627123] rtl8192cu: Tx queue select: 0x05
    [  187.013949] rtl_usb: reg 0x82, usbctrl_vendorreq TimeOut! status:0xffffff92 value=0xa200
    [  197.253732] rtl_usb: reg 0x82, usbctrl_vendorreq TimeOut! status:0xffffff92 value=0xa300
    [  207.493591] rtl_usb: reg 0x82, usbctrl_vendorreq TimeOut! status:0xffffff92 value=0xa400
    [  217.733460] rtl_usb: reg 0x80, usbctrl_vendorreq TimeOut! status:0xffffff92 value=0xa500
    [  230.660865] wlx801f02efe35d: authenticate with 00:07:89:9a:24:d9
    [  231.013147] wlx801f02efe35d: send auth to 00:07:89:9a:24:d9 (try 1/3)
    [  231.020672] wlx801f02efe35d: authenticated
    [  231.021103] wlx801f02efe35d: associate with 00:07:89:9a:24:d9 (try 1/3)
    [  231.041533] wlx801f02efe35d: RX AssocResp from 00:07:89:9a:24:d9 (capab=0x411 status=0 aid=7)
    [  231.041542] wlx801f02efe35d: AP has invalid WMM params (AIFSN=1 for ACI 3), will use 2
    [  231.185105] wlx801f02efe35d: associated
    [  231.210645] IPv6: ADDRCONF(NETDEV_CHANGE): wlx801f02efe35d: link becomes ready

    176초에 로딩 후 230초에 드라이버를 로딩했다. 이 하드웨어 자체가 문제있어 보인다.