uboot load address、entry point、 bootm address以及kernel運行地址的意義及聯系


按各地址起作用的順序,uboot引導linux內核啟動涉及到以下地址:

  1. load address:
  2. entry point: 這兩個地址是mkimage時指定的
  3. bootm address:bootm為uboot的一個命令,以此從address啟動kernel
  4. kernel運行地址:在具體mach目錄中的Makefile.boot中指定,為kernel啟動后實際運行的物理地址
mkimage -n 'linux-3.2.1' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage uImage

理論上因為mkimage要為zImage加上0x40字節的header,所以entry point = load address + 0x40

但由於uboot 的bootm對uImage處理不是簡單的go操作,其對前三個地址都有比較判斷,所以在實際的操作中,就分為兩種不同的情況:

1. bootm地址和load address一樣

  此種情況下,bootm不會對uImage header后的zImage進行memory move的動作,而會直接go到entry point開始執行。因此此時的entry point必須設置為load address + 0x40。如果kernel boot過程沒有到uncompressing the kernel,就可能是這里設置不對。

boom address == load address == entry point - 0x40

具體細節可參看uboot代碼common/cmd_bootm.c中bootm_load_os函數的實現:

        switch (comp) {
case IH_COMP_NONE:
if (load == blob_start || load == image_start) {
printf(" XIP %s ... ", type_name);
no_overlap = 1;
} else {
printf(" Loading %s ... ", type_name);
memmove_wd((void *)load, (void *)image_start,
image_len, CHUNKSZ);
}
*load_end = load + image_len;
puts("OK\n");
break;

2. bootm地址和load address不一樣(但需要避免出現memory move時出現覆蓋導致zImage被破壞的情況)

  此種情況下,bootm會把uImage header后的zImage move到load address(見上方代碼),然后go到entry point開始執行。 由此知道此時的load address必須等於entry point。

boom address != load address == entry point

因此,在mkimage以及設置uboot boot command的時候需要注意到以上兩種情況。

 

至於kernel的運行地址,其與前3個地址沒有關系,除了要避免內存覆蓋導致解壓后kernel不完整的情況。

zImage的頭部有地址無關的自解壓程序,因此剛開始執行的時候,zImage所在的內存地址(entry point)不需要同編譯kernel的地址相同。自解壓程序會把kernel解壓到編譯時指定的物理地址,然后開始地址相關代碼的執行。在開啟MMU之前,kernel都是直接使用物理地址(可參看System.map)。




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM