close

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

  1. load address:
  2. entry point: 这两个地址是mkimage时指定的
  3. bootm address:bootm为uboot的一个命令,以此从address启动kernel
  4. kernel运行地址:在具体mach目录中的Makefile.boot中指定,为kernel启动后实际运行的物理地址
  5. 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)。



arrow
arrow
    全站熱搜
    創作者介紹
    創作者 ryan0988 的頭像
    ryan0988

    尋找最初的初衷

    ryan0988 發表在 痞客邦 留言(0) 人氣()