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

Uboot-1.1.2 do_bootm_linux函数源码分析

2008-09-09 09:03 537 查看
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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: