在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);
}
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);
}