[platform]新旧内核的device设备注册对比
轉自:http://blog.chinaunix.net/uid-7332782-id-3268801.html
?
1. Version2.6內核啟動過程
????start_kernel(?) //板子上電啟動后進入start_kernel( ),相當于程序的main入口
????????-->setup_arch(&command_line) ?//command_line由內核傳入
????????????-->mdesc?=?setup_machine(machine_arch_type);
????????????????-->list?=?lookup_machine_type(nr);?//匯編實現查找機器碼所定義的平臺,找到后返回mdesc結構? ? ? ? ? ? ? ?
????????????-->init_machine?=?mdesc->init_machine; ?//struct machine_desc?*mdesc;machine_desc結構很重要,
????????-->rest_init()
????????????-->kernel_thread(kernel_init,?NULL,?CLONE_FS?|?CLONE_SIGHAND);?//定義進程kernel_init,pid=1,在kthreadd進程創建好后調度運行? ? ? ? ??
????????????????-->kernel_init()
????????????????????-->do_basic_setup()
????????????????????????-->driver_init()
????????????????????????????-->devices_init()
????????????????????????????-->buses_init()
????????????????????????????-->classes_init()
????????????????????????????-->platform_bus_init()
????????????????????????-->do_initcalls() ?//此函數很重要,執行了initcall表中所有的函數,包含了init_machine(saar_init())函數? ? ? ? ? ? ? ? ? ? ? ?
????????????????????????????-->saar_init()
????????????????????-->init_post() ???//調度用戶空間程序,比如bash,在用戶空間死循環執行程序?? ? ? ? ? ? ? ? ??
????????????-->pid?=?kernel_thread(kthreadd,?NULL,?CLONE_FS?|?CLONE_FILES); ?//定義進程kthreadd
2. Version3.x內核啟動過程和2.6版本在init_machine加載設備資源的差異對比
- 在2.6內核中, 在setup_arch()中,舉個例子imx5,
-->init_machine=mdesc->init_machine; //init/main.c->start_kernel()->setup_arch(), 將init_machine指向mdesc結構體重的init_machine指針,而mdesc中該指針指向具體芯片對應的設備資源函數mxc_board_init.
? -->.init_machine=mxc_board_init; //arch/arm/mach-mx5/mx50_arm2.c->MACHINE_START()?,宏即時初始化machine_desc結構體 ? ? ? ?
? ? -->mxc_register_device(&mxc_dma_device); //arch/arm/mach-mx5/mx50_arm2.c->mxc_board_init(), 在mxc_board_init完成這些設備注冊
? ? -->mxc_register_device(&mxc_wdt_device); //mxc_wdt_device這些設備資源也都申明在mach-mx50下面
? ? -->mxc_register_device(&mxci2c_devices[0]);
? ? -->..........
當然在setup_arch()中對init_machine進行初始化,這個時候并沒有調用init_machine函數,init_machine是在代碼中被定義為arch_initcall屬性(arch/arm/kernel/setup.c), 然后在do_initcalls()中進行遍歷調用,具體見上述的啟動過程。
由上述可以看出,在系統啟動時,device設備就已經register到總線上了,而3.x以后已經不在mach-**中申明設備資源了,那啟動流程如何呢,見下一節。
- ?在3.x內核中,在setup_arch()是這么處理的, 首先解析dtb
-->setup_arch() //init/main.c->start_kernel()->setup_arch()
? -->mdesc=setup_machine_fdt();
? -->unflatten_device_tree() //和2.6內核不同,在setup_arch()中并沒有init_machine = mdesc->init_machine.那init_machine如何執行呢?
? ? ?-->__unflatten_device_tree()
? ? ? ? -->unflatten_dt_node() //到此基本完成dts中node到鏈表的操作
節點中的設備注冊
-->DT_MACHINE_START //machine_desc結構體賦值,在2.6內核中宏偉MACHINE_START,文件位置:arch/arm/mach-***
? -->.init_machine=imx6sx_init_machine
? ? ?-->of_platform_populate();? //imx6sx_init_machine()調用,在setup_arch()中解析設備數,構造設備節點鏈表,然后在這里進行設備的注冊,而init_machine為arch_initcall屬性,當在setup_arch()后面代碼調用到do_initcalls()函數時調用init_machine()函數完成設備注冊。
? ? ? ? -->of_platform_bus_create();? //由for_each_child_of_node()調用,遍歷device tree中每個節點
? ? ? ? ? ?-->of_platform_device_create_pdata()
? ? ? ? ? ? ? -->of_device_alloc() //為每個device申請空間
? ? ? ? ? ? ? -->platform_device_put()
? ? ? ? ? ?-->of_platform_bus_create()
到此完成設備的注冊。
在3.x的setup.c中關于init_machine的調用是這么定義的
1 static int __init customize_machine(void) 2 { 3 /* 4 * customizes platform devices, or adds new ones 5 * On DT based machines, we fall back to populating the 6 * machine from the device tree, if no callback is provided, 7 * otherwise we would always need an init_machine callback. 8 */ 9 if (machine_desc->init_machine) 10 machine_desc->init_machine(); 11 #ifdef CONFIG_OF 12 else 13 of_platform_populate(NULL, of_default_bus_match_table, 14 NULL, NULL); 15 #endif 16 return 0; 17 }?
關于init_machine到底會不會被執行,在Documentation/Devicetree/usage-model.txt中有這么一段話
The most interesting hook in the DT context is .init_machine() which is primarily responsible for populating the Linux device model with data about the platform. Historically this has been implemented on embedded platforms by defining a set of static clock structures, platform_devices, and other data in the board support .c file, and registering it en-masse in .init_machine(). When DT is used, then instead of hard coding static devices for each platform, the list of devices can be obtained by parsing the DT, and allocating device structures dynamically.The simplest case is when .init_machine() is only responsible for registering a block of platform_devices. A platform_device is a concept used by Linux for memory or I/O mapped devices which cannot be detected by hardware, and for 'composite' or 'virtual' devices (more on those later). While there is no 'platform device' terminology for the DT, platform devices roughly correspond to device nodes at the root of the tree and children of simple memory mapped bus nodes.?
轉載于:https://www.cnblogs.com/aaronLinux/p/5559721.html
總結
以上是生活随笔為你收集整理的[platform]新旧内核的device设备注册对比的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 原创:嘉庆死后,皇后为何不选亲儿子继位,
- 下一篇: 2016年度最受欢迎的100个 Java