1. 程式人生 > >uboot驅動模型(DM)分析(一)

uboot驅動模型(DM)分析(一)

uboot版本:uboot-201711

要分析uclass之前,首先得搞清楚兩個巨集U_BOOT_DRIVER及U_BOOT_DEVICE的作用:

1.U_BOOT_DRIVER及U_BOOT_DEVICE巨集定義如下:

複製程式碼

 1 #define U_BOOT_DRIVER(__name)                        \
 2     ll_entry_declare(struct driver, __name, driver)
 3 
 4 #define U_BOOT_DEVICE(__name)                        \
 5     ll_entry_declare(struct driver_info, __name, driver_info)
 6 
 7 #define ll_entry_declare(_type, _name, _list)                \
 8     _type _u_boot_list_2_##_list##_2_##_name __aligned(4)        \
 9             __attribute__((unused,                \
10             section(".u_boot_list_2_"#_list"_2_"#_name)))

複製程式碼

下面具體分析如下:

例如:

複製程式碼

 1 U_BOOT_DRIVER(serial_s5p) = {
 2     .name    = "serial_s5p",
 3     .id    = UCLASS_SERIAL,
 4     .of_match = s5p_serial_ids,
 5     .ofdata_to_platdata = s5p_serial_ofdata_to_platdata,
 6     .platdata_auto_alloc_size = sizeof(struct s5p_serial_platdata),
 7     .probe = s5p_serial_probe,
 8     .ops    = &s5p_serial_ops,
 9     .flags = DM_FLAG_PRE_RELOC,
10 };

複製程式碼

根據上述巨集定義展開得到:

複製程式碼

 1 ll_entry_declare(struct driver, serial_s5p, driver)
 2         struct driver _u_boot_list_2_driver_2_serial_s5p __aligned(4) __attribute__((unused, section(".u_boot_list_2_driver_2_serial_s5p"))) = {
 3             .name    = "serial_s5p",
 4             .id    = UCLASS_SERIAL,
 5             .of_match = s5p_serial_ids,
 6             .ofdata_to_platdata = s5p_serial_ofdata_to_platdata,
 7             .platdata_auto_alloc_size = sizeof(struct s5p_serial_platdata),
 8             .probe = s5p_serial_probe,
 9             .ops    = &s5p_serial_ops,
10             .flags = DM_FLAG_PRE_RELOC,
11         };

複製程式碼

從上面我們可以看到宣告他們的時候對它們做了如下要求:

1.要求它們存放的時候4位元組對齊,這通常是為了更方便的訪問處理它們; 2.要求它們存放在一個各自獨有的段裡面

在連結指令碼arch/arm/cpu/u-boot.lds中有如下定義:

1 . = ALIGN(4);  
2             .u_boot_list : {  
3             KEEP(*(SORT(.u_boot_list*)));  
4      }  

所有以.u_boot_list開頭的段多將在這裡存放,KEEP關鍵字是為了保證所有的段多被加進來,不要被連結器自作聰明的把某些它認為沒有的段捨棄; 用巨集U_BOOT_DRIVER和U_BOOT_DEVICE宣告的變數將被分配到自己一個特有的段下,在連結的時候被組織到一起,具體可以在uboot編譯成功後生成的u-boot.map中檢視到u_boot_list段的相關資訊如下:

注意到u_boot_list_2_driver_1和u_boot_list_2_driver_3,這段地址範圍內即為驅動函式列表集合

搞清楚這兩個關鍵巨集後下篇將具體分析uclass,uclass_driver,udevice,driver之間的關係