Uboot-1.1.2 for PXA270源码分析-do_bootm_linux函数源码分析[转]

来源:互联网 发布:程序员的qq头像 编辑:程序博客网 时间:2024/04/27 21:27

原文链接:http://210.77.145.167/blog2/enchen/9742.html

do_bootm函数位于common/cmd_bootm.c文件中。

do_bootm函 数调用do_bootm_linux函数启动linux内核,当定义了CONFIG_PPC时将使用common/cmd_bootm.c文件中的 do_bootm_linux函数;当系统中没有定义该宏时,系统将使用lib_arm/armlinux.c文件中定义的do_bootm_linux 函数。注意:这两个函数有很大的区别!
 lib_arm/armlinux.c中do_bootm_linux函数源代码:

void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
       ulong addr, ulong *len_ptr, int verify)
{
 DECLARE_GLOBAL_DATA_PTR;

 ulong len = 0, checksum;
 ulong initrd_start, initrd_end;
 ulong data;
 void (*theKernel)(int zero, int arch, uint params);
 image_header_t *hdr = &header;
 bd_t *bd = gd->bd;

#ifdef CONFIG_CMDLINE_TAG
 char *commandline = getenv ("bootargs");
#endif

 theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep); // 设置kernal加载地址
 
 // 用户自定义了initrd之后需要加载进来
 // 整个过程需要进行头部以及整个数据内部校验
 // 类似于内核的加载校验,这里省略了。
 // 下面仅仅列出了无randisk时的处理:
 initrd_start = 0;
 initrd_end = 0;

 SHOW_BOOT_PROGRESS (15);

// 在psbec270.h文件中定义了如下宏
// #define CONFIG_CMDLINE_TAG
// #define CONFIG_SETUP_MEMORY_TAGS
// #define CONFIG_INITRD_TAG
// 根据上面不同的宏加载不同的TAG
// 注意的是必须定义CONFIG_CMDLINE_TAG和CONFIG_SETUP_MEMORY_TAGS
// 除非内核已经根据系统初始化了这些值, 否则必须定义, 不定义将导致无法启动.
#if defined (CONFIG_SETUP_MEMORY_TAGS) ||
    defined (CONFIG_CMDLINE_TAG) ||
    defined (CONFIG_INITRD_TAG) ||
    defined (CONFIG_SERIAL_TAG) ||
    defined (CONFIG_REVISION_TAG) ||
    defined (CONFIG_LCD) ||
    defined (CONFIG_VFD)
 setup_start_tag (bd);

#ifdef CONFIG_SETUP_MEMORY_TAGS
 // 设置memory tags
 setup_memory_tags (bd);
#endif
#ifdef CONFIG_CMDLINE_TAG
 // 设置启动命令行tags
 setup_commandline_tag (bd, commandline);
#endif
#ifdef CONFIG_INITRD_TAG
 if (initrd_start && initrd_end) // 存在ramdisk时设置initrdtag
  setup_initrd_tag (bd, initrd_start, initrd_end);
#endif
 setup_end_tag (bd);
#endif
 // 接下来开始调用执行内核启动
 printf ("nStarting kernel ...nn");
 // 启动之前先做一些清理工作,见下面说明
 cleanup_before_linux ();
 // 调用内核需要传递的参数如下:
 // R0:必须为0
 // R1:机器类型ID,本机为ARM(bd->bi_arch_number)
 // R2:启动参数列表在内存中的位置(bd->bi_boot_params)
 theKernel (0, bd->bi_arch_number, bd->bi_boot_params);
}

// 清理工作,调用内核之前必须满足如下条件才可以:
// CPU模式:
//  必须禁止中断(IRQs和FIQs);
//   CPU 必须 SVC 模式;
// Cache和MMU的设置:
//  MMU 必须关闭;
//  指令 Cache 可以打开也可以关闭;
//  数据 Cache 必须关闭;
int cleanup_before_linux (void)
{
 unsigned long i;

 disable_interrupts ();   // 禁止中断
 // 关闭指令和数据cache
 asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
 i &= ~(C1_DC | C1_IC);
 asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
 i = 0;
 asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i));
 return (0);
}

原文链接:http://210.77.145.167/blog2/enchen/9742.html


0 0
原创粉丝点击