uevent init and operation Embedded Linux kernel

cat /sys/devices/something_device/uevent
위 커맨드를 입력하면 내용이 나온다.

1. 어떻게 uevent가 생성되었나?

kernel source drivers/base/core.c 의
int device_add(struct device *dev) 함수 안에서
어떠한 일련의 동작이후
(kobject_add 및 부모 설정 및 이름 설정 기타 등등)

error = device_create_file(dev, &uevent_attr);
함수를 실행함으로써 생성된다.

static struct device_attribute uevent_attr =
__ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent);

uevent 란 이름으로 생성하면서
read 시 show_uevent
write 시 store_uevent 가 수행 된다.

2. uevent가 어떻게 알리는가?

위 1번의 동작 이후 바로 밑에 보면
kobject_uevent(&dev->kobj, KOBJ_ADD); 함수를 수행한다.
kobject_uevent함수는 user 영역으로 알린다.

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);
.
.
.
등등이 있고 다음과 같이 config 가 되어 compile 되었다면 broadcast 한다.

#if defined(CONFIG_NET)
retval = netlink_broadcast_filtered(uevent_sock, skb,
   0, 1, GFP_KERNEL,
   kobj_bcast_filter,
   kobj);
#endif

이와 더불어 다음과 같이 uevent_helper 문자열에 무엇인가 있다면 user mode에서 호출 한다.

if (uevent_helper[0] && !kobj_usermode_filter(kobj)) {
.
.
retval = call_usermodehelper(argv[0], argv,
    env->envp, UMH_WAIT_EXEC);
.
.
}
이것은 booting 이후 device_add 가 호출 되면 동작할 것이다.
부팅 시점에서 많은 device들이 device_add 함수가 호출될 터이지만 받는 놈이 없을 듯 하다.

3. cat /sys/devices/something_device/uevent 하면 정보가 나오는데,
   커널내에서 text문자열이 어디에 저장 되어 있는가?

문자열을 저장하고 있지 않다.
read 요청이 오면 그때그때 생성하여 보내주는 방식이다.
cat /sys/devices/something_device/uevent 입력하였다면
show_uevent 함수가 호출 된다. show_uevent 함수 안을 살펴 보면
kset의 uevent_ops 의 operation 함수들이 수행 되는데..

linux kernel 의 모든 device 는
void device_initialize(struct device *dev) 를 수행한다.
그때 dev->kobj.kset = devices_kset; 와 같이 kset 을 지정해 주는데

devices_kset 은 다음과 같이 device_uevent_ops를 가진다.
devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);

device_uevent_ops 의 내용을 다음과 같다.

static const struct kset_uevent_ops device_uevent_ops = {
.filter = dev_uevent_filter,
.name = dev_uevent_name,
.uevent = dev_uevent,
};

dev_uevent 함수 내용을 보면 struct device 가 가진 정보를 적절히 파싱하여

보여주는 방식이다.


Todo :
struct device 구조체 적절히 잘 알아야 할 것이고,
kobject 및 kset의 관계등 여러가지를 잘 알아야 한다.
언젠가는 net_link 에 대해서 분석할 날이 올까? ;;;

4. mdev 나 udev 와 관련된 동작.

처음 부팅 filesystem 이 mount 되면 init 수행 하면서 init script 에서
mdev -s 를 하게 되면

/sys/block
/sys/class

들 돌면서 /dev/* 에 dev file 들을 생성한다.

/proc/sys/kernel/hotplug 에 mdev가 등록 되어 있다면

kernel에서 device_add 함수 수행하면 kobject_uevent를 통하여 uevent_helper=mdev 가 수행 된다.


--------------------------------------- 추가 (2015-6-29)
 echo "add" > uevent 하게 되면 
 cat uevent 의 가진 내용을 
 ACTION=add 를 가지고 uevent 를 날린다.
 (action 종류는 아래와 같이..)
 
static const char *kobject_actions[] = {
[KOBJ_ADD] = "add",
[KOBJ_REMOVE] = "remove",
[KOBJ_CHANGE] = "change",
[KOBJ_MOVE] = "move",
[KOBJ_ONLINE] = "online",
[KOBJ_OFFLINE] = "offline",
};
 
 
 DEVPATH 는 
 devpath = kobject_get_path(kobj, GFP_KERNEL); 한 내용을 가져온다.
 kobj 가 어디 path 일까... ?
 
 이걸 처리해주는 부분은 store_uevent 함수이다.



덧글

댓글 입력 영역