新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > uclinux启动过程详细分析

uclinux启动过程详细分析

作者:时间:2018-08-31来源:网络收藏

本文引用地址:http://www.eepw.com.cn/article/201808/388126.htm

存储了可用物理内存起始地址的变量memory_start的初始化是通过一个ld脚本中定义的变量_end进行的。ld脚本是用来控制GNU ld连接器在连接内核各个目标文件部分的时候的配置动作,比如这样一个脚本:

SECTION

{

。=0x10000;

.text:{*(.text)}

。=0x8000000;

.data:{*(.data)}

.bss :{*(.bss)}

}

用来配置ld连接目标文件的时候将所有的目标文件中的存储程序正文的.text段(section)连接到一起,并且映射到输出文件的地址0x10000处,将所有目标文件中已初始化的数据.data段连接到一起并放置到输出可执行文件的0x8000000地址处,而所有目标文件中还未初始化的数据段.bss连接起来后影射到输出文件中紧跟在.data段之后的位置。

这个ld配置脚本文件对每个平台都是不同的。如为MICETEK上所使用的版本使用的ld配置文件为arch/armnomm/vmLinux.lds。可以通过修改某个平台上的ld脚本配置文件中的_end变量来达到配置其可用物理内存起始地址的目的。

setup_arch()在完成对memory_start变量的初始化之后,通过某些特定手段检测不同类型的内存分布情况。比如为检测某段地址范围是否为RAM的方法是通过将某个地址的数据读出来,将它加1后写回内存地址中,然后再读出来和原始数据比较看看其值是否成功增加了1,这样反复操作两次,最后将数据恢复。如果是可读可写的RAM,那么这个测试的结果就是每次比较都是成功的,否则就不能将这个地址当作RAM。

在setup_arch()中还可能根据所用平台进行对flash memory和ROM的测试。在这些平台相关的工作完成之后,setup_arch()将对系统运行的第一个进程init_task的mm_struct结构中描述地址空间分布的变量start_code,end_code,end_data和brk进行初始化,start_code为0,其他三个数值分别为来自于ld脚本配置文件中定义的相关变量_etext、_edata和_end。

此后setup_arch()将根据Linux中为系统中的第一块rom/flash memory card所分配的固定的主/从设备号(可以从Document/devices.txt中得到)来创建根文件系统的设备号,并存储在后来将要用到的全局变量ROOT_DEV中。

setup_arch()最后完成对系统启动参数的保存。

在调用setup_arch()返回之后,start_kernel()中得到了系统可用物理内存的起始和结束地址,以及命令启动时的命令行参数。

(2) paging_init()

在Linux中,paging_init()的一项主要功能是建立页目录和页表,而且将Linux移植到不同平台的过程中非常重要的一个步骤就是修改这个函数来适应新的硬件平台的虚拟内存体系。但是由于在中不再使用虚拟内存机制,也就不再需要维护页目录和页表数据结构了,所以paging_init()在这里只是为系统启动的时候保留一部分特殊用途的内存区间。它返回后,从可以使用的内存空间开始,依次是如下的数据结构:

empty_bad_page_table 占用1页(4KB)

empty_bad_page 占用1页(4KB)

empty_zero_page 占用1页,并初始化为全0

mem_map

bitmap

paging_init()函数在返回前通过调用free_area_init(start_mem,end_mem)进行建立buddy system的映射位图关系,以及建立空闲物理页面链表的操作。

(3)free_area_init()

这个函数用于建立管理物理页帧的数据结构mem_map,有多少物理页帧就有多少mem_map_t类型的结构体与之相对应。每个页面的mem_map_t结构中的flags被标明为PG_DMA和PG_reserved,并且页帧号被赋给相应的数值。同时建立了管理空闲页面的bitmap映射表,并且所有的位都被清零。

(3) mem_init()

mem_init()函数遍历整个可用物理内存地址空间,将每个页面相对应的struct page结构中flags的PG_reserved 标志位清除,标志用户个数的count计数器置1,并同时统计可用物理页面数量,然后打印系统的各个内存参数,如可用RAM和ROM的大小、内核代码段和数据段大小等。

======================================================

摘 要:本文采用三星公司的S3C44B0微处理器,对操作系统内核的引导过程进行了剖析。

关键字:S3C44B0X;uClinux;嵌入式系统;内核引导

1 前言

伴随着微电子的发展,用于嵌入式设备的处理器速度越来越快,功能也越来越强大。三星公司生产的S3C44B0微处理器,采用的是ARM7TDMI内核。该内核因为有着功耗小、成本低等特点,因此非常适合作为移动手持终端的处理器核心。Linux操作系统因为它的开放性,使得它不断的被应用到各个领域。在嵌入式领域同样也出现了各种各样的Linux变体,最常用的是uClinux。也正是因为uClinux操作系统支持不带MMU单元的ARM处理器,因此该系统可以对S3C44B0微处理器有很好的支持。

在嵌入式系统开发中,第一个部分便是系统的引导。而系统的引导过程是通过BootLoader来完成的。BootLoader程序是与硬件紧密相关的一段代码,而且编写的时候比较复杂,它主要的功能是初始化微处理器以及周边的硬件资源,并且引导操作系统的启动。下面我将以S3C44B0微处理器来作为例子,对uClinux操作系统内核的引导过程进行一个剖析。

2 BootLoader程序概念

简单的说Boot Lodaer就是在操作系统内核运行之前运行的一段小程序,通过这段小程序,可以初始化硬件设备、建立系统的内存空间映射图,从而将系统的软硬件环境设置成一个适合的状态,以便为最终调用操作系统内核准备好正确的环境。最终,BootLoader把操作系统内核映象加载到RAM中,并将系统控制权传递给它。

2.1 典型的BootLoader程序框架

操作系统角度来说,Boot Loader的总目标就是正确的调用内核来执行。

由于Boot Loader的实现依赖于CPU的体系结构,因此大多数Boot Loader都分为Stage1和Stage2两大部分。依赖于CPU体系结构的代码,例如设备初始化代码等,通常都放在Stage1中,而且通常都用汇编语言来实现,以达到短小精悍的目的。而Stage2通常用C语言来实现,这样可以实现更加复杂的功能,而且代码会具有更好的可读性和可移植性。

Boot Loader的Stage1通常包括如下步骤:

1) 硬件设备初始化



关键词: uClinux cpu 控制器

评论


相关推荐

技术专区

关闭