uboot在完成所有工作之後使用thekernel()啟動核心
thekernel (0, machid, bd->bi_boot_params);
傳遞三個引數0、machid、tag的首位址,分別存入r0,r1,r2,之後啟動核心。
核心中獲取tag首位址則是在arch/arm/kernel/setup.c檔案的setup_arch()函式中(核心版本:linux-2.6.22.6)
void __init setup_arch(char **cmdline_p)
setup_machine()函式:獲得開發板對應的machine_desc結構體
static struct machine_desc * __init setup_machine(unsigned int nr)
printk("machine: %s\n", list->name);
return list;
}
lookup_machine_type()定義在arch/arm/kernel/head-common.s中
具體作用就是通過u-boot傳入的機器id在.arch.info.init段中找到匹配的machine_desc結構體。
.long __proc_info_begin
.long __proc_info_end
3: .long .
.long __arch_info_begin
.long __arch_info_end
__lookup_machine_type:
adr r3, 3b @得到3標號的實體地址
ldmia r3, @r4=r3 r5=__arch_info_begin r6=__arch_info_end
sub r3, r3, r4 @ r3 = r3 - r4 得到虛擬位址與實體地址的差
add r5, r5, r3 @ r5 = __arch_info_begin的實體地址
add r6, r6, r3 @ r6 = __arch_info_end的實體地址
1: ldr r3, [r5, #machinfo_type] @ @ r5 =machine_desc r3=machine_desc 中的nr即機器id
teq r3, r1 @ r1為bootloader傳入的機器id 比較兩者
beq 2f @ 如果相等跳轉到2forward標號
add r5, r5, #sizeof_machine_desc @ 得到下個machine_desc結構體
cmp r5, r6 @比較是否到段的結尾
blo 1b @如果不是跳轉到1back標號
mov r5, #0 @ unknown machine
2: mov pc, lr
那machine_desc結構體是由什麼定義的呢?
核心對應每一種能支援開發板都會使用巨集machine_start和machine_end來定義乙個
定義如下:
#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
對於smdk2440開發板,定義如下:(位於arch/arm/mach-s3c2440/mach-smdk2440.c)
machine_start(s3c2440, "smdk2440")
/* maintainer: ben dooks */
.phys_io = s3c2410_pa_uart,
.io_pg_offst = (((u32)s3c24xx_va_uart) >> 18) & 0xfffc,
.boot_params = s3c2410_sdram_pa + 0x100, //s3c2410_sdram_pa = 0x30000000
//所以得到bootloader傳入的tag首位址為0x30000100
.init_irq = s3c24xx_init_irq,
.map_io = smdk2440_map_io,
.init_machine = smdk2440_machine_init,
.timer = &s3c24xx_timer,
machine_end
分析到這裡其實不難看出,核心並沒有使用thekernel()傳入的tag首位址,而是通過machine_desc的boot_params項獲得了tag首位址。
如果u-boot設定的tag首位址與核心中boot_params引數不一致時,可能會出現問題。
u boot向Linux核心傳遞引數tag原理分析
u boot最主要的功能是引導os,目前對linux支援的相對比較好,引導 的意義不僅僅是拷貝核心,執行核心,還要給核心kernel傳遞板子的相關引數,打個比方,u boot相當於是一名專業功底深厚的 接待員 他會先初始化好一些外圍裝置,比如說串列埠,sdram nand flash mmc等,初始...
Linux核心引數傳遞Tag
在2.4 具體哪個版本記不清了 以後的linux核心中引入了一種新的向核心傳遞引數的方法tag標記。核心引數通過乙個靜態的tag鍊錶在啟動的時候傳遞到核心。每個tag的結構為 tag header tag 其中tag header為tag頭,表明tag 的型別和大小,之所以要標識tag 的型別是因為...
uboot傳遞核心引數全解析
一 啟動引數的傳遞過程 啟動引數是包裝在資料結構裡的,在linux kernel啟動的時候,bootloader把這個資料結構拷貝到某個位址,在改動pc跳向核心介面的同時,通過通用暫存器r2來傳遞這個位址的值,下面這句話就是uboot跳向linux kernel的 bootm命令 thekernel...