Github Page

검색어 xargs에 대한 글을 관련성을 기준으로 정렬하여 표시합니다. 날짜순 정렬 모든 글 표시
검색어 xargs에 대한 글을 관련성을 기준으로 정렬하여 표시합니다. 날짜순 정렬 모든 글 표시

2/10/2015

find 확장 조합 (grep , xarg)

1. Linux 에서 검색방법

개별 find or grep으로 검색으을 하면, 어느정도의 한계를 느낄 것이며, 이를 확장해주는 것이 xargs의 기능이라고 생각한다.
이를 pipe라는 기능을 사용하여, '|'  조합으로 기본 구성을 하여 사용해보고, 단순 검색인
find와 grep을 이용을 해보자.


1.1 find 이용한 기본 검색 

  • find name 검색 

$ find . -name board // kernel 에서 board  filename 검색 
./Documentation/devicetree/bindings/board
./drivers/staging/board

$ find . -name '*.c' // *.c file 파일 검색 
.....

  • find로 변경시간 검색 
-5 or -10 , 즉 5분 전 or 5일 전 것이 가장 유용하게 이용이 될것이며, 파일이 많으면,
head or tail 이용하자

-cmim :  File의 status가 변경된 시간 (기준 n minute)
-ctime :  File의 status가 변경된 시간 (기준 n*24 hours, 1 day)
-mmin:   File의 data가 변경된 시간 (기준 n minute)
-mtime:  File의 data가 변경된 시간 (기준 n*24 hours , 1 day )


$ find . -cmin -5 //  -5 분이하, 즉 5분전  파일 변경된 것 검색 
./.config

$ find . -cmin 5         //  정확히 5 분 전 것만 검색 , 별로 검색에 필요 없음 
$ find . -cmin +5 | head //  +5 분이상, 즉 5분 후  파일 변경된 것 검색 , 파일이 너무 많아 head 사용 
./.tmp_kallsyms2.o
./mm
./mm/.filemap.o.cmd
./mm/.mincore.o.cmd
./mm/mremap.o
./mm/.compaction.o.cmd
./mm/page_isolation.o
./mm/.msync.o.cmd
./mm/modules.builtin
./mm/zsmalloc.c  

$ find . -ctime -5   //  파일 변경된 것 -5 *24 시간 이하     , 즉 5일 이전것 
.
./init
./include/linux
./kernel/sched
./arch/arm/boot/compressed
./arch/arm/kernel
./.config.old

$ find . -ctime 5    //  파일 변경된 것 5*24 hours 시간된 것 ,
$ find . -ctime +5   //  파일 변경된 것 +5 *24 hours 시간이상, 즉 5일 이후것  


atime /amin : 즉 access time 도 존재하지만 , debugging 할 경우에나 필요할 것 같다.

  • find로 size 기준으로 검색 
find로 file size 기준으로 검색

$ find -size -512c  // 512 byte 이하 검색 
$ find -size -4k  // 4k byte 이하 검색 
$ find -size -4M  // 4M byte 이하 검색 
$ find -size -4G  // 4G byte 이하 검색 

  • grep을 이용한 검색 
grep을 이용하며, 검색하면 좋지만, 시간 상당히 걸리뿐만 아니라
가끔 시스템이 죽을 경우도 존재한다.


$ grep -n _board_ ./System.map // System.map 파일 안에서 _board_ 검색하고 line을 출력 
$ grep -n _board_ ./System.map 
678:c001ff70 t omap_mux_dbg_board_open
680:c001ffc0 t omap_mux_dbg_board_show
18680:c043faf0 T spi_register_board_info
28085:c0679ecc r omap_mux_dbg_board_fops
37105:c088aeb8 R __ksymtab___i2c_board_list
37106:c088aec0 R __ksymtab___i2c_board_lock
45157:c08964c8 r __kcrctab___i2c_board_list
45158:c08964cc r __kcrctab___i2c_board_lock

$ grep -r _board_ .              // 현재 directory부터 모든 파일 안의 _board_  검색을 한다 
./System.map:c001ff70 t omap_mux_dbg_board_open
./System.map:c001ffc0 t omap_mux_dbg_board_show
./System.map:c043faf0 T spi_register_board_info
./System.map:c0679ecc r omap_mux_dbg_board_fops
./System.map:c088aeb8 R __ksymtab___i2c_board_list
./System.map:c088aec0 R __ksymtab___i2c_board_lock
./System.map:c08964c8 r __kcrctab___i2c_board_list
./System.map:c08964cc r __kcrctab___i2c_board_lock
./System.map:c08b2e64 r __kstrtab___i2c_board_list
./System.map:c08b2e75 r __kstrtab___i2c_board_lock
./System.map:c08cc7d4 T omap_serial_board_init
./System.map:c08e73c4 T i2c_register_board_info
./System.map:c08fc398 t pmic_i2c_board_info
./System.map:c0911390 d musb_default_board_data
./System.map:c0945560 D __i2c_board_lock
./System.map:c094556c D __i2c_board_list
.....

1.2. 기본조합 (find와 grep)

find만 이용할 경우 file list 만을 검색을 하지만, 여기서 grep을 이용하여 file list를 
find에서 검색한 list 에서만, grep을 이용하여 find의 검색 정보의 정확성을 높힌다.
사실 그리 좋은 조합은 아닌 것 같다.

1. find 로 *.c 파일 file list을 생성
2. *.c file list 입력을 받아 이를 grep 으로 board관련된 내용 file list 줄임


$ find . -name '*.c' | grep board  // find 로 전체 *.c 파일 list 생성
./sound/soc/intel/boards/haswell.c
./sound/soc/intel/boards/skl_rt286.c
./sound/soc/intel/boards/bytcr_rt5640.c
./sound/soc/intel/boards/byt-max98090.c
./sound/soc/intel/boards/broadwell.c
./sound/soc/intel/boards/cht_bsw_rt5645.c
./sound/soc/intel/boards/cht_bsw_max98090_ti.c
./sound/soc/intel/boards/mfld_machine.c
./sound/soc/intel/boards/cht_bsw_rt5672.c
./sound/soc/intel/boards/byt-rt5640.c
./kernel/debug/kdb/kdb_keyboard.c
./arch/arm/mach-tegra/board-paz00.c
./arch/arm/mach-omap2/board-generic.c
./arch/arm/mach-omap2/board-ldp.c
./arch/arm/mach-omap2/board-rx51-peripherals.c
./arch/arm/mach-omap2/common-board-devices.c
./arch/arm/mach-omap2/board-n8x0.c
./arch/arm/mach-omap2/board-rx51.c
./arch/arm/mach-omap2/board-rx51-video.c
./arch/arm/mach-omap2/board-flash.c
./arch/arm/mach-ux500/board-mop500-audio.c
./arch/arm/mach-ux500/board-mop500-regulators.c
./arch/arm/mach-omap1/board-h2-mmc.c
./arch/arm/mach-omap1/board-perseus2.c
./arch/arm/mach-omap1/board-osk.c


1.3 find 와 xargs 와 greps 조합 검색

  • xargs 와 pipe의 조합기능 
 xargs - build and execute command lines from standard input
 xargs는 stdin으로 부터 들어온 command lines을 실행하거나 빌드하는 기능이다.

쉽게 말하면

  1. find  *.c   |  xargs grep xx  // c파일을 찾아 list 만들고 이를 grep에게 argument로 전달 
  2. find  *.h  |  xargs rm    xx  // h파일을 찾아 list 만들고 이를 rm에게  argument로 전달 


xargs를 이용하여, grep으로 검색을 하되 find에서 검색한 내용안 에서만 검색을 한다.
위의 검색과  차이가 있다.


$ find . -name '*.c' | xargs grep dram_init   // *.c 검색해서  grep으로 *.c파일만 dram_init 내용을 검색 


1.4. xargs 확장 사용 

xargs: 파이프 이전의 명령의 결과 값들을 인자로 보내어 주어 실행시킴.
이름도 xargs , 현재 여러 인자를 TEST 못해봄.  주로, 인자 하나만 사용해봄.

$ find . -name '*.o' | xargs  grep 찾고자 하는 file 
$ find . -name '*.mk' -o -name 'Makefile' | xargs grep odroid 
$ find . -name '*.mk' | xargs rm 


Ref.
  http://stackoverflow.com/questions/7339253/find-and-number-of-days-range
  http://qdata.co.kr/bo/bbs/board.php?bo_table=ltip&wr_id=210


2. 소스내 패턴검색 (sed,xarg 응용)

sed를 알고나서, xarg에 적용을 하고 난뒤 아래와 같은 조합으로 만들어봤는데,
소스검색방법으로 정말 최적인것 같다.
SSD가 아닌곳에서도 소스검색용으로는 최적인것 같다.


sed 및 xargs와 grep를 이용하여, 빌드만 된 소스에서 원하는 패턴을 검색

      1. find로  obejct 검색한다.
      2. sed 로 *.o 에서 *.c로 변경한다. (검색결과 파이프로 받는다)
      3. xargs를 이용하여 grep 명령을 실행한다. (-r 재귀명령어, -s  no-messages )


$ find . -name '*.o' | sed -e 's/o$/c/g' | xargs grep -rs 'stmmac'


3. Find 기타사용

  • 소스 파일 추출  (cscope 파일 사용)

Find 사용하여, 소스 File 추출

$ find . \( -name '*.c' -o -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.s' -o -name '*.S' -o -name '*.asm' \) -print > cscope.files 

ex) 특정 파일 추출

    하나 추가할때마다 -o -name 사용

$ find . -name '*.c' -o -name '*.h' 


ls 하여 파일을 다시 grep으로 avc포함된 파일만  ./avc 폴더로 이동

$ ls | grep avc | xargs -i mv {} ./avc  

  https://kldp.org/node/35902

2/12/2015

xargs 기본사용

1. xargs 기본사용

xargs는 기본적으로 단독으로 사용하는 command가 아니며 다른 command과 조합으로 사용한다.

xargs에서 다른 command를 실행하면, 표준입력으로 값으로 들어온 값을 그대로 command로 넘겨준다. 그래서 이름 xargs 인 것 같다.
결론적으로 xargs의 command는 표준입력의 넘어온 list의 제한적인 검색 또는 실행을 한다.

$ find . -name "*.o" | xargs rm -rf  


SYNOPSIS
       xargs  [-0prtx] [-E eof-str] [-e[eof-str]] [--eof[=eof-str]] [--null] [-d delimiter] [--delimiter delimiter] [-I replace-str] [-i[replace-str]] [--replace[=replace-str]] [-l[max-lines]]
       [-L max-lines] [--max-lines[=max-lines]] [-n max-args] [--max-args=max-args] [-s max-chars] [--max-chars=max-chars] [-P max-procs]  [--max-procs=max-procs]  [--interactive]  [--verbose]
       [--exit] [--no-run-if-empty] [--arg-file=file] [--show-limits] [--version] [--help] [command [initial-arguments]]


2. 기본예제


$ find . -name "*.o" | xargs rm -rf
$ ls "*.o" | xargs rm -rf

위 예제가 제대로 동작이 안될 때 아래와 같이 한다.
왜냐하면 find를 검색은 기본적으로 newline을 포함하지만 -print0 은 이를 제거한다.

$ find /tmp -name "*.tmp" -print0 | xargs -0 rm

  • 각 directory의 전체 사이즈를 알고 싶을 경우.

$ ls | xargs du -hs 

http://www.dreamy.pe.kr/zbxe/CodeClip/164220
http://www.thegeekstuff.com/2013/12/xargs-examples/

8/13/2015

Device Tree 기반 소스수정 및 빌드 (U-Boot 와 Kernel)

1. Device Tree의 DTS 기본구조 및 Build 

Device Tree Syntax의 약자이며, Kernel 와  Uboot에 존재하며, 보통 두개의 dts 파일은 동일하다
  1. Kernel PATH:  arch/arm/boot/dts 
  2. Uboot PATH:  arch/arm/dts/

Device Tree Boot 방식
  https://ahyuo79.blogspot.com/2015/08/am437x-kernel-device-tree.html
  https://ahyuo79.blogspot.com/2015/08/device-tree-2-am437xam335x.html

Device Tree Syntax 구성방법
  https://ahyuo79.blogspot.com/2015/08/device-tree.html

지향하는 바는 DTS를 한번 설정하면 손쉽게 Uboot 와 Kernel 의 HW 설정변경 가능하도록하는 것이다.
물론 예외적으로 보면, 각 Image들과 결합을 하게되어 사용을 한다면, 따로 사용도 가능하겠다.

DTSI와 DTS파일이 존재하며, DTSI는 DTS에서 include하는 파일이며, 구조 또한 동일하다.
하지만, dt-bindings도 include를 하지만 header 파일로 사용이 된다.

Build 전에는 DTS와 DTSI만 존재하지만, Build 후에 DTB가 생성이된다.
  1. Main files: ./arch/arm/boot/dts 
  2. Include Files: ./arch/arm/boot/dts/include/dt-bindings
  3. Makefile./arch/arm/boot/dts/Makefile

1.1 AM437x Example
AM437x-GP-EVM 을 사용을 하며 TEST을 하고 있다.

$ ls arch/arm/boot/dts/am4*
am4372.dtsi             am437x-gp-evm.dtb  am437x-sk-evm.dtb  am43x-epos-evm-hdmi.dts  am43x-epos-evm.dts
am437x-gp-evm-hdmi.dts  am437x-gp-evm.dts  am437x-sk-evm.dts  am43x-epos-evm.dtb       am43xx-clocks.dtsi 


1.2 I.MX6 인 Example

I.MX6를 수정을 할때, 참고하던 Device Tree 예제들이며, 현재 Device Tree로 대부분의 CPU들이 지원을 하는 것 같다.
특히 한 것은 pinctl (iomuxc) 하는 방식이 TI와 다르게 사용되며, 관련부분은 별도로 봐야한다.

$ cat arch/arm/boot/dts/imx6ull-pinfunc.h  // 핀확인 IOMUXC Register 확인 (Kernel 소스)
$ vi arch/arm/boot/dts/imx6ul*   //

&iomuxc {
...
    pinctrl_can_int: canintgrp {
        fsl,pins = < 
            /*
               IOMUXC_SW_MUX_CTL_PAD : MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04
               IOMUXC_SW_PAD_CTL_PAD : 0x13010   (세부설정가능 Open Drain / Pull / Hysteresis Enable)
                                     : 0x80000000  상위 설정과 다르게 PAD Register를 변경을 막는다고 하는데, bit31/30은 자세한내용은 커널문서 
             */
            MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04    0x13010      /* SODIMM 73 */ 
        >;
    };
...
};

/sys/kernel/debug 가 되는 경우 아래와 같이 Pin 설정확인

$ ls /sys/kernel/debug/pinctrl/  // Target Device에서 debug 모드로 연결하여 확인 

$ cat /sys/kernel/debug/pinctrl/pinctrl-handles  // Target Device에서 설정확인 
Requested pin control handlers their pinmux maps:
device: 20e0000.iomuxc current state: default
........

$ cat /sys/kernel/debug/pinctrl/pinctrl-maps     // 관련정보 
$ cat /sys/kernel/debug/pinctrl/20e0000.iomuxc/pingroups


// GPIO 의 경우 sysfs에서 도 사용가능하지만, 직접 device tree의 모듈에 연결이 되어 사용가능하므로 주의
// 이때 아래와 같이 확인한 후 device tree에서 연결된 모듈의 gpio부분을 제거한 후 사용 

$ cat /sys/kernel/debug/gpio  // GPIO 정보 Debug 
..........
 gpio-112 (                    |peri_3v3            ) out hi
 gpio-114 (                    |sysfs               ) out lo
 gpio-116 (                    |sysfs               ) out lo
 gpio-117 (                    |sysfs               ) out lo
 gpio-118 (                    |sysfs               ) out lo
 gpio-119 (                    |sysfs               ) out lo
 gpio-122 (                    |sysfs               ) out lo
 gpio-123 (                    |can-stby            ) out hi
 gpio-127 (                    |sysfs               ) out lo

최근에 찾은 자료이며, i.MX6의 Device Tree 구조를 아래 사이트에서 쉽게 볼수 있어 업데이트한다.

  • i.MX의 Device Tree

i.MX6 관련내용 
  http://developer.toradex.com/device-tree-customization
  https://developer.toradex.com/device-tree-customization#2-imx-6ull-based-modules

/sys/kernel/debug 관련내용
  https://www.linuxtopia.org/online_books/linux_kernel/kernel_configuration/ch09s07.html

2. Device Tree 의 수정 및 사용법

Device Tree를 이해한다고, ARM BOOT를 다시 전체 분석을 할 필요는 없다.
지금 현재 제대로 동작을 하고 있으며, 필요한 모듈과 그기능을 찾아 그 부분만 수정을 하면 되기에 dts 파일과 dtsi파일을 이해하고 수정을 하면 되겠다.

2.1  DTS와 각 Driver의 구조 (AM437x 인 경우)

DTS파일과 각 Driver의 기본구조는 다음과 같다.
device tree의 기본동작 방식은 dts파일 안의 compatible의 이름과 driver의 맞을 경우 그 해당하는 driver에게 맞게 동작하게 되어있다.


그러므로, Kernel을 빌드후 다음과 같이 dts의 compatible의 이름을 검색하여 찾아 수정을하면 된다.



Device Tree의 위치는 위에서 설명했듯이 arch/arm/boot/dts/ 보면될 것이지만,관련된 부분을 전부 검색을 해보자.

  • Device Tree Source 관련소스 (driver) 검색  
  1. Kernel을 빌드 후, find들 이용하여 *.o file list 생성된다. 
  2. 이 file list들을 *.o에서 *.c 변경한다.
  3. 빌드된 file list의 *.c  중심으로 dts파일의 'compatible'로 검색진행 

$ cd kernel source 
$ find . -name '*.o' | sed -e 's/o$/c/g' | xargs grep -rs 'ti,am4372'
$ find . -name '*.o' | sed -e 's/o$/c/g' | xargs grep -rs 'arm,coretex-a9-gic'
$ find . -name '*.o' | sed -e 's/o$/c/g' | xargs grep -rs 'syscon'

or 

$ MY_KERENL=./kernel_source 
$ find $MY_KERENL -name '*.o' | sed -e 's/o$/c/g' | xargs grep -rs 'syscon' $MY_KERENL



2.2 DTS파일 수정 및 추가방법 (AM437x 경우)  

상위에서 DTS파일을 수정하고, 추가한다면, Kernel 내부의 Makefile 수정하면된다.
DTS파일을 빌드를 원한다면, Kernel로 이동 후에 빌드를 하자.

  • AM437x는 기본 Makefile 구성 (DTS관련부분만)
  1. Main Makefile ( U-BOOT , Kernel, Filesystem 모두 관리)
  2. Rule.make     ( 관련 설정)
  3. Kernel Source 내부 Makefile 

  • Main Makefile (DTB File Build 수정) 
현재 dtb 파일은 3개만 빌드를하게 만들었으며, 본인이 추가한다면 이곳에서 수정하자

$ vi Makefile
linux: linux-dtbs        ### linux kernel 부분 build 
        @echo =================================
        @echo     Building the Linux Kernel
        @echo =================================
        $(MAKE) -C $(LINUXKERNEL_INSTALL_DIR) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) $(DEFCONFIG)
        $(MAKE) -j $(MAKE_JOBS) -C $(LINUXKERNEL_INSTALL_DIR) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) zImage
        $(MAKE) -j $(MAKE_JOBS) -C $(LINUXKERNEL_INSTALL_DIR) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) modules
.....
# Kernel DTB build targets
linux-dtbs:
        @echo =====================================
        @echo     Building the Linux Kernel DTBs
        @echo =====================================
        $(MAKE) -C $(LINUXKERNEL_INSTALL_DIR) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) $(DEFCONFIG)
        $(MAKE) -j $(MAKE_JOBS) -C $(LINUXKERNEL_INSTALL_DIR) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) am43x-epos-evm.dtb am437x-gp-evm.dtb am437x-sk-evm.dtb


  • Linux Kernel/Uboot 에서 상위 dtb 생성확인 (check DTB files)

$ cd board-support/linux*  // Linux Kernel Source 이동 

$ find . -name *dtb    // 상위 Makefile로 인하여 dtb 파일은 이미 3개 생성됨 확인  
./arch/arm/boot/dts/am437x-sk-evm.dtb
./arch/arm/boot/dts/am43x-epos-evm.dtb
./arch/arm/boot/dts/am437x-gp-evm.dtb
./include/config/arm/atag/dtb

  • Linux Kernel/Uboot 에서 내부 Makefile 수정 (for new DTS File)
상위 Makefile에서 3개만 빌드했기 때문에, 3개이며, 추가를 원한다면 상위 Makefile 수정하자.
새로운 dtb/dts을 추가한다고 하면 Kernel 내부의 dts 관련 Makefile 파일을 수정하자.

$ cd board-support/linux*  // Linux Kernel Source 이동 

$ vi .config  // Kernel Config 확인 
...
CONFIG_SOC_AM43XX=y
# CONFIG_SOC_DRA7XX is not set
CONFIG_ARCH_OMAP2PLUS=y
....

$ vi arch/arm/boot/dts/Makefile   // new dts file 추가 , 본인의 dts 설정파일 만들어 추가하자

dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
        omap2430-sdp.dtb \
        omap2420-n800.dtb \
        omap2420-n810.dtb \
        omap2420-n810-wimax.dtb \
        omap3430-sdp.dtb \
        omap3-beagle.dtb \
        omap3-cm-t3730.dtb \
        omap3-sbc-t3730.dtb \
        omap3-devkit8000.dtb \
        omap3-beagle-xm.dtb \
        omap3-evm.dtb \
        omap3-evm-37xx.dtb \
        omap3-ldp.dtb \
        omap3-n900.dtb \
        omap3-n9.dtb \
        omap3-n950.dtb \
        omap3-overo-tobi.dtb \
        omap3-overo-storm-tobi.dtb \
        omap3-gta04.dtb \
        omap3-igep0020.dtb \
        omap3-igep0030.dtb \
        omap3-zoom3.dtb \
        omap4-panda.dtb \
        omap4-panda-a4.dtb \
        omap4-panda-es.dtb \
        omap4-var-som.dtb \
        omap4-sdp.dtb \
        omap4-sdp-es23plus.dtb \
        omap5-uevm.dtb \
        am335x-evm.dtb \
        am335x-evmsk.dtb \
        am335x-bone.dtb \
        am335x-boneblack.dtb \
        am335x-nano.dtb \
        am335x-base0033.dtb \
        am3517-craneboard.dtb \
        am3517-evm.dtb \
        am3517_mt_ventoux.dtb \
        am43x-epos-evm.dtb \
        am43x-epos-evm-hdmi.dtb \
        am437x-gp-evm.dtb \
        am437x-gp-evm-hdmi.dtb \
        am437x-sk-evm.dtb \
        dra7-evm.dtb \
        dra7-evm-lcd10.dtb \
        dra72-evm.dtb \
        dra72-evm-lcd10.dtb \
        am57xx-beagle-x15.dtb \
        am57xx-evm.dtb


  • Linux Kernel 내부 Makefile 에서 zImage 확인 
 zImage 빌드 할 경우 정확한 설정 확인하고, dtb와 연관성을 확인하자.
 아래의 *.cmd는 실행한 결과들이며, 이것을 확인을 하면, 어떻게 생성이 되었는지 쉽게  이해를 할수 있다.

$ cd board-support/linux*  // Linux Kernel Source 이동 

$ find . -name zImage   //zImage 와 Image 위치파악  
./arch/arm/boot/zImage

$ ls -a arch/arm/boot/    // zImage와 Image 생성 부분 분석 ( Makefile , *.cmd) 
.  ..  .Image.cmd  .gitignore  .zImage.cmd  Image  Makefile  bootp  compressed  dts  install.sh  zImage

$ cat ./arch/arm/boot/.zImage.cmd   //제대로 빌드되었다면 아래와 같이 확인가능 
cmd_arch/arm/boot/zImage := /home/jhlee/am437x/works/linux-devkit/sysroots/i686-arago-linux/usr/bin/arm-linux-gnueabihf-objcopy -O binary -R .comment -S  arch/arm/boot/compressed/vmlinux arch/arm/boot/zImage

$ vi arch/arm/boot/Makefile  // zImage 확인 
....
targets := Image zImage xipImage bootpImage uImage

ifeq ($(CONFIG_XIP_KERNEL),y)        // 현재 XIP 모드가 아님 ( NOR NAMD 이면, 가능하겠지만?)

$(obj)/xipImage: vmlinux FORCE
        $(call if_changed,objcopy)
        @$(kecho) '  Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))'

$(obj)/Image $(obj)/zImage: FORCE
        @echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)'
        @echo 'Only the xipImage target is available in this case'
        @false

else

$(obj)/xipImage: FORCE
        @echo 'Kernel not configured for XIP (CONFIG_XIP_KERNEL!=y)'
        @false

$(obj)/Image: vmlinux FORCE
        $(call if_changed,objcopy)
        @$(kecho) '  Kernel: $@ is ready'

$(obj)/compressed/vmlinux: $(obj)/Image FORCE
        $(Q)$(MAKE) $(build)=$(obj)/compressed $@

$(obj)/zImage:  $(obj)/compressed/vmlinux FORCE
        $(call if_changed,objcopy)                 ## OBJCOPYFLAGS 사용하며, objcopy를 이용하여 object를 binary를 만들때 사용한다  
        @$(kecho) '  Kernel: $@ is ready'          ## 자세한 내용은 Kernel 문서와 GCC 참조 

endif


  • Filesytem 에서 DTB와 Kernel zImage 확인 
Partition 과 Booting 부분에 있어, Partition은 2개이며, (fat32 와 filesystem 으로 존재) uboot는 fat32에 존재하며, 설정값도 그곳에 존재한다.
그리고 Filesystem 안의 boot에는  dtb 파일과 zImage는 File 형태로 존재하며 아래의 NFS File system에서도 동일하다.

$ cd board-support/linux*  // Linux Kernel Source 이동 
$ sudo cp arch/arm/boot/zImage /boot   // File System의 Boot에 저장 
$ sudo cp arch/arm/boot/dts/
.dtb /boot // File System의 Boot에 저장 $ targetNFS/boot //Kernel Image 와 *.dtb File 확인 (File system 안에 존재) $ ll drwxr-xr-x 2 jhlee jhlee 4096 7월 7 2015 ./ drwxr-xr-x 21 jhlee jhlee 4096 7월 7 2015 ../ lrwxrwxrwx 1 jhlee jhlee 40 7월 7 2015 am437x-gp-evm-hdmi.dtb -> devicetree-zImage-am437x-gp-evm-hdmi.dtb lrwxrwxrwx 1 jhlee jhlee 35 7월 7 2015 am437x-gp-evm.dtb -> devicetree-zImage-am437x-gp-evm.dtb lrwxrwxrwx 1 jhlee jhlee 35 7월 7 2015 am437x-sk-evm.dtb -> devicetree-zImage-am437x-sk-evm.dtb lrwxrwxrwx 1 jhlee jhlee 41 7월 7 2015 am43x-epos-evm-hdmi.dtb -> devicetree-zImage-am43x-epos-evm-hdmi.dtb lrwxrwxrwx 1 jhlee jhlee 36 7월 7 2015 am43x-epos-evm.dtb -> devicetree-zImage-am43x-epos-evm.dtb -rw-r--r-- 1 jhlee jhlee 49048 7월 7 2015 devicetree-zImage-am437x-gp-evm-hdmi.dtb -rw-r--r-- 1 jhlee jhlee 48112 7월 7 2015 devicetree-zImage-am437x-gp-evm.dtb -rw-r--r-- 1 jhlee jhlee 42675 7월 7 2015 devicetree-zImage-am437x-sk-evm.dtb -rw-r--r-- 1 jhlee jhlee 48544 7월 7 2015 devicetree-zImage-am43x-epos-evm-hdmi.dtb -rw-r--r-- 1 jhlee jhlee 47461 7월 7 2015 devicetree-zImage-am43x-epos-evm.dtb -rw-r--r-- 1 jhlee jhlee 105402448 7월 7 2015 vmlinux-3.14.43-g875c69b lrwxrwxrwx 1 jhlee jhlee 23 7월 7 2015 zImage -> zImage-3.14.43-g875c69b -rw-r--r-- 1 jhlee jhlee 4355472 7월 7 2015 zImage-3.14.43-g875c69b


  • TI-Kernel User Guide
  많은 부분이 아래에 내용에 나오며 아래부분을 참고하자.
  http://processors.wiki.ti.com/index.php/Linux_Kernel_Users_Guide


3. How To compile DTS Files
    위에서 언급했듯이 Kernel에서 직접 DTS를 빌드하고자 한다면, 아래와 같이 빌드하자.
    다만 새로 추가했다면, Kernel 내부 Makefile을 수정해야하며, DTS에 맞는 Kernel Config를 확인하자.

    $ cd board-support/linux*  // linux kernel 이동  
    $ ls .config // DTS에 맞는 config 설정이 되어있어야 함.
    $ make ARCH=arm CROSS_COMPILE=arm-xxxxx            
    $ make ARCH=arm CROSS_COMPILE=arm-xxxxx am43x-epos-evm.dtb
    

    만약, 위의 Makefile 파일에 추가 및 Makefile Config가 추가 되지 않았다면, target이 추가되지 않아 dtb를 compile를 할수가 없다.


    3.1 How To use DTC(Device Tree Compiler)

    위와 같이 Kernel Makefile를 이용하여 빌드하는 방법도 있지만,
    직접 dtc를 사용하여 compile 하는 방법도 가능하다

    *참고사항:  처음 Kernel source를 받으면, dtc file은 존재하지 않는다. build 도중 생김
    • DTC (Device Tree Compiler)
    $ cd board-support/linux*  // linux kernel 이동  
    $ ./scripts/dtc/dtc -I dtb -O dts -o (devicetree name).dts (devicetree name).dtb  // 직접 build 
    

      http://www.wiki.xilinx.com/Build+Device+Tree+Blob


    4. Device Tree Guide


    • Device Tree Syntax Spec (중요)  
    ** Device Tree의 Spec이 별도 존재하며 지속적으로 Update되고 있으므로, 각 Spec을 반드시 읽고 확인
      https://www.devicetree.org/specifications/ (문법)
      http://devicetree.org/Device_Tree_Usage  (수정방법)

    • TI Device Tree 사용법  
      http://omappedia.org/wiki/Device_Tree

    • Kernel/Uboot 내부 문서  
    ** Device Tree 사용 및 방법이 Chip Vendor마다 조금씩 다르므로 반드시 Kernel 문서를 확인해야함
      https://www.kernel.org/doc/Documentation/arm/Booting


    • 쉽게 Device Tree를 설명해주는 사이트  
    Device Tree를 쉽게 설명해주는 Guide이고, 아래의 문서에서 위의 그림을 복사하여 넣었다.

      http://www.elinux.org/images/a/ad/Arm-soc-checklist.pdf
      http://events.linuxfoundation.org/sites/events/files/slides/petazzoni-device-tree-dummies.pdf
      http://schedule2012.rmll.info/IMG/pdf/LSM2012_ArmKernelConsolidation_Petazzoni.pdf
      http://events.linuxfoundation.org/sites/events/files/slides/presentation_3.pdf
      http://lxr.free-electrons.com/source/Documentation/devicetree/booting-without-of.txt

    1/07/2015

    find 검색

    1. Find 기본사용법

    find는 원하는 file을 찾을 경우 사용하며, file정보를이용하여 검색하기 때문에 grep보다 빠른 검색가능하다.


    SYNOPSIS
           find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]
    


    1.1.  Find 의 옵션  

    Find는 FILE의 정보기준으로 검색을 하며, 다양한 옵션들을 제공하여 빨리 원하는 FILE들을 찾아준다.

    • Find 기본연산옵션
    1. FILE의 이름관련 연산
    2. FILE의 시간관련 연산 
    3. FILE의 사이즈관련 연산
    4. AND/OR/NOT 연산제공 :  상위 1/2/3번의 조합이 가능 

    **SIZE 관련 연산
    
           -size n[cwbkMG]
                  File uses n units of space.
    
                  `b'    for 512-byte blocks (this is the default if no suffix is used)
                  `c'    for bytes
                  `w'    for two-byte words
                  `k'    for Kilobytes (units of 1024 bytes)
                  `M'    for Megabytes (units of 1048576 bytes)
                  `G'    for Gigabytes (units of 1073741824 bytes)
    
    **TIME 관련 연산  (time: 기본단위는 24*hours , min:  minutes)
    
            -mtime  n : modified n days ago         (파일의 내용을 변경시 )
            -mmin   n : modified minutes ago
            -atime  n : access   n days ago         (파일을 오픈했을 경우, cat, vi, grep, head )
            -amin   n : access   minutes ago  
            -ctime  n : changed  n days ago          (파일의  속성이 변경시)
            -cmin   n : changed  minutes ago
    
    **SIZE/TIME의 숫자개념 
    
             -n  :  for less  than  ( < n )
             +n  :  for great than  ( > n )
              n  :  for exactly n   (  n )

    상위 FILE의 SIZE 및 TIME 연산의 AND/OR/NOT 연산가능

    **AND OR 연산 및 NOT 연산 
    
           -not expr
                  Same as ! expr, but not POSIX compliant.
    
           expr1 expr2
                  Two expressions in a row are taken to be joined with an implied "and"; expr2 is not evaluated if expr1 is false.
    
           expr1 -a expr2
                  Same as expr1 expr2.
    
           expr1 -and expr2
                  Same as expr1 expr2, but not POSIX compliant.
    
           expr1 -o expr2
                  Or; expr2 is not evaluated if expr1 is true.
    
           expr1 -or expr2
                  Same as expr1 -o expr2, but not POSIX compliant.
    
           expr1 , expr2
                  List;
    

    • Find의 기타옵션 
    1. 다른 command 실행연산
    2. FILE 검색결과의 출력방법


    **실행연산
    
           -exec command ;
    
    **output 종류 
    
    newline을 사용여부 및 프로그래밍으로 output을 만들수 있다 이 부분 man을 참고
    
           -print0
                  True; print the full file name on the standard output, followed by a null character
    
           -print True; print the full file name on the standard output, followed by a newline.
    
           -printf format
                  True;  print  format  on  the standard output,
    
                  %p     File's name.
    
                  %P     File's name with the name of the command line argument under which it was found removed.
    
                  %s     File's size in bytes.
    
                  %b     The amount of disk space used for this file in 512-byte blocks.
    
                  %k     The amount of disk space used for this file in 1K blocks.
    


    2. Find 예제 


    2.1 FILE의 이름기준 검색 


    * : 여러글자 대체
    ? : 한글자만 대체
    [1-8] : 한글자만 정의 (1~8)
    [a-c] : 한글자만 정의 (a~c)

    $ find . -name  expr// 원하는 검색어 
    $ find . -name '*.o'   // *.o 파일 검색  (가능하면 '' or ""사용) 
    $ find . -name *.h    // *.h  파일 검색
    $ find . -name *droid-[2-5]*  // android-2/4/5 검색
    $ find . -name *droid-[2-5].[0-1]*  //e.g android-2.0 검색
    $ find ./ -name '*aic*.o' // 중간에 aic 파일 검색
    


    2.2 FILE의 시간기준 검색 

    시간은 모두 과거의 기준으로 검색을 하기에 +- 모두 과거시간들과 검색한다.
    다만 차이가 있다면 아래와 같이 n 에따라 -:less than or +:great than or 일치 있을 뿐이다.

    $ find . -mtime -7             // 수정날짜 (n < 7   ) 현재 FILE(0) ~ 7일전 FILE 검색  
    $ find . -mmin  30             // 수정시간 ( n         ) 오직 30분전 변경된 FILE 만 검색 
    $ find . -mmin  -30            // 수정시간 ( n < 30 ) 현재 FILE(0) ~ 30분전 FILE 검색  
    $ find . -mmin  +30            // 수정시간 ( n > 30 ) 30분전 FILE  ~ 이전전부 FILE 검색       
    $ find . -mmin +30 -mmin -60   // 수정시간 (30 >n , n < 60) 30분전 ~ 60분전 사이만 검색 (AND연산) 
    
    $ find . -atime n/-n/+n        // 액세스 날짜 (파일오픈) 
    $ find . -amin n/-n/+n         // 액세스 시간 
    
    $ find . -ctime n/-n/+n        // 파일속성변경 날짜 (파일오픈 및 사용) 
    $ find . -cmin n/-n/+n         // 파일속성변경 시간 
    
    

    2.3 FILE의 크기기준검색
      FILE의 시간과 동일하게 적용하면됨

      $ find ./ -size  +50k
      $ find ./ -size  +50k -printf "%p            %s\n"    // printf format을 만들어 사용 자세한 내용은 man참고 
      $ find ./ -size  +50k | xargs du -hs
      $ find ./ -size  +50k | xargs du -h
      


      2.4 연산의 AND/OR/NOT 검색

      $ find ./ -name 'snd-*.o' -o -name 'snd*.h'   // NAME 연산 NAME 연산  OR연산 적용 
      $ find ./ -name 'snd-soc*.o' -a -name 'snd*.o'   // NAME 연산 NAME 연산 AND 연산적용  
      $ find ./sound/  -name '*.o' -not -name 'built-in.o' //NAME 연산 NAME 연산 NOT 연산적용  ( *.o 검색 하고, -not으로 제외) 
      $ find . -mtime -7  -name '*.c' -o -name '*.h'   // 7일전- 현재    수정한 파일 중 *.c or *.h 검색 
      $ find . -mmin -60 -name '*.c' -o -name '*.h'   // 60분전 - 현재   수정한 파일 중 *.c or *.h 검색
      

      • 수정시간 과 파일이름 검색이용 예제

      $ find . -mtime -7  -name '*.c' -o -name '*.h'   // 7일전- 현재    수정한 파일 중 *.c or *.h 검색 
      $ find . -mmin -60 -name '*.c' -o -name '*.h'   // 60분전 - 현재   수정한 파일 중 *.c or *.h 검색 

      • 수정시간 현재부터 30일 이전까지 관련 내용 검색  ( 30 < n )

      $ find . -mtime -30 -name '*.c' -o -name '*.h' // 검색내용 중  *.c 혹은 *.h 검색 
      $ find . -mtime -30 -name '*.h'                // 검색내용 중  *.h 만 재검색

      • 30이전 부터 60이전까지 관련내용 검색 (  30 > n  &&  60  < n )

      $ find . -mtime +30 -mtime -60  -name '*.c' -o -name '*.h'
      $ find . -mtime +30 -mtime -60  -name '*.h' 


      • find를 이용한 내부 command 이용 

       아래 내용은 날짜별로 관련내용을 분류할때 사용. (mv를 실행)
             - '{}' ';'     find 내부 command

      $ find . -name "*.VER" -mtime -31 -exec mv '{}' /opt/html/31';' -print
      $ find . -name "*.VER" -mtime +31 -mtime -62 -exec mv '{}' /opt/html/62 ';' -print


        http://www.linux-faqs.info/general/difference-between-mtime-ctime-and-atime

      2/13/2020

      SD/MMC 와 udev 재분석 과 Rule 생성

      1.  SD/MMC Spec 및 기본확인법 

      MMC 혹은 SDCard 관련 Spec을 다시 확인하고자 한다면 아래의 사이트에서 확인




      • MMC(SDCARD) 관련 Spec
      1. Part 1. Physical Layer Simplified Specification 
      2. Part A2. SD Host Controller Simplified Specification
      3. Part E1. SDIO Simplified Specification 
      4. Part E7. Wireless LAN Simplified Addendum
      5. 이외 
      대부분의 기본적인 내용은 Part1. Physical Layer Simplified Specification 을 보면 구조 및 기본동작이 이해가가능하며,
      UHS-II 관련부분이나 다른 SD 확장 API를 본다면 해당 문서를 참조

      SD/MMC 관련 Spec Download
        https://www.sdcard.org/downloads/pls/

      1.1 SD/MMC 정보확인 

      SD/MMC 기본 Register


      • SD/MMC Register 확인 
      $ find /sys -name cid  // CID Register 제조사 및 제품정보 파악가능 (Spec참조)
      /sys/devices/soc0/soc/2100000.aips-bus/219c000.usdhc/mmc_host/mmc3/mmc3:0001/cid     //eMMC
      /sys/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/cid     //SDCard 
      
      $ find /sys -name csd //CSD를 통해 MMC의 Spec 및 성능파악 (Spec참조)
      /sys/devices/soc0/soc/2100000.aips-bus/219c000.usdhc/mmc_host/mmc3/mmc3:0001/csd //eMMC
      /sys/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/csd //SDCard 
      
      $ find /sys -name scr // SDCard에 설정된 기본정보 (Databit,SDCard 종류) 확인가능 (Spec)
      /sys/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/scr  //SDCard 
      
      $ find /sys -name dsr or rca or ocr //기타정보들 
      
      • SD/MMC 기본정보파악 
      $ find /sys -name ios // 쉽게 MMC의 정보파악 
      /sys/kernel/debug/mmc3/ios  //eMMC
      /sys/kernel/debug/mmc2/ios  //SDCard
      
      $ cat /sys/kernel/debug/mmc3/ios  //eMMC 8bit
      clock:          198000000 Hz
      actual clock:   198000000 Hz
      vdd:            21 (3.3 ~ 3.4 V)
      bus mode:       2 (push-pull)
      chip select:    0 (don't care)
      power mode:     2 (on)
      bus width:      3 (8 bits)
      timing spec:    9 (mmc HS200)
      signal voltage: 1 (1.80 V)
      driver type:    0 (driver type B)
      
      $ cat /sys/kernel/debug/mmc2/ios  //SD Card 4bit
      clock:          50000000 Hz
      actual clock:   49500000 Hz
      vdd:            18 (3.0 ~ 3.1 V)
      bus mode:       2 (push-pull)
      chip select:    0 (don't care)
      power mode:     2 (on)
      bus width:      2 (4 bits)
      timing spec:    2 (sd high-speed)
      signal voltage: 0 (3.30 V)
      driver type:    0 (driver type B) 
      
      • SD Card의 경우 CD(Card Detection)/WP(Write Protection) 
      $ cat /proc/interrupts | egrep "(mmc|cd)" // SDCard는 Hotplug를 위해 CD필요 
       63:        676       GPC  24 Level     mmc2  //SDCard
       64:       9336       GPC  25 Level     mmc3  //eMMC 
       78:          0       GPC   6 Edge      2224000.lcdif
      126:          3  gpio-mxc  10 Edge      2198000.usdhc cd  //SDCard Card Detection (Hotplug)
      
      // SD Card Detection의 GPIO 및 Trigger 및 IRQ 확인 
      $ cat /sys/kernel/debug/gpio | grep cd  
       gpio-42  (                    |cd                  ) in  hi IRQ 
      
      SD Card의 경우 CD 와 WP Pin을 GPIO로 연결하여 사용가능하며, 주로 CD 사용할 경우 Hotplug가능. WP 미사용

      eMMC/SD Card 관련참고사항
        https://developer.toradex.com/knowledge-base/sd-mmc-card-(linux)

      1.2 SD/MMC의 Kernel 관련정보 

      • i.MX Kernel Config
      1. MMC/SD/SDIO (CONFIG_MMC)
      2. MMC block (CONFIG_MMC_BLOCK)
      3. Secure Digital Host Controller Interface support (CONFIG_MMC_SDHCI)
      4. SDHCI support on the platform-specific bus (CONFIG_MMC_SDHCI_PLTFM)
      5. SDHCI platform support for the NXP eSDHC i.MX controller (CONFIG_MMC_SDHCI_ESDHC_IMX)

      • Kernel source의 drivers/mmc/host/  
      1. sdhci.c standard stack code
      2. sdhci-pltfm.c sdhci platform layer
      3. sdhci-esdhc.c uSDHC driver
      4. sdhci-esdhc-imx.c uSDHC driver header file

      세부사항은 아래사이트 참고

      • i.MX 관련설정 (출처) 
      MMC/SDCard/SDIO Kernel 설정을 비롯하여Device Tree 설정정보를제공
        https://www.digi.com/resources/documentation/digidocs/90001546/reference/bsp/cc6/r_mmc-sd-sdio.htm


      • MMC/SD Device Driver 세부분석 
      새로 SD/MMC를 분석할 필요는 없는 것 같아 아래사이트를 참조하여 이해만하고 넘어감
        http://egloos.zum.com/furmuwon/v/11167927

      • SDCard 관련부분 Uboot 및 Kernel 설정 (Sitara/i.MX)
      아래사이트에서 쉽게 설정이 가능하도록 제공
        https://www.digikey.com/eewiki/pages/viewpage.action?pageId=35193201#BeagleBoneBlack-uEnv.txtbasedbootscript
        https://www.digikey.com/eewiki/display/linuxonarm/i.MX6+SABRE+Lite
        https://developer.toradex.com/knowledge-base/sd-mmc-card-(linux)


      1.3  Kernel의 Netlink uevent 와 udev 통신 

      Kernel은 udevNETLINK_KOBJECT_UEVENT로 통신을 하고 있으며, 이곳에 add_uevent_var의 환경설정값을 추가하여 통신을 진행한다.
      Kernel은 이외에도 다른 NETLINK도 사용하니 이것만 사용한다고 착각하지말자.

      • udev의 NETLINK_KOBJECT_UEVENT
      ue_sk->sk = netlink_kernel_create(net, NETLINK_KOBJECT_UEVENT, &cfg);
      user에서 socket으로 protocol을 NETLINK_KOBJECT_UEVENT로 설정 
        https://elixir.bootlin.com/linux/v4.20.4/source/lib/kobject_uevent.c#L751

      • SD/MMC 관련소스
      아래부분은 SD/MMC에서 공통으로사용되는 부분으로 필요할때만 보고, Chip Vendor관련부분은 상위에서 처럼 관련부분은 별도로 보자.
        https://elixir.bootlin.com/linux/v4.17.19/source/drivers/mmc/core
        https://elixir.bootlin.com/linux/v4.17.19/source/drivers/mmc/core/mmc.c

      • kobject_uevent->kobject_uevent_env
      보통 uevent는 아래와 같이 동작을 하며, 아래와 같이 각각의 환경변수값을 uevent와 함께보내면, udevd은 이를 받아 database로 기록하여 사용한다고한다.
      1. retval = add_uevent_var(env, "ACTION=%s", action_string);
      2. retval = add_uevent_var(env, "DEVPATH=%s", devpath);
      3. retval = add_uevent_var(env, "SUBSYSTEM=%s", subsystem);
      4. retval = add_uevent_var(env, "%s", envp_ext[i]);  // 상위 NULL 이지만 sys에서 설정가능
      5. retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)++uevent_seqnum);
      6. 기타 값 
        https://elixir.bootlin.com/linux/v4.20.4/source/lib/kobject_uevent.c#L454


      • kobject_synth_uevent 관련함수
        https://elixir.bootlin.com/linux/v4.20.4/source/lib/kobject_uevent.c#L192


      • kobject_uevent_env 의 확장값을 넣어 전송
      1. LEASE=1    :  상위 3번의 envp_ext[i] 값 설정 
      2. HOTPLUG=1 : 상위 3번의 envp_ext[i] 값 설정 
        https://elixir.bootlin.com/linux/v4.20.4/source/drivers/gpu/drm/drm_sysfs.c#L322
        https://elixir.bootlin.com/linux/v4.20.4/source/drivers/gpu/drm/drm_sysfs.c#L304


      • kobject 와 sysfiletem을 세부적으로 분석 (반드시 참고)
      *** 관련내용을 찾다가 아래사이트에서 자세히 분석해줘서 이해하기가 더 쉬움 (감사할 따름)
        http://jake.dothome.co.kr/kobject/


      • device driver의 attribute의 구성을 쉽게 이해가능 (sys file system 구성)
      attribute는 sys filesystem의 구성이기때문에 반드시 사용법 숙지하며, 이외에도 가끔 소스를 보면 다른 것도 존재하는 것 같은데, 그 부분은 추후 추가
      1. device_attribute
      2. bus_attribute
      3. class_attribute
      4. driver_attribute

      오래전의 linux kernel과 attribute설정방법은 조금 다르지만 거의 비슷함
        http://jake.dothome.co.kr/device-driver-1/

      2. udev 분석 및 테스트진행 

      현재 udevadm command로 통합이되어 관련명령어를 모두 사용이 가능하며, 이를 이용하여 udev의 정보 및 테스트도 진행이 가능하다.

      $ udevadm -h
      udevadm [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]
      
      Send control commands or test the device manager.
      
      Commands:
        info          Query sysfs or the udev database  //
        trigger       Request events from the kernel
        settle        Wait for pending udev events
        control       Control the udev daemon
        monitor       Listen to kernel and udev events
        test          Test an event run
        test-builtin  Test a built-in command
      


        http://fibrevillage.com/sysadmin/93-udevadm-command-examples

      2.1 udevadm info 기본분석방법 

      udevadm info를 이용하여 udev의 database 정보와 sysfs 정보를 확인가능하므로, 이를 이용하여 udev 분석이 쉬어진다.

      $ udevadm info  -h
      udevadm info [OPTIONS] [DEVPATH|FILE]
      
      Query sysfs or the udev database.
      
        -h --help                   Print this message
        -V --version                Print version of the program
        -q --query=TYPE             Query device information:
             name                     Name of device node
             symlink                 Pointing to node
             path                     sysfs device path
             property                The device properties
             all                      All values
        -p --path=SYSPATH           sysfs device path used for query or attribute walk
        -n --name=NAME              Node or symlink name used for query or attribute walk
        -r --root                   Prepend dev directory to path names
        -a --attribute-walk         Print all key matches walking along the chain
                                    of parent devices
        -d --device-id-of-file=FILE Print major:minor of device containing this file
        -x --export                 Export key/value pairs
        -P --export-prefix          Export the key name with a prefix
        -e --export-db              Export the content of the udev database
        -c --cleanup-db             Clean up the udev database
      



      • sys filesystem의 uevent의 환경변수 값 확인 (udev database정보)
      $ udevadm info  /dev/mmcblk2p1 
      or
      $ udevadm info  -q all /dev/mmcblk2p1 
      or
      $ udevadm info  /sys/block/mmcblk2/mmcblk2p1  // 3개의 정보들이 거의 동일하지만,DEVLINKS정보가 조금씩 다름 
      // /sys/device/..../mmcblk2p1의 uevnet 파악가능 (P는 /sys PATH)
      P: /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2/mmcblk2p1     
      N: mmcblk2p1   // /dev의 device node /dev/mmcblk2p1 
      S: disk/by-id/mmc-SA02G_0x207dfb75-part1       // 상위 N의 /dev/mmcblk2p1 의 link file /dev/disk/by-id/mmc-SA02G_0x207dfb75-part1
      S: disk/by-partuuid/0006c3b0-01                // 상위 N의 /dev/mmcblk2p1 의 link file /dev/disk/by-partuuid/0006c3b0-0
      S: disk/by-path/platform-2198000.usdhc-part1   // 상위 N의 /dev/mmcblk2p1 의 link file /dev/disk/by-path/platform-2198000.usdhc-part1
      S: disk/by-uuid/1497-59AD                      // 상위 N의 /dev/mmcblk2p1 의 link file /dev/disk/by-uuid/1497-59AD
      E: DEVLINKS=/dev/disk/by-path/platform-2198000.usdhc-part1 /dev/disk/by-uuid/1497-59AD /dev/disk/by-partuuid/0006c3b0-01 /dev/disk/by-id/mmc-SA02G_0x207dfb75-part1
      E: DEVNAME=/dev/mmcblk2p1
      E: DEVPATH=/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2/mmcblk2p1
      E: DEVTYPE=partition
      E: ID_FS_TYPE=vfat
      E: ID_FS_USAGE=filesystem
      E: ID_FS_UUID=1497-59AD
      E: ID_FS_UUID_ENC=1497-59AD
      E: ID_FS_VERSION=FAT32
      E: ID_NAME=SA02G
      E: ID_PART_ENTRY_DISK=179:24
      E: ID_PART_ENTRY_NUMBER=1
      E: ID_PART_ENTRY_OFFSET=73036
      E: ID_PART_ENTRY_SCHEME=dos
      E: ID_PART_ENTRY_SIZE=3002164
      E: ID_PART_ENTRY_TYPE=0xc
      E: ID_PART_ENTRY_UUID=0006c3b0-01
      E: ID_PART_TABLE_TYPE=dos
      E: ID_PART_TABLE_UUID=0006c3b0
      E: ID_PATH=platform-2198000.usdhc
      E: ID_PATH_TAG=platform-2198000_usdhc
      E: ID_SERIAL=0x207dfb75
      E: MAJOR=179
      E: MINOR=25
      E: PARTN=1
      E: SUBSYSTEM=block
      E: TAGS=:systemd:                   //  systemd의 *.device로 파일에서 추가됨 
      E: USEC_INITIALIZED=7347510      //  cat /proc/uptime 갱신된 정보시간 (boot이후)
      
      $ udevadm info  /dev/mmcblk2
      or
      $ udevadm info  -q all /dev/mmcblk2
      or
      $ udevadm info  /sys/block/mmcblk2
      P: /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2 // uevent 정보확인 
      N: mmcblk2
      S: disk/by-id/mmc-SA02G_0x207dfb75
      S: disk/by-path/platform-2198000.usdhc
      E: DEVLINKS=/dev/disk/by-id/mmc-SA02G_0x207dfb75 /dev/disk/by-path/platform-2198000.usdhc
      E: DEVNAME=/dev/mmcblk2
      E: DEVPATH=/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2
      E: DEVTYPE=disk
      E: ID_NAME=SA02G
      E: ID_PART_TABLE_TYPE=dos
      E: ID_PART_TABLE_UUID=0006c3b0
      E: ID_PATH=platform-2198000.usdhc
      E: ID_PATH_TAG=platform-2198000_usdhc
      E: ID_SERIAL=0x207dfb75
      E: MAJOR=179
      E: MINOR=24
      E: SUBSYSTEM=block
      E: TAGS=:systemd:             //  systemd의 *.device로 파일에서 추가됨 
      E: USEC_INITIALIZED=6995415  //  cat /proc/uptime 갱신된 정보시간 (boot이후)
      


      TAGS=:systemd 일 경우 systemd의 *.device로 udev rule에 추가
        https://www.freedesktop.org/software/systemd/man/systemd.device.html

      systemd-udevd service 

      • 좌측 Node 의미 및 분석방법 
      1. N: is for device Name in /dev
      2. S: is for Symlinks to that device name in /dev  (추후 udev/rules/에서 SYMLINK)
      3. P: is for device Path in /sys
      4. E: is for device properties in udev
        https://askubuntu.com/questions/725951/what-do-devices-environment-variable-lists-prefixes-p-n-s-e-mean


      • P: Node는 /sys의 device path이므로 이곳의 uevent 를 확인중요
      uevent 중심으로 분석을 해야함
      $ cat /sys/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2/mmcblk2p1/uevent
      MAJOR=179
      MINOR=25
      DEVNAME=mmcblk2p1
      DEVTYPE=partition
      PARTN=1
      
      $ cat /sys/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2/uevent
      MAJOR=179
      MINOR=24
      DEVNAME=mmcblk2
      DEVTYPE=disk
      


      • N: /dev의 device name 확인
      $ ls /dev/mmcblk*
      /dev/mmcblk2       /dev/mmcblk3       /dev/mmcblk3boot1  /dev/mmcblk3p2
      /dev/mmcblk2p1     /dev/mmcblk3boot0  /dev/mmcblk3p1     /dev/mmcblk3rpmb 

      • S:  상위 N: /dev의 device name의 symbolic link list 
      상위 N:의 /dev/mmclbk2 or /dev/mmcblk2p1의 /dev 내의 symbolic link 말하며,이는 DEVLINKS와 동일하다.
      rule에서도 SYMLINK을 이용하여 추가도 가능함

      $ ls /dev/disk/by-id/
      mmc-S0J57X_0x09231300        mmc-SA02G_0x207dfb75
      mmc-S0J57X_0x09231300-part1  mmc-SA02G_0x207dfb75-part1
      mmc-S0J57X_0x09231300-part2
      
      $ ls /dev/disk/by-path/
      platform-2198000.usdhc        platform-219c000.usdhc-boot1
      platform-2198000.usdhc-part1  platform-219c000.usdhc-part1
      platform-219c000.usdhc        platform-219c000.usdhc-part2
      platform-219c000.usdhc-boot0

      • E: uevent를 통해 udev 설정된 환경값 
      이부분은 아래와 기본정보는 /sys 의 uevent 로 확인가능하며, 다른정보는 database에서 가져옴

      • 이외 다른 uevent 값 검색 분석 
      $ find /sys -name uevent | xargs cat  // 대부분 Device 정보 와 호환정보(연결)
      ....
      MAJOR=253
      MINOR=0
      DEVNAME=rtc0
      OF_NAME=snvs
      OF_FULLNAME=/soc/aips-bus@2000000/snvs@20cc000
      OF_COMPATIBLE_0=fsl,sec-v4.0-mon
      OF_COMPATIBLE_1=syscon
      OF_COMPATIBLE_2=simple-mfd
      OF_COMPATIBLE_N=3
      ...
      $ find /sys -name uevent | xargs cat | grep DEVLINKS
      없음 
      $ find /sys -name uevent | xargs cat | grep DEVNAME
      DEVNAME=mem
      DEVNAME=zero
      DEVNAME=kmsg
      DEVNAME=full
      DEVNAME=urandom
      DEVNAME=null
      DEVNAME=random
      DEVNAME=pxp_device
      DEVNAME=hwrng
      DEVNAME=autofs
      ......

      2.2 udevadm info 의 attribute 분석 

      udev의 기본적인 uevent의 정보와 sys filesystem의 attribute를 분석할때, -a를 옵션을 주어 분석이 가능하다.
      ATTR{x}는 해당 /sys file 주소의 값들을 출력을 해주며, 추후 rule에서도 이를 적용가능하다.

      1. uevent 정보(KERNEL/SUBSYSTEM/DRIVER) 
      2. attribute 정보(ATTR{xxx}  

      parent기반으로 분석되기때문에 호출되는 순서를 파악가능하며 최종단을 주목

      $ udevadm info -a /dev/mmcblk2   // /dev node로  모든 attribute를 출력 
      or
      $ udevadm info -a /sys/block/mmcblk2  //sys filesystem의 모든 attribute를 출력 
      
      Udevadm info starts with the device specified by the devpath and then
      walks up the chain of parent devices. It prints for every device
      found, all possible attributes in the udev rules key format.
      A rule to match, can be composed by the attributes of the device
      and the attributes from one single parent device.
      // 아래 looking at device 위치에 /sys file의 uevent node 확인 (최종 device의 길이 중요)
        looking at device '/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2':  
          KERNEL=="mmcblk2"     //device의 node name (상위 device의 마지막 node)  uevent 정보는 별도의 db를 가지고 있음 
          SUBSYSTEM=="block"    //mmcblk2의 SUBSYSTEM   
          DRIVER==""            //uevent 의 정보 
          ATTR{alignment_offset}=="0"      // cat /sys/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2/alignment_offset
          ATTR{capability}=="50"           // cat /sys/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2/capability
          ATTR{discard_alignment}=="0"     // cat /sys/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2/ext_range
          ATTR{ext_range}=="256"           //  ATTR{x} 모두 상동  
          ATTR{force_ro}=="0"
          ATTR{hidden}=="0"
          ATTR{inflight}=="       0        0"
          ATTR{range}=="8"
          ATTR{removable}=="0"
          ATTR{ro}=="0"
          ATTR{size}=="3842048"
          ATTR{stat}=="      95       16     6363      545        0        0        0        0        0      400      440        0        0        0        0"
      // Parent device 의 uevent이며, 분석에 중요하며, SD Card Device의 정보를 얻은 시점 
        looking at parent device '/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234':  //   
          KERNELS=="mmc2:1234"
          SUBSYSTEMS=="mmc"
          DRIVERS=="mmcblk"
          ATTRS{cid}=="02544d534130324704207dfb7500a800"     // MMC의 Register CID  
          ATTRS{csd}=="002e00325b5aa3a9ffffff800a800000"     // MMC의 Register CSD   
          ATTRS{date}=="08/2010"                             // 날짜정보, Filesystem 기준으로 생각됨  
          ATTRS{dsr}=="0x404"                                // MMC의 Register DSR  
          ATTRS{erase_size}=="512"                           // MMC의 경우 512 block 단위임  
          ATTRS{fwrev}=="0x4"
          ATTRS{hwrev}=="0x0"
          ATTRS{manfid}=="0x000002"                          // 제조사 ID  
          ATTRS{name}=="SA02G"                               // SD Card Name 
          ATTRS{ocr}=="0x00040000"                           // MMC의 Register OCR  
          ATTRS{oemid}=="0x544d"
          ATTRS{preferred_erase_size}=="4194304"
          ATTRS{rca}=="0x1234"                               // MMC의 Register RCA  
          ATTRS{scr}=="0225800001000000"                     // MMC의 Register SCR  
          ATTRS{serial}=="0x207dfb75"
          ATTRS{ssr}=="00000000000000280202900100aa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
          ATTRS{type}=="SD"                                   // SD Card 임, eMMC가 아님  
      // Parent device 의 uevent  SD Card Device를 찾은시점 
        looking at parent device '/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2':
          KERNELS=="mmc2"
          SUBSYSTEMS=="mmc_host"
          DRIVERS==""
      
        looking at parent device '/devices/soc0/soc/2100000.aips-bus/2198000.usdhc':
          KERNELS=="2198000.usdhc"
          SUBSYSTEMS=="platform"
          DRIVERS=="sdhci-esdhc-imx"
          ATTRS{driver_override}=="(null)"
      
        looking at parent device '/devices/soc0/soc/2100000.aips-bus':
          KERNELS=="2100000.aips-bus"
          SUBSYSTEMS=="platform"
          DRIVERS==""
          ATTRS{driver_override}=="(null)"
      
        looking at parent device '/devices/soc0/soc':
          KERNELS=="soc"
          SUBSYSTEMS=="platform"
          DRIVERS==""
          ATTRS{driver_override}=="(null)"
      
        looking at parent device '/devices/soc0':
          KERNELS=="soc0"
          SUBSYSTEMS=="soc"
          DRIVERS==""
          ATTRS{family}=="Freescale i.MX"
          ATTRS{revision}=="1.4"
          ATTRS{soc_id}=="i.MX6SX"

      $ udevadm info -a  /dev/mmcblk2p1  // 각 Partition 정보와 비교 
      
      Udevadm info starts with the device specified by the devpath and then
      walks up the chain of parent devices. It prints for every device
      found, all possible attributes in the udev rules key format.
      A rule to match, can be composed by the attributes of the device
      and the attributes from one single parent device.
      // uevent node 확인가능. 상위 node에 mmcblk2p1 추가되었으며,나머지는 동일
        looking at device '/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2/mmcblk2p1':
          KERNEL=="mmcblk2p1"
          SUBSYSTEM=="block"
          DRIVER==""
          ATTR{alignment_offset}=="0"
          ATTR{discard_alignment}=="354304"
          ATTR{inflight}=="       0        0"
          ATTR{partition}=="1"
          ATTR{ro}=="0"
          ATTR{size}=="3002164"
          ATTR{start}=="73036"
          ATTR{stat}=="      53       16     4275      309        0        0        0        0        0      260      270        0        0        0        0"
      // 상위 (udevadm info -a /dev/mmcblk2)  동일한 device node 이며 상위와 완전동일  
        looking at parent device '/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2':
          KERNELS=="mmcblk2"
          SUBSYSTEMS=="block"
          DRIVERS==""
          ATTRS{alignment_offset}=="0"
          ATTRS{capability}=="50"
          ATTRS{discard_alignment}=="0"
          ATTRS{ext_range}=="256"
          ATTRS{force_ro}=="0"
          ATTRS{hidden}=="0"
          ATTRS{inflight}=="       0        0"
          ATTRS{range}=="8"
          ATTRS{removable}=="0"
          ATTRS{ro}=="0"
          ATTRS{size}=="3842048"
          ATTRS{stat}=="      95       16     6363      545        0        0        0        0        0      400      440        0        0        0        0"
      
        looking at parent device '/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234':
          KERNELS=="mmc2:1234"
          SUBSYSTEMS=="mmc"
          DRIVERS=="mmcblk"
          ATTRS{cid}=="02544d534130324704207dfb7500a800"
          ATTRS{csd}=="002e00325b5aa3a9ffffff800a800000"
          ATTRS{date}=="08/2010"
          ATTRS{dsr}=="0x404"
          ATTRS{erase_size}=="512"
          ATTRS{fwrev}=="0x4"
          ATTRS{hwrev}=="0x0"
          ATTRS{manfid}=="0x000002"
          ATTRS{name}=="SA02G"
          ATTRS{ocr}=="0x00040000"
          ATTRS{oemid}=="0x544d"
          ATTRS{preferred_erase_size}=="4194304"
          ATTRS{rca}=="0x1234"
          ATTRS{scr}=="0225800001000000"
          ATTRS{serial}=="0x207dfb75"
          ATTRS{ssr}=="00000000000000280202900100aa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
          ATTRS{type}=="SD"
      
        looking at parent device '/devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2':
          KERNELS=="mmc2"
          SUBSYSTEMS=="mmc_host"
          DRIVERS==""
      
        looking at parent device '/devices/soc0/soc/2100000.aips-bus/2198000.usdhc':
          KERNELS=="2198000.usdhc"
          SUBSYSTEMS=="platform"
          DRIVERS=="sdhci-esdhc-imx"
          ATTRS{driver_override}=="(null)"
      
        looking at parent device '/devices/soc0/soc/2100000.aips-bus':
          KERNELS=="2100000.aips-bus"
          SUBSYSTEMS=="platform"
          DRIVERS==""
          ATTRS{driver_override}=="(null)"
      
        looking at parent device '/devices/soc0/soc':
          KERNELS=="soc"
          SUBSYSTEMS=="platform"
          DRIVERS==""
          ATTRS{driver_override}=="(null)"
      
        looking at parent device '/devices/soc0':
          KERNELS=="soc0"
          SUBSYSTEMS=="soc"
          DRIVERS==""
          ATTRS{family}=="Freescale i.MX"
          ATTRS{revision}=="1.4"
          ATTRS{soc_id}=="i.MX6SX"
      


      2.3  udevadm monitor를 이용확인

      udevadm의 monitor를 이용하여 sdcard의 card detection 부분을 체크

      $ udevadm monitor  -h
      udevadm monitor [OPTIONS]
      
      Listen to kernel and udev events.
      
        -h --help                                Show this help
        -V --version                             Show package version
        -p --property                            Print the event properties
        -k --kernel                              Print kernel uevents
        -u --udev                                Print udev events
        -s --subsystem-match=SUBSYSTEM[/DEVTYPE] Filter events by subsystem
        -t --tag-match=TAG                       Filter events by tag
      
      

      실시간 모니터로 아래와 같이 uevent를 볼수 있으며 옵션을 추가하여 각 event를 더 확인하자.

      $ udevadm monitor
      monitor will print the received events for:
      UDEV - the event which udev sends out after rule processing
      KERNEL - the kernel uevent
      
      mmc2: card 1234 removed
      KERNEL[179853.651358] remove   /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2/mmcblk2p1 (block)
      KERNEL[179853.654058] remove   /devices/virtual/bdi/179:24 (bdi)
      KERNEL[179853.654755] remove   /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2 (block)
      UDEV  [179853.662386] remove   /devices/virtual/bdi/179:24 (bdi)
      KERNEL[179853.671233] unbind   /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234 (mmc)
      KERNEL[179853.671436] remove   /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234 (mmc)
      UDEV  [179853.699415] remove   /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2/mmcblk2p1 (block)
      UDEV  [179853.704243] remove   /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2 (block)
      UDEV  [179853.715698] unbind   /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234 (mmc)
      UDEV  [179853.716975] remove   /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234 (mmc)
      mmc2: host does not support reading read-only switch, assuming write-enable
      mmc2: new high speed SD card at address 1234
      KERNEL[179860.947683] add      /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234 (mmc)
      UDEV  [179860.956872] add      /devices/soc0/soc/2100000.aips-bummcblk2: mmc2:1234 SA02G 1.83 GiB
      s/2198000.usdhc/mmc_host/mmc2/mmc2:1234 (mmc)
      KERNEL[179860.966523] add      /devices/virtual/bd mmcblk2: p1
      i/179:24 (bdi)
      UDEV  [179860.977474] add      /devices/virtual/bdi/179:24 (bdi)
      KERNEL[179860.978045] add      /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2 (block)
      KERNEL[179860.980267] add      /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2/mmcblk2p1 (block)
      KERNEL[179860.983182] bind     /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234 (mmc)
      UDEV  [179861.117857] add      /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2 (block)
      FAT-fs (mmcblk2p1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
      UDEV  [179861.423592] add      /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234/block/mmcblk2/mmcblk2p1 (block)
      UDEV  [179861.426851] bind     /devices/soc0/soc/2100000.aips-bus/2198000.usdhc/mmc_host/mmc2/mmc2:1234 (mmc)
      


      3. udev Rule 만드는 법 

      udevadm info 와 monitor를 통해 기본 udev의 정보와 sys file system의 정보를 이용하여 udev rule을 간단히 만들어보자.

      • udev rule의 기본저장장소
      1. /lib/udev/rules.d/
      2. /etc/udev/rules.d/  : User는 이곳에 설정하여 추가해서 넣자 
      3. /dev/udev/rules.d/

      • Rule에서 기본적으로 match되는 정보  
      1. KERNEL : device의 kernel 이름 , device의 이름과 match
      2. SUBSYSTEM : device의 subsystem과 match
      3. DRIVER: device와 관련된 driver name과 match
      4. NAME:  /dev 에서 사용되어지는 device node와 match  
      5. SYMLINK: NAME의 대신에 사용되어지는 symbloic link list
      6. ATTRS{x}: 상위 sys filesystem의 정보와 match
      7. ENV{DEVLINKS}: 상위 E: Node 정보와 match 

      • matching 할때 pattern 
      1. *:  어느 문자들이든 match
      2. ?:  어느 한 문자만  match
      3. []:  범위를 정해서 match

      • Event 와 실행 
      1. ACTION: 해당 정보의 device가 add or remove , change가 있을 경우 
      2. RUN : 조건이 충족되면 실행을 하는 command 

      RUN에 ENV{ } 정보를 출력하고 싶다면, %E{xx}로 사용가능
      SYMLINK를 이용하여 /dev에 새로 device node의 symblolic link 생성가능
      좀 더 사용을 하면 GOTO와 LABEL을 사용하며, 예제를 보면 쉽게 이해가 가능


      3.1  MMC Device 와 udev Rule 생성 

      • MMC의 동작 rule 생성 및 적용 
      mmcblk2p 가 Hotplug 될 때, add와 remove에 맞게 간단히 RUN을 사용하여 작성

      $ cat /etc/udev/rules.d/10-mmc.rules  //RUN을 추가하여 지속적으로 실행가능 
      # Mount and remove mmc partitions manually for 32G  
      # udevadm info /dev/mmcblk2 에서 E DEVNAME 부분확인 , 상위 환경변수부분 참조
      
      ACTION=="add" KERNEL=="mmcblk[2]p[0-9]", RUN+="/bin/mkdir -p /media/card", RUN+="/bin/mount %E{DEVNAME} /media/card"
      ACTION=="remove" KERNEL=="mmcblk[2]p[0-9]", RUN+="/bin/umount -f /media/card" , RUN+="/bin/rmdir /media/card"
      


      udev Basic Rule 사용법 (systemd-udevd.service에서 관리)
        https://www.freedesktop.org/software/systemd/man/udev.html#
        http://www.reactivated.net/writing_udev_rules.html
        https://wiki.debian.org/udev

      udev Rule의 예제 및 udevadm 사용법
        https://gnu-linux.org/writing-udev-rules-for-flash-drive.html
        https://kernel.googlesource.com/pub/scm/linux/hotplug/udev/+/1ed38f41749dde482e164e692255b60c38b5d876/etc/udev/rules.d/80-drivers.rules

      udev 관련 Kernel 설정
        https://wiki.gentoo.org/wiki/Udev/ko


      3.2 다른 Device 와 systemd 의 Service 연결적용 

      • udev 의 device(ttyACM0) 기본분석

      일반적으로 많이 사용되는 USB Serial ttyACM에 udev에 연결하여 systemd 와 함께 service 할 수 있도록 설정.

      $ ls /dev/ttyACM0                // USB serial 존재파악 
      
      $ udevadm info -a -n /dev/ttyACM0                    // udev 값 분석 및 각 ATTRS 값 확인 
      
      
      // 분석방법은 아래와 같이 최종 driver 단 기준부터 그 위의 KERNEL/SUBSYSTEM/ ATTRS  중심으로 파악  
      ...........
        looking at device '/devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.0/tty/ttyACM0':
          KERNEL=="ttyACM0"
          SUBSYSTEM=="tty"
          DRIVER==""
      
        looking at parent device '/devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.0':
          KERNELS=="1-1.1:1.0"
          SUBSYSTEMS=="usb"
          DRIVERS=="cdc_acm"
          ATTRS{authorized}=="1"
          ATTRS{bAlternateSetting}==" 0"
          ATTRS{bInterfaceClass}=="02"
          ATTRS{bInterfaceNumber}=="00"
          ATTRS{bInterfaceProtocol}=="01"
          ATTRS{bInterfaceSubClass}=="02"
          ATTRS{bNumEndpoints}=="01"
          ATTRS{bmCapabilities}=="7"
          ATTRS{iad_bFirstInterface}=="00"
          ATTRS{iad_bFunctionClass}=="02"
          ATTRS{iad_bFunctionProtocol}=="01"
          ATTRS{iad_bFunctionSubClass}=="02"
          ATTRS{iad_bInterfaceCount}=="02"
          ATTRS{interface}=="PLSx"
          ATTRS{supports_autosuspend}=="1"
      
        looking at parent device '/devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1/1-1.1':
          KERNELS=="1-1.1"
          SUBSYSTEMS=="usb"
          DRIVERS=="usb"
          ATTRS{authorized}=="1"
          ATTRS{avoid_reset_quirk}=="0"
          ATTRS{bConfigurationValue}=="1"
          ATTRS{bDeviceClass}=="ef"
          ATTRS{bDeviceProtocol}=="01"
          ATTRS{bDeviceSubClass}=="02"
          ATTRS{bMaxPacketSize0}=="64"
          ATTRS{bMaxPower}=="100mA"
          ATTRS{bNumConfigurations}=="1"
          ATTRS{bNumInterfaces}=="14"
          ATTRS{bcdDevice}=="1730"
          ATTRS{bmAttributes}=="e0"
          ATTRS{busnum}=="1"
          ATTRS{configuration}==""
          ATTRS{devnum}=="5"
          ATTRS{devpath}=="1.1"
          ATTRS{devspec}=="  (null)"
          ATTRS{idProduct}=="005b"
          ATTRS{idVendor}=="1e2d"
          ATTRS{ltm_capable}=="no"
          ATTRS{manufacturer}=="Cinterion Wireless Modules"
          ATTRS{maxchild}=="0"
          ATTRS{product}=="PLSx"
          ATTRS{quirks}=="0x0"
          ATTRS{removable}=="unknown"
          ATTRS{rx_lanes}=="1"
          ATTRS{speed}=="480"
          ATTRS{tx_lanes}=="1"
          ATTRS{urbnum}=="122"
          ATTRS{version}==" 2.00"
      .............
        looking at parent device '/devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1':
          KERNELS=="usb1"
          SUBSYSTEMS=="usb"
          DRIVERS=="usb"
          ATTRS{authorized}=="1"
          ATTRS{authorized_default}=="1"
          ATTRS{avoid_reset_quirk}=="0"
          ATTRS{bConfigurationValue}=="1"
          ATTRS{bDeviceClass}=="09"
          ATTRS{bDeviceProtocol}=="01"
          ATTRS{bDeviceSubClass}=="00"
          ATTRS{bMaxPacketSize0}=="64"
          ATTRS{bMaxPower}=="0mA"
          ATTRS{bNumConfigurations}=="1"
          ATTRS{bNumInterfaces}==" 1"
          ATTRS{bcdDevice}=="0419"
          ATTRS{bmAttributes}=="e0"
          ATTRS{busnum}=="1"
          ATTRS{configuration}==""
          ATTRS{devnum}=="1"
          ATTRS{devpath}=="0"
          ATTRS{idProduct}=="0002"
          ATTRS{idVendor}=="1d6b"
          ATTRS{interface_authorized_default}=="1"
          ATTRS{ltm_capable}=="no"
          ATTRS{manufacturer}=="Linux 4.19.35-1.1.0+g0f9917c ehci_hcd"
          ATTRS{maxchild}=="1"
          ATTRS{product}=="EHCI Host Controller"
          ATTRS{quirks}=="0x0"
          ATTRS{removable}=="unknown"
          ATTRS{rx_lanes}=="1"
          ATTRS{serial}=="ci_hdrc.1"
          ATTRS{speed}=="480"
          ATTRS{tx_lanes}=="1"
          ATTRS{urbnum}=="25"
          ATTRS{version}==" 2.00"
      .....
      
      // USB CDC 중 ACM은 일반적으로 USB Serial로 많이 사용되지만, 꼭 Serial으로만 사용해야하는 것은 아니다. 
      // 세부사항은 USB CDC 종류에서 각각 파악하자  
      
      $ udevadm info -a -n /dev/ttyACM0 | grep serial  // ttyACM0을 USB Serial로 사용하기 위해 serial 이름파악 
      ATTRS{serial}=="ci_hdrc.1"
      

      • udev 의 device(ttyACM0) 와 systemd 의 service 연결
      각 udev rule에서 ttyACM 관련부분을 검색 한 후 이를 분석한 후, 직접 수정
      $ find /etc/udev/rules.d/  -name *ttyACM*  // udev file 찾기 (우선순위 etc -> lib) 못찾으면 grep 사용 
      $ find /lib/udev/rules.d/  -name *ttyACM*  
      
      // 나의 경우, KERENL에, ttyACM0을 넣고, serial을 더 좀 더 확실히 하기 위해 ATTRS{serial} 추가했지만, 자기 구성대로 변경
      // SYSTEMD_WANTS 사용시 udev database에 TAG+="systemd" 넣지 않는다면, systemd에서 찾지 못한다 (세부내용은 Manual)  
      // 이기능은 systemd의 Want=에 추가되며, 추후 systemd의 *.socket 의 BindToDevice= 와 연결가능 
      
      $ cat /etc/udev/rules.d/20-ttyACM0.rules  // KERNEL의 Device 와 Serial 이름으로 동작 
      KERNEL=="ttyACM0", ATTRS{serial}=="ci_hdrc.1" , TAG+="systemd", ENV{SYSTEMD_WANTS}="my.service"
      

      udev Rule에 TAG+="systemd"와 ENV{SYSTEMD_WANTS} 와 udev Database
        https://www.freedesktop.org/software/systemd/man/systemd.device.html
        https://www.freedesktop.org/software/systemd/man/udev.html#

      • 연결될 systemd의 service 구성

      systemd의 service 중 (BindToDevice대신) BindTo 와 After 부분설정을 위해 각 값 검색
      $ systemctl list-units --all --full   //  systemctl list-units --all --full 의 정보가 너무 많음 
      $ systemctl list-units --all --full | grep ".device"   //  systemctl list-units --all --full 의 정보가 너무 많아 device만 찾음 
      
      // device 구성을 보면, parent가 존재하므로, 점점 node가 길어지면, 최종으로 load되는 부분을 찾아야함 
      // systemd.device에서 ttyACM0 or 상위 ATTR 값을 넣어 검색범위를 좁힘 
      $ systemctl list-units --all --full | grep ".device" | grep "ci_hdrc.1" // systemd.device 에 상위 ATTR 값 동일부분확인
        dev-serial-by\x2dpath-platform\x2dci_hdrc.1\x2dusb\x2d0:1.1:1.0.device                                              loaded    active   plugged   PLSx         
        dev-serial-by\x2dpath-platform\x2dci_hdrc.1\x2dusb\x2d0:1.1:1.2.device                                              loaded    active   plugged   PLSx         
        dev-serial-by\x2dpath-platform\x2dci_hdrc.1\x2dusb\x2d0:1.1:1.4.device                                              loaded    active   plugged   PLSx         
        dev-serial-by\x2dpath-platform\x2dci_hdrc.1\x2dusb\x2d0:1.1:1.6.device                                              loaded    active   plugged   PLSx         
        dev-serial-by\x2dpath-platform\x2dci_hdrc.1\x2dusb\x2d0:1.1:1.8.device                                              loaded    active   plugged   PLSx         
        sys-devices-soc0-soc-2100000.aips\x2dbus-2184200.usb-ci_hdrc.1-usb1-1\x2d1-1\x2d1.1-1\x2d1.1:1.0-tty-ttyACM0.device loaded    active   plugged   PLSx         
        sys-devices-soc0-soc-2100000.aips\x2dbus-2184200.usb-ci_hdrc.1-usb1-1\x2d1-1\x2d1.1-1\x2d1.1:1.10-net-usb0.device   loaded    active   plugged   PLSx         
        sys-devices-soc0-soc-2100000.aips\x2dbus-2184200.usb-ci_hdrc.1-usb1-1\x2d1-1\x2d1.1-1\x2d1.1:1.12-net-usb1.device   loaded    active   plugged   PLSx         
        sys-devices-soc0-soc-2100000.aips\x2dbus-2184200.usb-ci_hdrc.1-usb1-1\x2d1-1\x2d1.1-1\x2d1.1:1.2-tty-ttyACM1.device loaded    active   plugged   PLSx         
        sys-devices-soc0-soc-2100000.aips\x2dbus-2184200.usb-ci_hdrc.1-usb1-1\x2d1-1\x2d1.1-1\x2d1.1:1.4-tty-ttyACM2.device loaded    active   plugged   PLSx         
        sys-devices-soc0-soc-2100000.aips\x2dbus-2184200.usb-ci_hdrc.1-usb1-1\x2d1-1\x2d1.1-1\x2d1.1:1.6-tty-ttyACM3.device loaded    active   plugged   PLSx         
        sys-devices-soc0-soc-2100000.aips\x2dbus-2184200.usb-ci_hdrc.1-usb1-1\x2d1-1\x2d1.1-1\x2d1.1:1.8-tty-ttyACM4.device loaded    active   plugged   PLSx
      
      $ systemctl list-units --all --full | grep ".device" | grep "ttyACM0" // systemd.device 에 ttyACM0 재확인 
        dev-ttyACM0.device                                                                                                  loaded    active   plugged   PLSx         
        sys-devices-soc0-soc-2100000.aips\x2dbus-2184200.usb-ci_hdrc.1-usb1-1\x2d1-1\x2d1.1-1\x2d1.1:1.0-tty-ttyACM0.device loaded    active   plugged   PLSx
      

      udev Rule에 같이 동작할 systemd 의 service 설정
      **system unit 과 system.service manual 참조
      //상위 udev의 Rule에서 적용했던 부분이 동작할 경우 실행 (ttyACM0) 
      //Unit의 BindTo 와 After를 *.service로만 한정지어 생각했는데, device를 비롯하여 mount 등 모두 가능
      //Unit의 대상은 모든 systemd의 설정의 기본이며, service/socket/device/mount/등 모두 적용대상
      $ vi /lib/systemd/system/my.service 
      or 
      $ vi /etc/systemd/system/my.service 
      [Unit]
      Description=TEST Service for ttyACM0
      BindsTo=sys-devices-soc0-soc-2100000.aips\x2dbus-2184200.usb-ci_hdrc.1-usb1-1\x2d1-1\x2d1.1-1\x2d1.1:1.0-tty-ttyACM0.device
      After=sys-devices-soc0-soc-2100000.aips\x2dbus-2184200.usb-ci_hdrc.1-usb1-1\x2d1-1\x2d1.1-1\x2d1.1:1.0-tty-ttyACM0.device
      
      # BindsTo 는 Requires 와 유사하게 dependencies를 요구하는 설정이며, Requres 보다 좀 더 강력하다고 하며, 
      # After와 함께 같이 사용할때 최적이라고 한다.
      # 주의 할 것은 Fail 될 경우, Skip되므로 이 부분 주의하며, 상위 Device가 연결될때 Timing을 기다림
      
      [Service]
      ExecStart=test start 
      
      [Install]
      WantedBy=multi-user.target
      

      1. udev에서 ttyACM0 상위정보의 uevent가 오면 이를 udev에 TAG를 사용하여 systemd에 노출하고 service로 연결
      2. 상위 service에서 AfterBindsTo는 systemd의 service에 연결하여 Timing을 조절(제대로 붙기전에는 실행 불가능) 

      아래의 사이트에서 쉽게 찾아 연결했으며, 세부내용은 아래사이트 참조

      systemd의 unit 과 service 설정정보
        https://www.freedesktop.org/software/systemd/man/systemd.unit.html
        https://www.freedesktop.org/software/systemd/man/systemd.unit.html#Mapping%20of%20unit%20properties%20to%20their%20inverses
        https://www.freedesktop.org/software/systemd/man/systemd.service.html#


      $ udevadm info /dev/ttyACM0 // 상위 실행 후 동작확인 
      P: /devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.0/tty/ttyACM0
      N: ttyACM0
      S: serial/by-id/usb-Cinterion_Wireless_Modules_PLSx-if00
      S: serial/by-path/platform-ci_hdrc.1-usb-0:1.1:1.0
      E: DEVLINKS=/dev/serial/by-path/platform-ci_hdrc.1-usb-0:1.1:1.0 /dev/serial/by-id/usb-Cinterion_Wireless_Modules_PLSx-if00
      E: DEVNAME=/dev/ttyACM0
      E: DEVPATH=/devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.0/tty/ttyACM0
      E: ID_BUS=usb
      E: ID_MODEL=PLSx
      E: ID_MODEL_ENC=PLSx
      E: ID_MODEL_ID=005b
      E: ID_PATH=platform-ci_hdrc.1-usb-0:1.1:1.0
      E: ID_PATH_TAG=platform-ci_hdrc_1-usb-0_1_1_1_0
      E: ID_REVISION=1730
      E: ID_SERIAL=Cinterion_Wireless_Modules_PLSx
      E: ID_TYPE=generic
      E: ID_USB_CLASS_FROM_DATABASE=Miscellaneous Device
      E: ID_USB_DRIVER=cdc_acm
      E: ID_USB_INTERFACES=:020201:0a0000:020200:020600:
      E: ID_USB_INTERFACE_NUM=00
      E: ID_USB_PROTOCOL_FROM_DATABASE=Interface Association
      E: ID_VENDOR=Cinterion_Wireless_Modules
      E: ID_VENDOR_ENC=Cinterion\x20Wireless\x20Modules
      E: ID_VENDOR_ID=1e2d
      E: MAJOR=166
      E: MINOR=0
      E: SUBSYSTEM=tty
      E: SYSTEMD_WANTS=my.service   // systemd service 확인 
      E: TAGS=:systemd:             // TAG의 systemd 추가 확인 
      E: USEC_INITIALIZED=19217285
      

      udev 와 systemd 연결
        https://unix.stackexchange.com/questions/89691/how-do-i-connect-a-3g-dongle-using-systemd

      systemd 기본사용법
        https://ahyuo79.blogspot.com/2020/01/systemd.html


      4. udevadm test 와 trigger를 이용하여 테스트 

      새로 만든 udev rule에 ACTION Event를 주어 SW로만 테스트 진행가능하며, 본인이 좀 더 세부 테스트를 한다면, 다양한 옵션설정도 가능.

      아래의 두가지 방식으로 테스트 가능

      • udev 의 테스트 방식 

      $ udevadm test -h
      $ udevadm test [OPTIONS] DEVPATH
      
      Test an event run.
      
        -h --help                            Show this help
        -V --version                         Show package version
        -a --action=ACTION                   Set action string
        -N --resolve-names=early|late|never  When to resolve names
      


      • udev에 uevent를 주어 테스트 진행 

       $ udevadm trigger  -h
      udevadm trigger [OPTIONS] DEVPATH
      
      Request events from the kernel.
      
        -h --help                         Show this help
        -V --version                      Show package version
        -v --verbose                      Print the list of devices while running
        -n --dry-run                      Do not actually trigger the events
        -t --type=                        Type of events to trigger
                devices                     sysfs devices (default)
                subsystems                  sysfs subsystems and drivers
        -c --action=ACTION                Event action value, default is "change"
        -s --subsystem-match=SUBSYSTEM    Trigger devices from a matching subsystem
        -S --subsystem-nomatch=SUBSYSTEM  Exclude devices from a matching subsystem
        -a --attr-match=FILE[=VALUE]      Trigger devices with a matching attribute
        -A --attr-nomatch=FILE[=VALUE]    Exclude devices with a matching attribute
        -p --property-match=KEY=VALUE     Trigger devices with a matching property
        -g --tag-match=KEY=VALUE          Trigger devices with a matching property
        -y --sysname-match=NAME           Trigger devices with this /sys path
           --name-match=NAME              Trigger devices with this /dev name
        -b --parent-match=NAME            Trigger devices with that parent device
        -w --settle                       Wait for the triggered events to complete
      


      실제테스트 진행 
      • 상위 만들어진 rule에 SW로 테스트 진행 (문제발생)
      $ udevadm test -a remove /dev/mmcblk2
      or
      $ udevadm test -a remove  /sys/block/mmcblk2
      calling: test
      version 239
      This program is for debugging only, it does not run any program
      specified by a RUN key. It may show incorrect results, because
      some values may be different, or not available at a simulation run.
      
      Load module index
      Skipping empty file: /etc/systemd/network/99-default.link
      Created link configuration context.
      Reading rules file: /etc/udev/rules.d/10-imx.rules
      Reading rules file: /etc/udev/rules.d/30-mmc.rules
      Reading rules file: /lib/udev/rules.d/50-firmware.rules
      Reading rules file: /lib/udev/rules.d/50-udev-default.rules
      Reading rules file: /lib/udev/rules.d/60-block.rules
      Reading rules file: /lib/udev/rules.d/60-cdrom_id.rules
      Reading rules file: /lib/udev/rules.d/60-drm.rules
      Reading rules file: /lib/udev/rules.d/60-evdev.rules
      Reading rules file: /lib/udev/rules.d/60-input-id.rules
      Reading rules file: /lib/udev/rules.d/60-persistent-alsa.rules
      Reading rules file: /lib/udev/rules.d/60-persistent-input.rules
      Reading rules file: /lib/udev/rules.d/60-persistent-storage-tape.rules
      Reading rules file: /lib/udev/rules.d/60-persistent-storage.rules
      Reading rules file: /lib/udev/rules.d/60-persistent-v4l.rules
      Reading rules file: /lib/udev/rules.d/60-sensor.rules
      Reading rules file: /lib/udev/rules.d/60-serial.rules
      Reading rules file: /lib/udev/rules.d/64-btrfs.rules
      Reading rules file: /lib/udev/rules.d/70-joystick.rules
      Reading rules file: /lib/udev/rules.d/70-mouse.rules
      Reading rules file: /lib/udev/rules.d/70-power-switch.rules
      Reading rules file: /lib/udev/rules.d/70-touchpad.rules
      Reading rules file: /lib/udev/rules.d/70-uaccess.rules
      Reading rules file: /lib/udev/rules.d/71-seat.rules
      Reading rules file: /lib/udev/rules.d/73-seat-late.rules
      Reading rules file: /lib/udev/rules.d/75-net-description.rules
      Reading rules file: /lib/udev/rules.d/75-probe_mtd.rules
      Reading rules file: /lib/udev/rules.d/78-sound-card.rules
      Reading rules file: /lib/udev/rules.d/80-drivers.rules
      Reading rules file: /lib/udev/rules.d/80-net-setup-link.rules
      Reading rules file: /lib/udev/rules.d/90-alsa-restore.rules
      Reading rules file: /lib/udev/rules.d/90-vconsole.rules
      Reading rules file: /lib/udev/rules.d/97-hid2hci.rules
      Reading rules file: /lib/udev/rules.d/99-systemd.rules
      Reading rules file: /etc/udev/rules.d/touchscreen.rules
      rules contain 24576 bytes tokens (2048 * 12 bytes), 11107 bytes strings
      1602 strings (19400 bytes), 1040 de-duplicated (8856 bytes), 563 trie nodes used
      unable to open device '/sys/dev/mmcblk2'   //문제발생 /sys/dev/의 구조가 다르며, /sys로 변경해도 동일, /dev/mmcblk2 현재없어서 인것 같음 
      Unload module index
      Unloaded link configuration context.
      
      $ udevadm test -a add /dev/mmcblk2 
      $ udevadm test -a add  /sys/block/mmcblk2
      

      다시 trigger 기반으로 테스트진행시 문제없음 
      • 상위 만들어진 rule에 SW로 테스트 진행 (문제없음)
      $ udevadm trigger -c add /dev/mmcblk2   // RUN 동작확인 
      $ udevadm trigger -c remove /dev/mmcblk2 // RUN 동작확인
      

      12/08/2016

      DM814x SDK 설치 및 관련 설정

      1. EZSDK 설치

      수정중
      Memory Map 과 구조도 및 Firmware 이해 필요,
      Linux File system 부분 수정 부분

      1.1 GCC Tool Chain and SDK Download 

      • arm-2009q1-203-arm-none-linux-gnueabi.bin (Code Sourcery ARM GCC Tool Chain)
      • ezsdk_dm814x-evm_5_05_02_00_setuplinux
        http://www.ti.com/tool/linuxezsdk-davinci

      1.2 개발환경구성 

      • 환경변수 재설정
      아래의 환경변수는 CROSS_COMPILE과 INSTALL_MOD_PATH 등 Makefile과 Rule.make를
      보고 필요한부분을 넣었다.
      기본정의 Rule.make에 정의가 되어있으면 동작이 제대로 되어야겠지만,
      본인이 원하는 대로 동작이 안된다면, 두 파일을 비교하여 오동작되는 부분을 파악해서
      환경변수 고치던지 하는것이 편할 것이다.
      나는 source 를 이용하여 아래와 같이 그냥 외부에서 설정을 해놓았다.  

      $ vi setPATH.sh
      #!/bin/sh
      # source setPATH.sh
      # INSTALL_MOD_PATH : Kernel Module 
      # SYSLINK_INSTALL_DIR : syslink.ko 
      
      export PATH=$PATH:/home/jhlee/dm8148/CodeSourcery/Sourcery_G++_Lite/bin
      export EZSDK="${HOME}/dm8148/ti-ezsdk_dm814x-evm_xx_xx_xx_xx" 
      export CROSS_COMPILE=arm-none-linux-gnueabi-
      export ARCH=arm
      
      export INSTALL_MOD_PATH="${HOME}/dm8148/targetfs"     // Kernel module    
      
      $ source setPATH.sh 
      

      • 개발환경구성설정 (TI에서 제공)
      1. NFS Server 환경구성 
      2. TFTP 설정 
      $ cd ~/dm8148/ti-ezsdk_dm814x-evm_5_05_02_00 
      $./setup.sh              // 자동으로 설정 NFS/TFTP 
      



      1.3 EZSDK 설치시 구조 및 빌드방법



      • EZSDK 설치시 구조

      $ cd ~/dm8148/ti-ezsdk_dm814x-evm_5_05_02_00 
      $ tree -d -L 2 
      .
      ├── bin
      ├── board-support
      │   ├── docs
      │   ├── external-linux-kernel-modules
      │   ├── host-tools
      │   ├── linux-2.6.37-psp04.04.00.01
      │   ├── media-controller-utils_3_00_00_05
      │   ├── prebuilt-images
      │   └── u-boot-2010.06-psp04.04.00.01
      ├── component-sources
      │   ├── bios_6_33_05_46
      │   ├── c674x-aaclcdec_01_41_00_00_elf
      │   ├── codec_engine_3_22_01_06
      │   ├── edma3lld_02_11_05_02
      │   ├── framework_components_3_22_01_07
      │   ├── graphics-sdk_4.04.00.02
      │   ├── gst-openmax_GST_DM81XX_00_07_00_00
      │   ├── ipc_1_24_03_32
      │   ├── linuxutils_3_22_00_02
      │   ├── omx_05_02_00_48
      │   ├── osal_1_22_01_09
      │   ├── rpe_1_00_01_13
      │   ├── slog_04_00_00_02
      │   ├── syslink_2_20_02_20
      │   ├── uia_1_01_01_14
      │   ├── xdais_7_22_00_03
      │   └── xdctools_3_23_03_53
      ├── docs
      │   └── licenses
      ├── dsp-devkit
      │   ├── cgt6x_7_3_4
      │   ├── docs
      │   └── packages
      ├── etc
      ├── example-applications
      │   ├── am-benchmarks-1.1
      │   ├── am-sysinfo-1.0
      │   ├── linux-driver-examples-psp04.04.00.01
      │   ├── matrix-gui-e-1.3
      │   └── omtb_01_00_01_07
      ├── filesystem
      ├── linux-devkit
      │   ├── arm-none-linux-gnueabi
      │   ├── bin
      │   ├── etc
      │   ├── include
      │   ├── lib
      │   ├── mkspecs
      │   ├── share
      │   └── usr
      └── usr
          ├── lib
          └── share
      


      $ vi Rules.make  // 아래와 같이 수정 
      ....
      #EXEC_DIR=/home/jhlee/dm8148/targetfs/home/root/dm814x-evm   // 기본으로 이것으로 설정하며, 진행한다. 
      EXEC_DIR=/home/jhlee/dm8148/targetfs                         // 필요한 것이 있다면 그 때만 이것으로 설정 
                           // 위와 같이 진행하지 않으면 Filesystem이 필요없는것을 다 포함하게되어서 커진다. 
      
      //예를들어 아래와 같이 진행하면, EXEC_DIR/usr/lib/....   설치되므로 필요할때만 위와 같이 변경 
      $ make syslink
      $ make syslink_install  
      
      //전체 명령어 확인 및 Install 될 주소 확인                                                                
      $ make help
      
      Available build targets are  :
      
          components_linux               : Build the Linux components
          components_dsp                 : Build the DSP components
          components                     : Build the components for which a rebuild is necessary to enable all other build targets listed below. You must do this at least once upon installation prior to attempting the other targets.
          components_clean               : Remove files generated by the 'components' target
      
          apps                           : Build all Examples, Demos and Applications
          apps_clean                     : Remove all files generated by 'apps' target
          install                        : Install all Examples, Demos and Applications the targets in /home/jhlee/dm8148/targetfs/home/root/dm814x-evm
      
          linux-devkit                   : Populate the linux devkit
          dsp-devkit                     : Populate the dsp devkit
      
          cmem                           : Build the CMEM kernel module
          cmem_clean                     : Remove generated cmem files.
          cmem_install                   : Install cmemk module
      
          syslink                        : Configure and build SYS Link for HLOS and HLOS without sample examples
          syslink_clean                  : Remove generated SysLink files
          syslink_install                : Install HLOS and RTOS link files
      
          linux                          : Build Linux kernel uImage and module
          linux_clean                    : Remove generated Linux kernel files
          linux_install                  : Install kernel binary and  modules
      
          u-boot                         : Build the u-boot boot loader
          u-boot_clean                   : Remove generated u-boot files
          u-boot_install                 : Install the u-boot image
      
          psp-examples                   : Build the driver examples
          psp-examples_clean             : Remove generated driver example files
          psp-examples_install           : Install the psp examples
      
          osal                           : Build the OSAL
          osal_clean                     : Remove generated OSAL files
      
          matrix                         : Build matrix application launcher
          matrix_clean                   : Remove all matrix files
          matrix_install                 : Install matrix
      
          omx                            : Build OMX and OMX IL Clients
          omx_clean                      : Remove OMX generated files
          omx_install                    : Install OMX IL Clients
      
          omtb                           : Build OMTB IL Clients
          omtb_clean                     : Remove OMTB generated files
          omtb_install                   : Install OMTB IL Clients
      
          media-controller-utils         : Build media controller utils
          media-controller-utils_clean   : Remove media controller utils generated files
          media-controller-utils_install : Install media controller utils
      
          edma3lld                       : Build the EDMA3LLD Libraries
          edma3lld_clean                 : Remove generated EDMA3LLD files
      
          sgx-driver                     : Build SGX kernel module
          sgx-driver_clean               : Remove SGX generated files
          sgx-driver_install             : Install SGX kernel module
      
          gstomx                         : Build TI GST OpenMax Plugin
          gstomx_clean                   : Remove TI GST OpenMax generated files
          gstomx_install                 : Install TI GST OpenMax Plugin
      
          rpe                            : Build Remote Processor Execute
          rpe_clean                      : Remove Remote Processor Execute generated files
          rpe_install                    : Install Remote Processor Execute
      
          all                            : Rebuild everything
          clean                          : Remove all generated files
      
          install                        : Install all the targets in 
                                  /home/jhlee/dm8148/targetfs/home/root/dm814x-evm // 중요: EXEC_DIR 수정 후 변경됨 
      
      

      • TI에서 제공하는 User Manual
        http://processors.wiki.ti.com/index.php/Category:EZSDK

        http://developer.ridgerun.com/wiki/index.php/Getting_Started_Guide_for_DM8148_EVM

        http://processors.wiki.ti.com/index.php/DM814x_AM387x_PSP_User_Guide

        http://processors.wiki.ti.com/index.php/DM814x_AM387x_PSP_User_Guide#Linux_Kernel

      1.4 Video TEST

      • MPEG4 HDMI Decoding TEST 
      $ gst-launch filesrc location= test1.mp4 ! qtdemux name=mux mux.video_00 ! queue  ! h264parse output-format=1 ! omx_h264dec ! omx_scaler ! omx_ctrl display-mode=OMX_DC_MODE_1080P_30 ! omx_videosink enable-last-buffer=false

      • IP Camera TEST
      $ gst-launch -v rtspsrc location=rtsp://192.168.1.168:8556/PSIA/Streaming/channels/2?videoCodecType=H.264 caps="video/x-h264,mapping=/video " ! rtph264depay ! queue ! h264parse ! omx_h264dec ! omx_mdeiscaler name=d d.src_00 ! omx_ctrl display-mode=OMX_DC_MODE_1080P_30 ! omx_videosink enable-last-buffer=false 
      
      $ gst-launch rtspsrc location=rtsp://192.168.1.168:8556/PSIA/Streaming/channels/2?videoCodecType=H.264 ! rtph264depay ! queue ! \
      h264parse output-format=1 ! omx_h264dec ! omx_scaler ! omx_ctrl display-mode=OMX_DC_MODE_1080P_30 ! omx_videosink enable-last-buffer=false
      
      • IP Camera TEST (1080P Resize)
      $ gst-launch rtspsrc location=rtsp://192.168.1.168:8556/PSIA/Streaming/channels/2?videoCodecType=H.264  ! rtph264depay ! queue ! h264parse access-unit=true ! queue ! omx_h264dec ! omx_mdeiscaler name=d d.src_00 ! 'video/x-raw-yuv, width=(int)1920, height=(int)1080' ! queue ! omx_ctrl \
      display-mode=OMX_DC_MODE_1080P_30 ! gstperf print-fps=true print-arm-load=true ! omx_videosink sync=false enable-last-buffer=false
      

      • Gstreamer Examples
        https://developer.ridgerun.com/wiki/index.php/Gstreamer_pipelines_for_DM816x_and_DM814x
        https://developer.ridgerun.com/wiki/index.php/Gstreamer_pipelines_for_DM816x_and_DM814x#RTSP_-_Video_H264_1080.4030fps_2

      • DM8168 Firmware Debug
        https://developer.ridgerun.com/wiki/index.php?title=How_to_build_DM8168_M3_Firmware_and_debug_messages

      3. KERNEL Config & Build 

      위의 CROSS_COMPILE과 ARCH 환경변수가 설정이 되지 않을 경우 매번 설정하면서 실행.
      미리 설정된 File은 아래 존재하며 이곳에서 보자.

      $ cd ~/dm8148/
      $ source setPATH.sh 
      $ cd ti-ezsdk_dm814x-evm_5_05_02_00/board-support/linux-2.6.37-psp04.04.00.01
      $ ls ./arch/arm/configs/       // 지원되는 Configs 확인    
      
      
      $ make ti8148_evm_defconfig   // Kernel Config 설정 
      $ make menuconfig             // 상위 setPATH.sh를 설정을 안했다면, ARCH=arm 선언하자.
      $ make uImage                 // 상위 setPATH.sh를 설정을 안했다면  setARCH=arm 와 CROSS_COMPILE=arm-none-linux-gnueabi- 
      
      $ cp /arch/arm/boot/uImage  /tftpboot/uImage
      

      3.1 Kernel 분석 및 수정 

      • CTAGS와 CSCOPE 생성
      vi 에서 소스분석을 더 용이하게 하기 위해서 아래와 같이 설치 및 사용하자.
        http://ahyuo79.blogspot.com/search?q=sudo+apt-get+install+ctags

        http://processors.wiki.ti.com/index.php/TI81xx_PSP_Porting_Guide


      $ vi ./arch/arm/mach-omap2/board-ti8148evm.c
      ....
      MACHINE_START(TI8148EVM, "ti8148evm")
              /* Maintainer: Texas Instruments */
              .boot_params    = 0x80000100,
              .map_io         = ti8148_evm_map_io,    // 변경된 device memory map check 
              .reserve         = ti81xx_reserve,
              .init_irq       = ti8148_evm_init_irq,   // 점검 
              .init_machine   = ti8148_evm_init,       // 변경된 device check , EVM과 현재보드와 사용하는 Device가 다름 (HDMI 변경 및 기타 IO및 사용안함)
              .timer          = &omap_timer,       
      MACHINE_END
      


      $ make uImage
        CHK     include/linux/version.h
        CHK     include/generated/utsrelease.h
      make[1]: `include/generated/mach-types.h'는 이미 갱신되었습니다.
        CALL    scripts/checksyscalls.sh
        CHK     include/generated/compile.h
        LD      vmlinux.o
      
      drivers/built-in.o: In function `pcf8575_ths7375_enable':
      notify_shm_drv.c:(.text+0x15f14): multiple definition of `pcf8575_ths7375_enable'
      arch/arm/mach-omap2/built-in.o:gpmc-nand.c:(.text+0x9ce8): first defined here
      drivers/built-in.o: In function `vps_ti816x_set_tvp7002_filter':
      notify_shm_drv.c:(.text+0x15f8c): multiple definition of `vps_ti816x_set_tvp7002_filter'
      arch/arm/mach-omap2/built-in.o:gpmc-nand.c:(.text+0x9d60): first defined here
      drivers/built-in.o: In function `vps_ti816x_select_video_decoder':
      notify_shm_drv.c:(.text+0x15f78): multiple definition of `vps_ti816x_select_video_decoder'
      arch/arm/mach-omap2/built-in.o:gpmc-nand.c:(.text+0x9d4c): first defined here
      drivers/built-in.o: In function `ti816x_pcf8575_init':
      notify_shm_drv.c:(.text+0x15f50): multiple definition of `ti816x_pcf8575_init'
      arch/arm/mach-omap2/built-in.o:gpmc-nand.c:(.text+0x9d24): first defined here
      drivers/built-in.o: In function `pcf8575_ths7360_sd_enable':
      notify_shm_drv.c:(.text+0x15f28): multiple definition of `pcf8575_ths7360_sd_enable'
      arch/arm/mach-omap2/built-in.o:gpmc-nand.c:(.text+0x9cfc): first defined here
      drivers/built-in.o: In function `pcf8575_ths7360_hd_enable':
      notify_shm_drv.c:(.text+0x15f3c): multiple definition of `pcf8575_ths7360_hd_enable'
      arch/arm/mach-omap2/built-in.o:gpmc-nand.c:(.text+0x9d10): first defined here
      drivers/built-in.o: In function `ti816x_pcf8575_exit':
      notify_shm_drv.c:(.text+0x15f64): multiple definition of `ti816x_pcf8575_exit'
      arch/arm/mach-omap2/built-in.o:gpmc-nand.c:(.text+0x9d38): first defined here
      make: *** [vmlinux.o] 오류 1
      
      $ arm-none-linux-gnueabi-readelf -s arch/arm/mach-omap2/built-in.o | grep -r pcf8575_ths7375_enable
        2521: 00009ce8    20 FUNC    GLOBAL DEFAULT    1 pcf8575_ths7375_enable
      
      $ arm-none-linux-gnueabi-readelf -s drivers/built-in.o | grep -r pcf8575_ths7375_enable
       21182: 00015f14    20 FUNC    GLOBAL DEFAULT    1 pcf8575_ths7375_enable
      
      $ find . -name '*.o' | sed -e 's/o$/c/g' | xargs grep -rs pcf8575_ths7375_enable
      ./drivers/video/ti81xx/vpss/dctrl.c:  r = pcf8575_ths7375_enable(TI816X_THSFILTER_ENABLE_MODULE);
      
      $ grep -r pcf8575_ths7375_enable .
      이진파일 ./drivers/built-in.o 와(과) 일치
      이진파일 ./drivers/video/built-in.o 와(과) 일치
      이진파일 ./drivers/video/ti81xx/built-in.o 와(과) 일치
      ./drivers/video/ti81xx/vpss/dctrl.c:  r = pcf8575_ths7375_enable(TI816X_THSFILTER_ENABLE_MODULE);
      이진파일 ./drivers/video/ti81xx/vpss/dctrl.o 와(과) 일치
      이진파일 ./drivers/video/ti81xx/vpss/built-in.o 와(과) 일치
      이진파일 ./drivers/video/ti81xx/vpss/vpss.o 와(과) 일치
      ./tags:pcf8575_ths7375_enable arch/arm/mach-omap2/board-ti8168evm.c /^EXPORT_SYMBOL(pcf8575_ths7375_enable);$/;" v
      ./tags:pcf8575_ths7375_enable arch/arm/mach-omap2/board-ti8168evm.c /^int pcf8575_ths7375_enable(enum ti816x_ths_filter_ctrl ctrl)$/;" f
      ./tags:pcf8575_ths7375_enable arch/arm/mach-omap2/include/mach/board-ti816x.h /^int pcf8575_ths7375_enable(enum ti816x_ths_filter_ctrl ctrl)$/;" f
      ./arch/arm/mach-omap2/include/mach/board-ti816x.h:int pcf8575_ths7375_enable(enum ti816x_ths_filter_ctrl ctrl);
      ./arch/arm/mach-omap2/include/mach/board-ti816x.h:int pcf8575_ths7375_enable(enum ti816x_ths_filter_ctrl ctrl)
      이진파일 ./arch/arm/mach-omap2/built-in.o 와(과) 일치
      ./arch/arm/mach-omap2/board-ti8168evm.c:int pcf8575_ths7375_enable(enum ti816x_ths_filter_ctrl ctrl)
      ./arch/arm/mach-omap2/board-ti8168evm.c:EXPORT_SYMBOL(pcf8575_ths7375_enable);
      이진파일 ./arch/arm/mach-omap2/ti81xx_vpss.o 와(과) 일치
      
      
      $ make menuconfig   // 필요 module을 yes로 변경 및 필요 없은 것들을 제거. 
      
      $ make uImage
        CHK     include/linux/version.h
        CHK     include/generated/utsrelease.h
      make[1]: `include/generated/mach-types.h'는 이미 갱신되었습니다.
        CALL    scripts/checksyscalls.sh
        CHK     include/generated/compile.h
        LD      drivers/built-in.o
      drivers/media/built-in.o: In function `vps_ti816x_set_tvp7002_filter':        // 이곳에서 에러가 나서 현재 complier가 혼동하는 것 같음 
      ti81xxvin_lib.c:(.text+0x30eac): multiple definition of `vps_ti816x_set_tvp7002_filter'
      drivers/video/built-in.o:sii9022a_drv.c:(.text+0x72d0): first defined here
      drivers/media/built-in.o: In function `pcf8575_ths7375_enable':
      ti81xxvin_lib.c:(.text+0x30e34): multiple definition of `pcf8575_ths7375_enable'
      drivers/video/built-in.o:sii9022a_drv.c:(.text+0x7258): first defined here
      drivers/media/built-in.o: In function `ti816x_pcf8575_init':
      ti81xxvin_lib.c:(.text+0x30e70): multiple definition of `ti816x_pcf8575_init'
      drivers/video/built-in.o:sii9022a_drv.c:(.text+0x7294): first defined here
      drivers/media/built-in.o: In function `ti816x_pcf8575_exit':
      ti81xxvin_lib.c:(.text+0x30e84): multiple definition of `ti816x_pcf8575_exit'
      drivers/video/built-in.o:sii9022a_drv.c:(.text+0x72a8): first defined here
      drivers/media/built-in.o: In function `pcf8575_ths7360_sd_enable':
      ti81xxvin_lib.c:(.text+0x30e48): multiple definition of `pcf8575_ths7360_sd_enable'
      drivers/video/built-in.o:sii9022a_drv.c:(.text+0x726c): first defined here
      drivers/media/built-in.o: In function `vps_ti816x_select_video_decoder':
      ti81xxvin_lib.c:(.text+0x30e98): multiple definition of `vps_ti816x_select_video_decoder'
      drivers/video/built-in.o:sii9022a_drv.c:(.text+0x72bc): first defined here
      drivers/media/built-in.o: In function `pcf8575_ths7360_hd_enable':
      ti81xxvin_lib.c:(.text+0x30e5c): multiple definition of `pcf8575_ths7360_hd_enable'
      drivers/video/built-in.o:sii9022a_drv.c:(.text+0x7280): first defined here
      make[1]: *** [drivers/built-in.o] 오류 1
      make: *** [drivers] 오류 2
      
      $ vi drivers/media/.built-in.o.cmd  // compile되어 만들어지는 build-in.o를 다시 분석  (video 가 dm8168로 인식)
      
      $ find . -name plat   //             plat/cpu.h 찾아 설정이 제대로 있는지 확인 
      ./drivers/dsp/syslink/omap_notify/plat
      ./arch/arm/plat-pxa/include/plat
      ./arch/arm/plat-s5p/include/plat
      ./arch/arm/plat-versatile/include/plat
      ./arch/arm/plat-samsung/include/plat
      ./arch/arm/plat-omap/include/plat
      ./arch/arm/plat-nomadik/include/plat
      ./arch/arm/plat-spear/include/plat
      ./arch/arm/plat-s3c24xx/include/plat
      ./arch/arm/plat-orion/include/plat
      


      $ vi ./arch/arm/mach-omap2/ti81xx_vpss.c 
      
      $ vi ./arch/arm/mach-omap2/devices.c
      
      $ vi arch/arm/mach-omap2/board-flash.c
      

      • 문제점 분석 및 해결
      아래와 같이 빌드된 된 source만 찾아 grep으로 이를 검색

      $ find . -name '*.o' | sed -e 's/o$/c/g' | xargs grep -rs omap_mux_init

        http://ahyuo79.blogspot.com/search?q=xargs

      상위문제 Linux Kernel 사용이 되는 필요없는 Config를 제거하여 문제해결

      현재 나의 Board가 EVM이 아니기 때문에 Kernel config를 점검해가면서 수정해서
      필요 없는 부분을 제거하고 변경하고 TEST 하자.

      3.2 NAND 변경시 관련설정

      Device Drivers -> Memory Technology Devices

        http://processors.wiki.ti.com/index.php/Flash_configuration_in_the_Kernel#Enabling_NAND_Support
        http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/p/177166/641847#641847