uclinux启动过程详细分析

时间:2018-08-31来源:网络

一 般, 在Linux中初始化脚本在/etc/inittab 文件(或称初始化表)中可以找到关于不同运行级别的描述。inittab是以行为单位的描述性(非执行性)文本,每一个指令行都是固定格式。 inittab中有respawn项,但如果一个命令运行时失败了,为了避免重运行的频率太高,init将追踪一个命令重运行了多少次,并且如果重运行的 频率太高,它将被延时五分钟后再运行。

② kernel进程

A》 请注意init是1号进程,其他进程id分别是kflushd/ bdflush, kupdate, kpiod and kswapd。这里有一个要指出的:你会注意到虚拟占用(SIZE)和实际占用(RSS)列都是0,进程怎么会不使用内存呢?

这些进程就是内核守护进程。大部分内核并不显示在进程列表里。守护进程在init之后启动,所以他们和其他进程一样有进程ID,但是他们的代码和数据都存放在内核占有的内存中。在列表中使用中括号来区别与其他进程。

B》 输入和输出是通过内存中的缓冲来完成的,这让事情变得更快,程序的写入会存放在内存缓冲中,然后再一起写入硬盘。守护进程kflushd和kupdate 管理这些工作。kupdate间断的工作(每5秒)来检查是否有写过的缓冲,如过有,就让kflushd把它们写入磁盘。

C》 进程有时候无事可做,当它运行时也不一定需要把其所有的代码和数据都放在内存中。这就意味着我们可以通过把运行中程序不用的内容切换到交换分区来更好的是利用内存。把这些进程数据移入/移出内存通过进程IO管理守护进程kpiod和交换守护进程kswapd,大约每隔1秒,kswapd醒来并检查内存情 况。如果在硬盘的东西要读入内存,或者内存可用空间不足,kpiod就会被调用来做移入/移出操作。

D》 bdflush - BUF_DIRTY, 将dirty缓存写回到磁盘的核心守护进程。对于有许多脏的缓冲区(包含必须同时写到磁盘的数据的缓冲区)的系统提供了动态的响应。它在系统启动的时候作为一个核心线程启动,它叫自己为 “kflushd”,而这是你用ps显示系统中的进程的时候你会看得的名字。即定期(5秒)将脏(dirty)缓冲区的内容写入磁盘,以腾出内存;

E》 ksoftirqd_CPUx 是一个死循环, 负责处理软中断的。它是用来对软中断队列进行缓冲处理的进程。当发生软中断时,系统并不急于处理,只是将相应的cpu的中断状态结构中的active 的相应的位,置位,并将相应的处理函数挂到相应的队列,然后等待调度时机来临,再来处理。

ksoftirqd_CPUx是由 cpu_raise_softirq() 即cpu触发中断,唤醒的内核线程,这涉及到软中断,ksoftirqd的代码参见[kernel/softirq.c]。

F》 keventd,它的任务就是执行 scheduler 调度器队列中的任务,keventd 为它运行的任务提供了可预期的进程上下文。

G》 khubd, 是用来检测USB hub设备的,当usb有动态插拔时,将交由此内核进程来处理。在检测到有hub事件时会有相应的动作(usb_hub_events())

H》 mtdblockd是用来对flash块设备进行写操作的守护进程。NAND类型的Flash需要MTD(Memory Technology Devices 内存技术驱动程序)驱动的支持才能被linux所使用。NAND的特点是不能在芯片内执行(XIP,eXecute In Place),需要把代码读到系统RAM中再执行,传输效率不是最高,最大擦写次数量为一百万次,但写入和擦除的速度很快,擦除单元小,是高数据存储密度 的最佳选择。NAND需要I/O接口,因此使用时需要驱动程序。

I》 loop0 是负责处理loop块设备的(回环设备)。loopback device指的就是拿文件来模拟块设备, 在我们这里,loop设备主要用来处理需要mount到板上的文件系统,类似mount /tmp/rootfs /mnt -o loop。。我们的实例有:mount -o loop -t cramfs /xxx.bin /xxx 也就是将xxx.bin这个文件mount到板上来模拟cramfs压缩ram文件系统。loop0进程负责对loop设备进行操作。

loopback设备和其他的块设备的使用方法相同。特别的是,可以在该设备上建立一个文件系统,然后利用mount命令把该系统映射到某个目录下以便访问。这种整个建立在一个普通磁盘文件上的文件系统,就是虚拟文件系统 (virtual file system)。

总结

上面的内容是本人为了在实际开发中更加清楚地了解uclinux的启动过程而做的一个总结性的文章。在对uclinux的启动过程做了一个详细注释后,大家 会对涉及到嵌入系统的各个概念有了一个更加明确的认识,并能对嵌入系统的软硬件环境的有关设置更加清楚。当你自己动手结合linux源代码来分析时,将会有一个清楚的全局观。

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

1. 运行bootloader初始化程序

SRAM 、SDRAM等存储设备属于挥发性的存储器,掉电以后其中的内容就会全部丢失,所以必须把操作系统的内核镜像存放在Flash等不挥发性存储介质上。但是操作系统在运行时,需要动态的创建一些如数据段、堆栈、页表(针对使用虚拟地址的操作系统)等内容,所以需要在RAM中运行操作系统。

因此,就需要一个引导程序把操作系统的内核镜像从Flash存储器拷贝到RAM中,然后再从RAM中执行操作系统的内核。Bootloader就是可以完成这样一种功能的程序。

从本质上来讲,bootloader不属于操作系统内核。它采用汇编语言编写,因此针对不同的CPU体系结构,这一部分代码不具有可移植性。在移植操作系统时,这部分代码必须加以改写

具体来讲,bootloader在系统启动时主要完成以下几项工作:

(1) 将操作系统内核从Flash拷贝到SDRAM中,如果是压缩格式的内核,还要将之解压缩。

(2) 改写系统的memory map,原先flash起始地址映射为0地址,这时需要将RAM的起始地址映射为0。

(3) 设置堆栈指针并将bss段清零。

将来执行C语言程序和调用子函数时要用到

(4) 改变pc值,使得CPU开始执行真正的操作系统内核。

2. 运行操作系统内核

bootloader程序执行完上述的各项工作后,通过一条跳转指令,转而执行init目录下C语言源文件main.c中的函数start_kernel()。

因为在此之前bootloader已经创建好一个初始化环境,C函数可以开始执行了。

整个操作系统内核的初始化工作从这里才算是真正开始。这个函数的长度比较短,代码如下:

1 2 3 4 5 6 7 8 9 10 11

关键词: uClinux cpu 控制器

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW

或用微信扫描左侧二维码

相关文章

查看电脑版