Linux 内核引导

原创 2015年11月19日 18:20:11

引导linux内核系统的过程包括很多阶段,这里将以引导X86 PC为例进行讲解。引导X86 PC上的linux过程和引导嵌入式系统上的linux的过程基本类似。不过在X86 PC上用一个从BIOS转移到Bootloader的过程,而嵌入式系统往往复位后就直接运行Bootloader。下图为X86上从上电/复位到运行linux用户空间初始化进程的流程。在进入与linux相关代码之间,会经历这样的阶段:


  1. 当系统上电或复位时,CPU会将PC指针赋值为宜个特定的地址0XFFFF0并执行该地址处的指令。在PC机中,该地址位于BIOS中,它保存在主板上的ROM或Flash中。
  2. BIOS运行时按照CMOS的设置定义的启动设备顺序来搜索处于活动状态并且可以引导的设备。若从硬盘启动,BIOS会将硬盘MBR(主引导记录)中的内容加载到RAM。MBR是一个512字节大小的扇区,位于磁盘上的第一个扇区中(0道0柱面1扇区)。当MBR被加载到RAM中之后,BIOS就会将控制权交给MBR。
  3. 主引导加载程序查找并加载次引导加载程序。它在分区表中查找活动分区,找到一个活动分区时,扫描分区表中的其他分区,以确保它们都不是活动的。当这个过程验证完成之后,就将活动的引导记录从这个设备中读入RAM中并执行它。
  4. 次引导加载程序加载linux内核和可选的初始化RAM磁盘,将控制权交给linux内核源代码。
  5. 运行被加载的内核,并启动用户空间应用程序。

嵌入式系统中linux的引导过程与之相似,但一般更加简洁。无论具体以怎样的方式实现,只要具备如下的特征就可以称其为Bootloader。

  • 可以在系统上电或复位的时候以某种方式打开执行,这些方式包括BIOS引导执行,直接在NOR Flash中执行,NAND Flash中的代码被MCU自动拷入内部或外部RAM执行等
  • 能将U盘,磁盘,光盘,NOR/NAND Flash,ROM,SD卡等存储介质,甚或网口,串口中的操作系统加载到RAM并将控制权嫁给操作系统源代码执行。
完成上述功能的Bootloader的实现方式非常多样化,甚至本身也可以是一个简化版的操作系统。著名的linux Bootloader包括用于PC的LILO和GURB,应用与嵌入式系统的U-BootRedBoot等。

相比较于LILO,GRUB本身能理解EXT2,EXT3文件系统,因此可在文件系统中加载linux,而LILO只能识别“裸扇区”。
U-Boot的定位为“Universal Bootloader”,其功能比较强大,涵盖了包括PowerPC,ARM,MIPS和X86在内的绝大多数处理器架构,提供网卡,串口,Flash等外设驱动,提供必要的网络协议(BOOTP,DHCP,TFTP),能识别多种文件系统(cramfs,fat,jffs2和registerfs等),并附带了调试,脚本,引导,等工具,应用十分广泛。

RedBoot是Redhat公司随eCos发布的Bootloader开源项目,除了包含U-Boot类似的强大功能外,它还包括GDB stub(插桩),因此能通过串口或网口与GDB进行通讯,调试GCC任何程序(包括内核)。

我们有必要对上述流程的第5个阶段进行更详细的分析,它完成启动内核并运行用户空间的init进程。分析如下:
当内核映像被加载到RAM之后,Bootloader的控制权被释放,内核阶段就开始了。内核映像并不是完全可以直接执行的代码,而是一个压缩过的zImage(小内核)BzImage(大核)。

但是,并非zImage和bImage映像中的一切都被压缩了,否者Bootloader把控制权交给这个内核映像它就“傻”了。实际上,映像中包含未被压缩的部分,这部分包括解压压缩程序,解压程序和解压映像中被压缩的部分。zImage和bzImage都是用gzip压缩的,它们不仅是一个压缩文件,而且在这两个文件的开头部分内嵌有gzip解压缩代码。

如下图示,当bzImage(用于i386镜像)被调用时,它从/arch/i386/boot/head.S的start汇编汇编例程开始执行。这个程序设置一些基本的硬件设置,并调用/arch/i386/boot/compressed/head.S中的start_32程序设置一些基本的运行环境(如堆栈)后,清除BSS段,调用/arch/i386/boot/compressed/misc.c中的decompress_kernel( ) C函数解压内核。内核被解压到内存中之后,会再调用/arch/i386/kernel/head.S文件中的startup_32例程,这个新的start_32例程(称为清除程序或进程 0)会初始化页表,并启动内核分页机制,接着为任何可选的浮点单元(FPU)检测CPU类型,并将其存储起来供以后使用。这些都做完之后,/init/main.c中的start_kernel( )函数被调用,进入与体系结构无关的linux部分。

start_kernel( )会调用一系列初始化函数来设置中断,执行进一步的内存配置。之后,/arch/i386/process.c中kernel_thread( )被调用以启动第一个核心线程,该线程执行init( )函数,而原执行序列会调用CPU_idle( )等待调用。




作为核心线程的init( )函数完成外设及其驱动程序的加载和初始化,挂载根文件系统。init( )打开/dev/console设备,重定向stdin,stdout和stderr到控制台。之后,它搜索文件系统中的init( )程序(也可以由“init= ”命令行参数指定init程序),并使用execve( )系统调用执行init程序。搜索init程序的顺序为:/sbin/init,/bin/init,和/bin/sh。嵌入式系统中,多数情况下,可以给内核传入一个简单的shell脚本来启动必需 的嵌入式应用程序。

至此,漫长的linux内核引导和启动过程就结束了,而init( )对应的这个由start_kernel( )创建的第一个线程也进入用户模式。











版权声明:本文为博主原创文章,未经博主允许不得转载。

Linux 内核引导参数简介

http://www.jinbuguo.com/kernel/boot_parameters.html 概述 内核引导参数大体上可以分为两类:一类与设备无关、另一类与设备有...

Linux 内核引导参数简介

内核如何处理引导参数 绝大部分的内核引导参数的格式如下(每个参数的值列表中最多只能有十项): name[=value_1][,value_2]...[,value_10] 如果"name...

kernel移植之linux stage1:内核引导

/* * linux/arch/arm/kernel/head.S * * Copyright (C) 1994-2002 Russell King * Copyright (c) 20...

linux内核引导参数简介

概述 内核引导参数大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导参数多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导参数。比如,如果你想知道可以向 AH...
  • jsw_4
  • jsw_4
  • 2014年12月10日 13:40
  • 515

Linux 内核引导选项简介

概述 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 ...

Linux 内核引导选项简介

概述 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 ...

linux内核引导参数

linux内核引导参数 1.“boot=”   此参数指明包含引导扇区的设备名(如:/dev/had),若此项忽略,则从当前的根分区 中读取引导扇区。 2.“root=”   此参数告诉内核...
  • lqrensn
  • lqrensn
  • 2012年10月22日 10:13
  • 589

Linux内核引导参数简介

Linux内核引导参数简介 作者:金步国 版权声明 本文作者是一位自由软件爱好者,所以本文虽然不是软件,但是本着 GPL 的精神发布。任何人都可以自由使用、转载、复制和再分发,但必须保留...

Linux0.11的内核引导启动流程

Linux0.11的内核引导启动程序由boot/目录下的bootsect.s、setup.s和head.s完成,由于内核的启动涉及到硬件操作比较多,所以均是汇编文件。      讲述内核引导启动流程...

x86 linux系统内核引导流程梳理

引言:在上节提到双系统关键技术之一关于系统启动问题,即在执行内核代码前做了些什么?是怎样从汇编代码过渡到c代码执行?arm芯片和x86芯片启动有什么不同?ram, sram, rom,prom, fl...
  • armmfc
  • armmfc
  • 2016年04月24日 16:18
  • 519
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux 内核引导
举报原因:
原因补充:

(最多只允许输入30个字)