Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1257572
  • 博文数量: 254
  • 博客积分: 1586
  • 博客等级: 上尉
  • 技术积分: 2295
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-15 16:38
个人简介

linux学习中

文章分类

全部博文(254)

文章存档

2016年(6)

2015年(2)

2014年(74)

2013年(93)

2012年(12)

2011年(2)

2010年(51)

2009年(14)

分类:

2010-10-22 10:21:27

我们用的u-boot已经改的面目全非,不过核心还是完全相同的,换了个面目而已。开源的好处,想改就改来玩玩。不过流程还是人家的。

u-boot通过bootm命令来启动内核,这个命令的处理函数是do_bootm,这个函数处理的是uboot-mkimage制作的映像,如果正好这个映像是内核,那么它就会调用do_bootm_linux函数,并在该函数中给内核传递参数并调用内核入口函数来启动内核。下面就来写写do_bootm和do_bootm_linux的简单流程,以及u-boot是如何把内核启动参数传递给内核的。这里只说流程,背景知识需要提前准备。当然也需要对着代码才能明白这些话是不是P话,是不是错话。OK,开始。

   do_bootm开始,首先通过s = getenv ("verify")取环境变量verify的值,这个后面用来判断是否要对映像数据部分进行CRC校验,然后addr = load_addr获得映像在内存中的位置。memmove (&header, (char *)addr, sizeof(image_header_t));把映像的头部信息拷贝到一个提前准备好的全局变量中去,后续的操作基本都是通过检查这个全局变量的各个成员来进行的。

首先通过MAGIC NUMBER来检查文件类型是否是UIMAGE的映像,然后crc32 (0, (uchar *)data, len)作头部的CRC校验,再根据前面取得的verify值做映像数据部分的CRC校验,然后检查ARCH,再检查映像类型(是单独的应用程序,还是内核,还是多个文件)。在这里前面的检查,如果不符合,不支持,或者出错,那么都会导致do_bootm出错返回,这是这些操作都不会破坏在内存中存放的UIMAGE映像(当然也可是存放在FLASH中的)。

以上的检查都做完后检查是否是压缩过得映像,这里的压缩指的是U-Boot用的压缩,与内核的zImage不是一回事儿,如果压缩了,那么就调用相应的解压缩程序进行解压缩,解压缩的位置就是在头部信息中指定的装载地址,而这个地址是在用uboot-mkimage制作映像的时候指定的。解压缩结束后再次判断映像类型,如果是内核或者多文件类型,那么就进入do_bootm_linux函数了。

在do_bootm_linux中,首先kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong)) ntohl(hdr->ih_ep)获得内核入口地址,然后检查initrd映像并取得initrd的位置和大小。然后开始设置启动内核所需要的参数,也就是要传递给内核的参数,现在的u-boot通过一个结构struct tag来管理这一大堆参数。通过调用一大堆setup_xx_tag函数设置完参数以后,关闭中断,关掉并冲刷CACHE,然后调用内核入口函数,通过bdinfo的bi_boot_params成员把存放这些 参数的tag数据结构的地址传递给内核。这样就开始执行内核代码了。大致过程就是这样吧。

阅读(1506) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~