안드로이드용 리눅스 커널을 빌드하고 있습니다. 드라이버 모듈에 관해 질문있습니다.
안드로이드 포팅 프로젝트를 하고 있는데요
궁금한점 있어 질문드립니다.
현제 기존 2.6.25용 커널에 driver 디렉토리의 관련내용을 2.6.32로 올림과 동시에
현제 포팅용 보드에 맞도록 수정하고 있는데요
수정은 했지만 커널의 어느부분에서 모듈을 로드하는지 모르겠습니다.
예를 들자면 led 드라이버를 잡는다고 보면
컴파일시 driver/led/led.ko 모듈을 생성해 zImage로 같이 넣어줄 것으로 생각되는데요
zImage에 들어있는 led.ko를 커널 소스의 어느부분에서 로드하는 것인지를 잘 모르겠습니다.
이것저것 뒤지다가 알아낸 것은 (2.6.32 커널 기준)
start_kernel >> rest_init >> kernel_init >> do_basic_setup >> driver_init >> device_init 이런 루트가 있다는 것입니다.
device_init 함수에서 그것을 해줄 것으로 생각해 어렵게 찾아 들어가긴 했는데
제 생각과 많이 빛나간 소스가 들어있더군요..
소스의 내용은 대략 이렇습니다.(driver/base/core.c)
---------------------------------------------------------------------------------------------------------
1264 int __init devices_init(void)
1265 {
1266 devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);
1267 if (!devices_kset)
1268 return -ENOMEM;
1269 dev_kobj = kobject_create_and_add("dev", NULL);
1270 if (!dev_kobj)
1271 goto dev_kobj_err;
1272 sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj);
1273 if (!sysfs_dev_block_kobj)
1274 goto block_kobj_err;
1275 sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj);
1276 if (!sysfs_dev_char_kobj)
1277 goto char_kobj_err;
1278
1279 return 0;
1280
1281 char_kobj_err:
1282 kobject_put(sysfs_dev_block_kobj);
1283 block_kobj_err:
1284 kobject_put(dev_kobj);
1285 dev_kobj_err:
1286 kset_unregister(devices_kset);
1287 return -ENOMEM;
1288 }
---------------------------------------------------------------------------------------------------------
또한 위 함수를 호출하는 driver_init 함수의 내용도 올립니다.(driver/base/init.c)
---------------------------------------------------------------------------------------------------------
22 /* These are the core pieces */
23 devtmpfs_init();
24 devices_init();
25 buses_init();
26 classes_init();
27 firmware_init();
28 hypervisor_init();
29
30 /* These are also core pieces, but must come after the
31 * core core pieces.
32 */
33 platform_bus_init();
34 system_bus_init();
35 cpu_dev_init();
36 memory_dev_init();
37 }
---------------------------------------------------------------------------------------------------------
모듈을 어디서 로드하는지ㅠㅠ조언 부탁드립니다...꾸벅(__)
init/main.c 의 do_initcalls
init/main.c 의 do_initcalls 함수에서 모듈 초기화 함수를 호출하는게 아닐까요?
보통 모듈에서 초기화 함수로 등록하는 매크로인 module_init 가 해당 함수 포인터를 테이블에 등록하고 do_initcalls 에서 그 테이블에 등록된 함수를 순서대로 호출하는 것 같습니다.
답변 감사합니다. 근데 다른 궁금증이 생겼네요..
정말 감사합니다. 많은 도움이 되었습니다.
module_init 메크로를 타고 올라가니 .initcalls 라는 섹션에 테이블로 저장하는 것으로 생각되었습니다.
그렇다면 do_initcalls()가 수행되기 전에 먼저 테이블에 등록시킨다는 것인데
컴파일시에 컴파일러가 zImage로 페키징될 모듈파일을 돌아다니며 module_init을 수행하여 .initcalls라는
섹션에 저장하는 것인가요?? 그리하여 do_initcalls() 함수가 호출되면 해당 섹션에 있는 모듈들을 수행하는 것인가요?
아마도 링크
컴파일 단계에서 해당 섹션에 함수 포인터를 넣고, 링크단계에서 각각의 드라이버 오브젝트 안에 있는 섹션을 arch/*/kernel/vmlinux.lds를 참고해 해당 위치로 모아주지 않을까 합니다.
hyun 님 감사합니다.
복받으실꺼예요^_^
댓글 달기