MMC 혹은 SDCard 관련 Spec을 다시 확인하고자 한다면 아래의 사이트에서 확인
- MMC(SDCARD) 관련 Spec
- Part 1. Physical Layer Simplified Specification
- Part A2. SD Host Controller Simplified Specification
- Part E1. SDIO Simplified Specification
- Part E7. Wireless LAN Simplified Addendum
- 이외
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 IRQSD 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
- MMC/SD/SDIO (CONFIG_MMC)
- MMC block (CONFIG_MMC_BLOCK)
- Secure Digital Host Controller Interface support (CONFIG_MMC_SDHCI)
- SDHCI support on the platform-specific bus (CONFIG_MMC_SDHCI_PLTFM)
- SDHCI platform support for the NXP eSDHC i.MX controller (CONFIG_MMC_SDHCI_ESDHC_IMX)
- Kernel source의 drivers/mmc/host/
- sdhci.c standard stack code
- sdhci-pltfm.c sdhci platform layer
- sdhci-esdhc.c uSDHC driver
- sdhci-esdhc-imx.c uSDHC driver header file
세부사항은 아래사이트 참고
- i.MX 관련설정 (출처)
https://www.digi.com/resources/documentation/digidocs/90001546/reference/bsp/cc6/r_mmc-sd-sdio.htm
- MMC/SD Device Driver 세부분석
http://egloos.zum.com/furmuwon/v/11167927
- SDCard 관련부분 Uboot 및 Kernel 설정 (Sitara/i.MX)
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은 udev와 NETLINK_KOBJECT_UEVENT로 통신을 하고 있으며, 이곳에 add_uevent_var의 환경설정값을 추가하여 통신을 진행한다.
Kernel은 이외에도 다른 NETLINK도 사용하니 이것만 사용한다고 착각하지말자.
- udev의 NETLINK_KOBJECT_UEVENT
user에서 socket으로 protocol을 NETLINK_KOBJECT_UEVENT로 설정
https://elixir.bootlin.com/linux/v4.20.4/source/lib/kobject_uevent.c#L751
- SD/MMC 관련소스
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
- retval = add_uevent_var(env, "ACTION=%s", action_string);
- retval = add_uevent_var(env, "DEVPATH=%s", devpath);
- retval = add_uevent_var(env, "SUBSYSTEM=%s", subsystem);
- retval = add_uevent_var(env, "%s", envp_ext[i]); // 상위 NULL 이지만 sys에서 설정가능
- retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)++uevent_seqnum);
- 기타 값
- kobject_synth_uevent 관련함수
- kobject_uevent_env 의 확장값을 넣어 전송
- LEASE=1 : 상위 3번의 envp_ext[i] 값 설정
- HOTPLUG=1 : 상위 3번의 envp_ext[i] 값 설정
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 구성)
- device_attribute
- bus_attribute
- class_attribute
- 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
rule에서도 SYMLINK을 이용하여 추가도 가능함
2.2 udevadm info 의 attribute 분석
udev의 기본적인 uevent의 정보와 sys filesystem의 attribute를 분석할때, -a를 옵션을 주어 분석이 가능하다.
ATTR{x}는 해당 /sys file 주소의 값들을 출력을 해주며, 추후 rule에서도 이를 적용가능하다.
parent기반으로 분석되기때문에 호출되는 순서를 파악가능하며 최종단을 주목
2.3 udevadm monitor를 이용확인
udevadm의 monitor를 이용하여 sdcard의 card detection 부분을 체크
실시간 모니터로 아래와 같이 uevent를 볼수 있으며 옵션을 추가하여 각 event를 더 확인하자.
3. udev Rule 만드는 법
udevadm info 와 monitor를 통해 기본 udev의 정보와 sys file system의 정보를 이용하여 udev rule을 간단히 만들어보자.
RUN에 ENV{ } 정보를 출력하고 싶다면, %E{xx}로 사용가능
SYMLINK를 이용하여 /dev에 새로 device node의 symblolic link 생성가능
좀 더 사용을 하면 GOTO와 LABEL을 사용하며, 예제를 보면 쉽게 이해가 가능
3.1 MMC Device 와 udev Rule 생성
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 연결적용
일반적으로 많이 사용되는 USB Serial ttyACM에 udev에 연결하여 systemd 와 함께 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 중 (BindToDevice대신) BindTo 와 After 부분설정을 위해 각 값 검색
udev Rule에 같이 동작할 systemd 의 service 설정
**system unit 과 system.service manual 참조
아래의 사이트에서 쉽게 찾아 연결했으며, 세부내용은 아래사이트 참조
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#
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로만 테스트 진행가능하며, 본인이 좀 더 세부 테스트를 한다면, 다양한 옵션설정도 가능.
아래의 두가지 방식으로 테스트 가능
실제테스트 진행
다시 trigger 기반으로 테스트진행시 문제없음
- 좌측 Node 의미 및 분석방법
- N: is for device Name in /dev
- S: is for Symlinks to that device name in /dev (추후 udev/rules/에서 SYMLINK)
- P: is for device Path in /sys
- E: is for device properties in udev
- P: Node는 /sys의 device path이므로 이곳의 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
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 설정된 환경값
- 이외 다른 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에서도 이를 적용가능하다.
- uevent 정보(KERNEL/SUBSYSTEM/DRIVER)
- 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의 기본저장장소
- /lib/udev/rules.d/
- /etc/udev/rules.d/ : User는 이곳에 설정하여 추가해서 넣자
- /dev/udev/rules.d/
- Rule에서 기본적으로 match되는 정보
- KERNEL : device의 kernel 이름 , device의 이름과 match
- SUBSYSTEM : device의 subsystem과 match
- DRIVER: device와 관련된 driver name과 match
- NAME: /dev 에서 사용되어지는 device node와 match
- SYMLINK: NAME의 대신에 사용되어지는 symbloic link list
- ATTRS{x}: 상위 sys filesystem의 정보와 match
- ENV{DEVLINKS}: 상위 E: Node 정보와 match
- matching 할때 pattern
- *: 어느 문자들이든 match
- ?: 어느 한 문자만 match
- []: 범위를 정해서 match
- Event 와 실행
- ACTION: 해당 정보의 device가 add or remove , change가 있을 경우
- RUN : 조건이 충족되면 실행을 하는 command
RUN에 ENV{ } 정보를 출력하고 싶다면, %E{xx}로 사용가능
SYMLINK를 이용하여 /dev에 새로 device node의 symblolic link 생성가능
좀 더 사용을 하면 GOTO와 LABEL을 사용하며, 예제를 보면 쉽게 이해가 가능
3.1 MMC Device 와 udev Rule 생성
- MMC의 동작 rule 생성 및 적용
$ 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 연결
$ 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
- udev에서 ttyACM0 상위정보의 uevent가 오면 이를 udev에 TAG를 사용하여 systemd에 노출하고 service로 연결
- 상위 service에서 After와 BindsTo는 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 동작확인