http://www.zhimengzhe.com/linux/186849.html
little kernel分析_linux教程-织梦者(比较重要)
可参看http://blog.csdn.net/hankhanti/article/details/6133570
bootloader移植
配置:
配合 boot.img 来看会比较好理解.
由此可知 boot_img_hdr 中各成员值为:
magic[BOOT_MAGIC_SIZE] = "ANDROID!"
kernel_size = 0x00EC4CD1
kernel_addr = 0x80008000
ramdisk_size = 0x001C2434
ramdisk_addr = 0x81000000
second_size = 0x00000000
second_addr = 0x80F00000
tags_addr = 0x80000100
page_size = 0x00000800
cmdline[BOOT_ARGS_SIZE] = "console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0 androidboot.hardware=xxx msm_rtb.filter=0x237 ehci-hcd.park=3 androidboot.bootdevice=7824900.sdhci lpm_levels.sleep_disabled=1 earlyprintk"
TAGS_ADDR 如上 target/
然后将资料写入 tag, tag 的结构如下所示.
struct boot_img_hdr{ unsigned char magic[BOOT_MAGIC_SIZE]; unsigned kernel_size; /* size in bytes */ unsigned kernel_addr; /* physical load addr */ unsigned ramdisk_size; /* size in bytes */ unsigned ramdisk_addr; /* physical load addr */ unsigned second_size; /* size in bytes */ unsigned second_addr; /* physical load addr */ unsigned tags_addr; /* physical addr for kernel tags */ unsigned page_size; /* flash page size we assume */#if OSVERSION_IN_BOOTIMAGE uint32_t unused; /* future expansion: should be 0 */ uint32_t os_version; /* version << 11 | patch_level */#else unsigned dt_size; /* device_tree in bytes */ unsigned unused; /* future expansion: should be 0 */#endif unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */ unsigned char cmdline[BOOT_ARGS_SIZE]; unsigned id[8]; /* timestamp / checksum / sha1 / etc */};
然后进入到 kernel 的入口函数: entry(0, machtype, tags)
\android\bootable\bootloader\lk\target\xxx\rules.mk
PLATFORM := xxx
MEMBASE := 0x8F600000 # SDRAM
MEMSIZE := 0x00100000 # 1MB
BASE_ADDR := 0x80000000
SCRATCH_ADDR := 0x90100000
#TAGS_ADDR := BASE_ADDR+0x00000100
#KERNEL_ADDR := BASE_ADDR+0x00008000
#RAMDISK_ADDR := BASE_ADDR+0x01000000
另外一种配置解释:
//调用boot_linux()解压并启动内核
boot_linux((void*)hdr->kernel_addr, (void *)hdr->tags_addr,
(const char *)hdr->cmdline,board_machtype(),
(void *)hdr->ramdisk_addr,hdr->ramdisk_size);
这里的kernel_addr、tags_addr和ramdisk_addr地址由\bootable\bootloader\lk\project\xxx.mk定义如下:
DEFINES +=ABOOT_FORCE_KERNEL_ADDR=0x80008000
DEFINES +=ABOOT_FORCE_RAMDISK_ADDR=0x82000000
DEFINES += ABOOT_FORCE_TAGS_ADDR=0x81E00000
DEFINES +=ABOOT_FORCE_KERNEL64_ADDR=0x00080000
要和device\xxx\xxx\BoardConfig.mk下定义的保持一致
BOARD_KERNEL_BASE := 0x80000000
BOARD_KERNEL_PAGESIZE := 2048
BOARD_KERNEL_TAGS_OFFSET := 0x01E00000
BOARD_RAMDISK_OFFSET :=0x02000000
编译及运行flow:target_get_scratch_address ////获取scratch内存地址
SCRATCH_ADDR := 0x90100000
void *target_get_scratch_address(void)
{
return ((void *)SCRATCH_ADDR);
}
device\xxx\xxx\BoardConfig.mk
BOARD_KERNEL_CMDLINE := console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0 androidboot.hardware=xxx msm_rtb.filter=0x237 ehci-hcd.park=3 androidboot.bootdevice=7824900.sdhci lpm_levels.sleep_disabled=1 earlyprintk
android\bootable\bootloader\lk\make\build.mk
$(OUTBIN): $(OUTELF)
@echo generating image: $@
$(NOECHO)$(SIZE) $<
$(NOCOPY)$(OBJCOPY) -O binary $< $@
$(OUTBIN)
generating image: ../../../out/target/product/xxx/obj/EMMC_BOOTLOADER_OBJ/build-xxx/lk.bin
$(OUTELF): $(ALLOBJS) $(LINKER_SCRIPT)
@echo linking $@ ld: $(NOECHO):$(LD) :$(LDFLAGS) -T :$(LINKER_SCRIPT):$(ALLOBJS):$(LIBGCC)
$(NOECHO)$(LD) $(LDFLAGS) -T $(LINKER_SCRIPT) $(ALLOBJS) $(LIBGCC) -o $@
$(OUTELF)
linking ../../../out/target/product/xxx/obj/EMMC_BOOTLOADER_OBJ/build-xxx/lk
$(LD)
../../../prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-ld
$(LDFLAGS)
-gc-sections
$(LINKER_SCRIPT)
../../../out/target/product/xxx/obj/EMMC_BOOTLOADER_OBJ/build-xxx/system-onesegment.ld
android\out\target\product\xxx\obj\EMMC_BOOTLOADER_OBJ\build-xxx
system-onesegment.ld
../../../out/target/product/xxx/obj/EMMC_BOOTLOADER_OBJ/build-xxx/arch/arm/crt0.o
android\bootable\bootloader\lk\arch\arm\crt0.S
bl kmain
android\bootable\bootloader\lk\kernel\main.c
/* called from crt0.S */
void kmain(void)
// create a thread to complete system initialization
bootstrap2
target_init
smem_add_modem_partitions //初始化分区表
apps_init
app->init(app)/* call all the init routines */ //调用所有需在init进程运行的应用 app_descriptor: __apps_start到 __apps_end
aboot_init //判断按键启动方式: normal_boot boot_into_fastboot等
target_is_emmc_boot
target_is_emmc_boot
(androidboot.bootdevice=7824900.sdhci (boot_dev_type == BOOT_EMMC || boot_dev_type == BOOT_DEFAULT || boot_dev_type == BOOT_SD))
boot_linux_from_mmc
partition_get_index(flash_get_ptable) //ptable (ptable_find) //"boot" / "recovery"
//ptentry
/* struct ptentry {
char name[MAX_PTENTRY_NAME];
unsigned start;
unsigned length;
unsigned flags;
char type;
char perm;
};
struct ptable
{
struct ptentry parts[MAX_PTABLE_PARTS];
int count;
};
*/
/* TODO: create/pass atags to kernel */
boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,(const char *)hdr->cmdline, board_machtype(),(void *)hdr->ramdisk_addr, hdr->ramdisk_size);
/* Jump to a 64bit kernel */
scm_elexec_call((paddr_t)kernel, tags_phys);// 调用kernel内核
shell_init
console_init
console_register_commands(block);
//STATIC_COMMAND_START{ "help", "this list", &cmd_help },{ "test", "test the command processor", &cmd_test },STATIC_COMMAND_END(help);等...
/* APP_START(aboot) .init = aboot_init, APP_END APP_START(shell) .init = shell_init, .entry = shell_entry, APP_END */
start_app /* start any that want to start on boot */ //aboot //shell shell_entry console_start console_loop