|
最近在学习UBOOT,自已也已成功移植了UBOOT1.1.6版本,但跟天嵌提供的UBOOT1.1.6版本相比,不能引导未加头信息的内核(zImage),于是看了天嵌的UBOOT,详细如下:
1、定义了“boot_zImage”这个命令,命令的函数在lib_arm/boot_zImage.c中实现;
2、执行“boot_zImage”命令时调用do_boot_zImage(), do_boot_zImage()调用boot_zImage(0x200000,0x300000)(传入的参数意义是:0x200000是内核映像文件在NAND的偏移地址,0x300000是内核映像文件的SIZE);
3、在boot_zImage()函数中实现了从NAND拷贝到SDRAM、设置机器ID、设置启动参数等并最终调用call_linux(0, mach_type, to),跳转到内核入口处执行了。
代码如下:
- int boot_zImage(ulong from, size_t size)
- {
- int ret;
- ulong boot_mem_base; /* base address of bootable memory */
- ulong to;
- ulong mach_type;
- boot_mem_base = 0x30000000;
- /* copy kerne image */
- to = boot_mem_base + LINUX_KERNEL_OFFSET;//内核入口地址 = 0x30008000
- printf("Copy linux kernel from 0x%08lx to 0x%08lx, size = 0x%08lx ... ",
- from, to, size);
- ret = copy_kernel_img(to, (char *)from, size);//从NAND的0x200000处读0x300000大小的内核到0x30008000处
- if (ret) {
- printf("failed\n");
- return -1;
- } else {
- printf("Copy Kernel to SDRAM done,");
- }
- if (*(ulong *)(to + 9*4) != LINUX_ZIMAGE_MAGIC) {
- printf("Warning: this binary is not compressed linux kernel image\n");
- printf("zImage magic = 0x%08lx\n", *(ulong *)(to + 9*4));
- } else {
- // printf("zImage magic = 0x%08lx\n", *(ulong *)(to + 9*4));
- ;
- }
- /* Setup linux parameters and linux command line */
- setup_linux_param(boot_mem_base + LINUX_PARAM_OFFSET);//0x30000100,设置内存、命令行参数等
- /* Get machine type */
- mach_type = MACH_TYPE_S3C2440;//机器ID
- // printf("MACH_TYPE = %d\n", mach_type);
- /* Go Go Go */
- printf("NOW, Booting Linux......\n");
- call_linux(0, mach_type, to);//启动内核
- return 0;
- }
-
-
- //启动内核 r0 = 0,r1 = ID,r2 = 0x30008000
- void call_linux(long a0, long a1, long a2)
- {
- local_irq_disable();
- cache_clean_invalidate();
- tlb_invalidate();
- __asm__(
- "mov r0, %0\n"
- "mov r1, %1\n"
- "mov r2, %2\n"
- "mov ip, #0\n"
- "mcr p15, 0, ip, c13, c0, 0\n" /* zero PID */
- "mcr p15, 0, ip, c7, c7, 0\n" /* invalidate I,D caches */
- "mcr p15, 0, ip, c7, c10, 4\n" /* drain write buffer */
- "mcr p15, 0, ip, c8, c7, 0\n" /* invalidate I,D TLBs */
- "mrc p15, 0, ip, c1, c0, 0\n" /* get control register */
- "bic ip, ip, #0x0001\n" /* disable MMU */
- "mcr p15, 0, ip, c1, c0, 0\n" /* write control register */
- "mov pc, r2\n"//pc = 0x30008000,跳到内核处执行
- "nop\n"
- "nop\n"
- : /* no outpus */
- : "r" (a0), "r" (a1), "r" (a2)
- : "r0","r1","r2","ip"
- );
复制代码 疑问:以上“r2”为什么是内核的入口地址而不是参数的地址,因为还未学习内核,所以不懂。难道这就是zImage和uImage的区别?{:2_30:} |
|