您的位置:首页 > 运维架构 > Linux

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

2014-08-07 19:27 411 查看
原文链接: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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: