lk boot bootimg

在aboot.c 中
APP_START(aboot)
.init = aboot_init,
APP_END
会为aboot_init new 一个thread(前面已经讲过了)
void aboot_init(const struct app_descriptor *app)
{
if (keys_get_state(KEY_BACK) != 0)
goto fastboot;


boot_linux_from_flash();
dprintf(CRITICAL, "ERROR: Could not do normal boot. Reverting "
"to fastboot mode.\n");


fastboot:
}


这个函数首先判断用户是否按下back key,如果按下就进入fastboot ,否则就从flash上copy bootimg到dram中。其中fastboot 中有个continue的命令也是调用boot_linux_from_flash 来从flash上将booting copy到dram。
fastboot_register("continue", cmd_continue);
void cmd_continue(const char *arg, void *data, unsigned sz)
{
boot_linux_from_flash();
}
看到了吧
我们继续看boot_linux_from_flash 


int boot_linux_from_flash(void)
{
struct boot_img_hdr *hdr = (void*) buf;
unsigned n;
struct ptentry *ptn;
struct ptable *ptable;
unsigned offset = 0;
const char *cmdline;


首先得到flashlayout
ptable = flash_get_ptable();
if (ptable == NULL) {
dprintf(CRITICAL, "ERROR: Partition table not found\n");
return -1;
}
从flashlayout 中找到boot partition
ptn = ptable_find(ptable, "boot");
if (ptn == NULL) {
dprintf(CRITICAL, "ERROR: No boot partition found\n");
return -1;
}
先读取bootimg 2k的head
if (flash_read(ptn, offset, buf, 2048)) {
dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
return -1;
}
offset += 2048;
看bootimg是否有Android这个字样
if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
dprintf(CRITICAL, "ERROR: Invaled boot image heador\n");
return -1;
}
从bootimg中的得到kernel size
n = ROUND_TO_PAGE(hdr->kernel_size);
if (flash_read(ptn, offset, (void *)hdr->kernel_addr, n)) {
dprintf(CRITICAL, "ERROR: Cannot read kernel image\n");
return -1;
}
offset += n;


从bootimg中的得到ramdisk size,并copy到dram中


n = ROUND_TO_PAGE(hdr->ramdisk_size);
if (flash_read(ptn, offset, (void *)hdr->ramdisk_addr, n)) {
dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n");
return -1;
}
offset += n;


dprintf(INFO, "\nkernel  @ %x (%d bytes)\n", hdr->kernel_addr,
hdr->kernel_size);
dprintf(INFO, "ramdisk @ %x (%d bytes)\n", hdr->ramdisk_addr,
hdr->ramdisk_size);


检查bootimg中是否包含cmdline


if(hdr->cmdline[0]) {
cmdline = (char*) hdr->cmdline;
} else {
cmdline = DEFAULT_CMDLINE;
}
dprintf(INFO, "cmdline = '%s'\n", cmdline);


/* TODO: create/pass atags to kernel */


dprintf(INFO, "\nBooting Linux\n");
boot_linux((void *)hdr->kernel_addr, (void *)TAGS_ADDR,
  (const char *)cmdline, LINUX_MACHTYPE,
  (void *)hdr->ramdisk_addr, hdr->ramdisk_size);


return 0;
}




调用boot_linux 继续boot kernel
void boot_linux(void *kernel, unsigned *tags, 
const char *cmdline, unsigned machtype,
void *ramdisk, unsigned ramdisk_size)
{
unsigned *ptr = tags;
给entry赋值,就等于hdr->kernel_addr。
void (*entry)(unsigned,unsigned,unsigned*) = kernel;
struct ptable *ptable;


/* CORE */
*ptr++ = 2;
*ptr++ = 0x54410001;


传递ramdisk 给的size 和 address 给kernel,其中0x54410001是个magic number.


if (ramdisk_size) {
*ptr++ = 4;
*ptr++ = 0x54420005;
*ptr++ = (unsigned)ramdisk;
*ptr++ = ramdisk_size;
}


传递flashlayout给kernel,其中0x4d534d70是个magic number.


if ((ptable = flash_get_ptable()) && (ptable->count != 0)) {
int i;
*ptr++ = 2 + (ptable->count * (sizeof(struct atag_ptbl_entry) /
      sizeof(unsigned)));
*ptr++ = 0x4d534d70;
for (i = 0; i < ptable->count; ++i)
ptentry_to_tag(&ptr, ptable_get(ptable, i));
}


传递(cmdline 给kernel,类似uboot的bootargs 。其中0x54410009是个magic number.


if (cmdline && cmdline[0]) {
unsigned n;
/* include terminating 0 and round up to a word multiple */
n = (strlen(cmdline) + 4) & (~3);
*ptr++ = (n / 4) + 2;
*ptr++ = 0x54410009;
memcpy(ptr, cmdline, n);
ptr += (n / 4);
}


/* END */
*ptr++ = 0;
*ptr++ = 0;


dprintf(INFO, "booting linux @ %p, ramdisk @ %p (%d)\n",
kernel, ramdisk, ramdisk_size);
if (cmdline)
dprintf(INFO, "cmdline: %s\n", cmdline);


enter_critical_section();
platform_uninit_timer();
关掉cache和mmu
arch_disable_cache(UCACHE);
arch_disable_mmu();
调到entry开始执行kernel,传递三个参数,第一个固定为0,第二个machtype被定义成LINUX_MACHTYPE,一般在对应平台的init.c中定义,第三个参数tags,就是传给给kernel的参数.
entry(0, machtype, tags);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值