核心解析U-boot傳入的machid
machid
在沒有裝置樹的時候,machine相關的初始化函式都在類似arch/arm/mach-s3c24xx的目錄下。
圖中圈住的machine,他們都屬於arm/mach-s3c24xx體系,在核心配置s3c24xx時,都會被編進核心。
U-boot傳入machid到核心用到的是param_struct/tag,核心根據U-boot傳入的machid選擇不同的初始化函式。
在include/generated/mach-types.h下可以看到很多單板對應的machid。
核心解析machid
箭頭上面那行mdesc = setup_machine_fdt(__atags_pointer);是解析裝置樹的,而setup_machine_tags函式就是解析U-boot傳入的tag(machid)。
for_each_machine_desc(p)是巨集。
/*
* Machine type table - also only accessible during boot
*/
extern struct machine_desc __arch_info_begin[], __arch_info_end[];
#define for_each_machine_desc(p) \
for (p = __arch_info_begin; p < __arch_info_end; p++)
__arch_info_begin到__arch_info_end儲存的就是machine_desc結構體,遍歷其中的machine_desc,當某一machine_desc的nr和machine_nr(U-boot傳入)相等時break。
__arch_info_begin、__arch_info_end、nr
把machine_desc結構體放入指定位置就是利用了編譯器的特性。
http://blog.csdn.net/qq_33160790/article/details/79256279
開啟arch/arm/mach-s3c24xx/mach-smdk2440.c檔案,末尾可以看到上面部分。
/*
* Set of macros to define architecture features. This is built into
* a table by the linker.
*/
#define MACHINE_START(_type,_name) \
static const struct machine_desc __mach_desc_##_type \
__used \
__attribute__((__section__(".arch.info.init"))) = { \
.nr = MACH_TYPE_##_type, \
.name = _name,
#define MACHINE_END \
};
這裡attribute((section(“.arch.info.init”)))就是利用了編譯器的特性,把machine_desc放到了.arch.info.init段。
.init.arch.info : {
__arch_info_begin = .;
*(.arch.info.init)
__arch_info_end = .;
}
vmlinux.lds連結檔案中可以看到.arch.info.init的起始和結束就是__arch_info_begin、__arch_info_end。
回到前面的MACHINE_START(_type,_name)巨集,_type是S3C2440。經過##連線
.nr = MACH_TYPE_##_type就變為:
.nr = MACH_TYPE_S3C2440,聯絡到前面提到的mach-types.h。
這裡nr就等於362(十六進位制的16a)。
貼上machine_desc結構體。