已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
转 Linux 引导加载学习笔记本文以是我的学习记录,其中一些文字和图片来自参考资料所列文档,感谢作者对其知识和分享!最近在自学Linux kernel方面的东西,这两天了粗浅的研究了下kernel boot过程,在此记录。这里所指Linux引导加载未涉及虚拟化环境,即系统未运行在hypervisor之上。Linux通过执行不同阶段的引导加载程序(boot loader)程序来引导操作系统,在完成内核等引导之后,最终会由调度器接管CPU,其通过启用中断来周期性的抢占控制权,处理多个用户进程/客户进程(kvm虚拟化)。Top level的引导过程如下图。整个Linux系统引导共分5步执行操作:BIOS/BootMonitor引导程序;BIOS包括POST和Runtime服务。被称为第一阶段的MBR(Master boot record)引导程序;位于BIOS配置的启动磁盘0柱面1扇区的主引导记录,用于启动第二阶段的linux boot loader。被称为第二阶段的linux boot loader;主要有LILO(Linux loader)和GNU GRUB(Grand unified boot loader)两种boot loader程序,现主流为GRUB。包括了通过initrd来创建RAM盘,执行init脚本,通过LKM(linux kernel module)加载本地磁盘等驱动程序来挂载磁盘中的root文件系统。RAM盘中是个完整的小型linux环境,在没有磁盘的嵌入式环境中,initrd可以是最终的根文件系统,也可以通过NFS来挂载最终的文件系统。linux kernel(及initrd函数)引导;负责加载并解压zImage/bzImage kernel及initrd映像,并开始执行kernel初使化和引导程序/过程。init进程。用于启动linux配置的各项用户空间服务(demon)进程。加电后首先被执行的是BIOS(Base input/output system)程序。嵌入式环境使用boot monitor,它负责在一个位于rom/flash中预定地址开始执行引导程序,而在PC环境中这个启动地址是0xFFFF0,相对来讲BIOS提供了更多的配置功能。它主要由两部分组成:POST(Power On Self Test)程序;其负责接通电源时对硬件检测,包括创建中断向量、设置寄存器、对一些外部设备进行初始化和检测等。BIOS Runtime服务;负责为操作系统提供一些基础服务,主要与IO外设有关。当BIOS POST执行完后,其将会从内存中清理,而Runtime服务会常驻内存,为操作系统提供一些底层的支持。最后BIOS将控制权交给称为第一阶段引导程序的MBR(Master boot record)程序。接下来执行的MBR是一个512 byte固定大小的映像。包括446 byte长的被称为初始程序加裁程序(Initial program loader,IPL)的可执行代码和64 byte分区表(16 byte*4个),最后以0xaa55特殊字节结束。如下图所示。MBR引导程序会将扫描分区表,获得唯一活动分区后,将其中的引导程序读入RAM并开始执行。MBR启动的引导程序被称为第二阶段引导程序,它是引导的主体,是引导加载的真正部分。Linux中该阶段有两个流行的程序,LILO(较老)和GRUB。如果安装了lilo程序,可以通过root用户执行如下命令来通过lilo生成默认配置的MBR,并写入到启动磁盘0柱面1扇区位置上。Shell代码#/sbin/lilo-v-v#/sbin/lilo-v-v一般需要修改lilo的配置文件,使生成的MBR有效。位于/etc/lilo.conf。lilo配置示例。Config代码boot=/dev/hdamap=/boot/mapinstall=/boot/boot.bprompttimeout=100compactdefault=Linuximage=/boot/vmlinuz-2.4.18-14label=Linuxroot=/dev/hdb3read-onlypassword=linuxother=/dev/hdalabel=WindowsXPboot=/dev/hdamap=/boot/mapinstall=/boot/boot.bprompttimeout=100compactdefault=Linuximage=/boot/vmlinuz-2.4.18-14 label=Linux root=/dev/hdb3 read-only password=linuxother=/dev/hda label=WindowsXP boot键指定了lilo在哪里安装MBR。可以通过替换boot=/dev/fd0配置来指定lilo创建有引导记录的软盘。LILO天生存在一些缺点和不足,因此linux在新版本中引入了GRUB程序。它为了从磁盘来加裁配置和kernel映像,不像LILO只能从裸扇区中执行引导程序,而具有了访问磁盘文件系统(ext2/3、reiserfs、jfs、fat等)的能力。GRUB是通过引入所谓1.5阶段的引导加载程序来实现这项功能的,在该阶段中,GRUB主要来加载特殊的文件系统驱动。此后,阶段2的引导加载程序就可以进行加载了。一般GRUB有一个不错的GUI界面,其中通过分析配置文件来显示了一此引导选项。在我的ubuntu 8.10系统中,该配置文件位于/boot/grub/menu.lst。我们可以选择内核甚至修改附加内核参数,甚至可以使用GRUB shell对引导过程进行高级手工控制。我的menu.lst文件内容如下。Config代码default 0timeout 3hiddenmenutitle Ubuntu 8.10,kernel 2.6.27-11-genericuuid e2cf53c5-11de-4d57-a532-878901afd9b4kernel/boot/vmlinuz-2.6.27-11-generic root=UUID=e2cf53c5-11de-4d57-a532-878901afd9b4 ro locale=zh_CN quiet splashinitrd/boot/initrd.img-2.6.27-11-genericquiettitle Ubuntu 8.10,kernel 2.6.27-11-generic(recovery mode)uuid e2cf53c5-11de-4d57-a532-878901afd9b4kernel/boot/vmlinuz-2.6.27-11-generic root=UUID=e2cf53c5-11de-4d57-a532-878901afd9b4 ro locale=zh_CN singleinitrd/boot/initrd.img-2.6.27-11-generictitle Ubuntu 8.10,kernel 2.6.27-7-genericuuid e2cf53c5-11de-4d57-a532-878901afd9b4kernel/boot/vmlinuz-2.6.27-7-generic root=UUID=e2cf53c5-11de-4d57-a532-878901afd9b4 ro locale=zh_CN quiet splashinitrd/boot/initrd.img-2.6.27-7-genericquiettitle Ubuntu 8.10,kernel 2.6.27-7-generic(recovery mode)uuid e2cf53c5-11de-4d57-a532-878901afd9b4kernel/boot/vmlinuz-2.6.27-7-generic root=UUID=e2cf53c5-11de-4d57-a532-878901afd9b4 ro locale=zh_CN singleinitrd/boot/initrd.img-2.6.27-7-generict itle Ubuntu 8.10,memtest86+uuid e2cf53c5-11de-4d57-a532-878901afd9b4kernel/boot/memtest86+.binquietdefault 0timeout 3hiddenmenutitle Ubuntu 8.10,kernel 2.6.27-11-genericuuid e2cf53c5-11de-4d57-a532-878901afd9b4kernel/boot/vmlinuz-2.6.27-11-generic root=UUID=e2cf53c5-11de-4d57-a532-878901afd9b4 ro locale=zh_CN quiet splash initrd/boot/initrd.img-2.6.27-11-genericquiettitle Ubuntu 8.10,kernel 2.6.27-11-generic(recovery mode)uuid e2cf53c5-11de-4d57-a532-878901afd9b4kernel/boot/vmlinuz-2.6.27-11-generic root=UUID=e2cf53c5-11de-4d57-a532-878901afd9b4 ro locale=zh_CN singleinitrd/boot/initrd.img-2.6.27-11-generictitle Ubuntu 8.10,kernel 2.6.27-7-genericuuid e2cf53c5-11de-4d57-a532-878901afd9b4kernel/boot/vmlinuz-2.6.27-7-generic root=UUID=e2cf53c5-11de-4d57-a532-878901afd9b4 ro locale=zh_CN quiet splash initrd/boot/initrd.img-2.6.27-7-genericquiettitle Ubuntu 8.10,kernel 2.6.27-7-generic(recovery mode)uuid e2cf53c5-11de-4d57-a532-878901afd9b4kernel/boot/vmlinuz-2.6.27-7-generic root=UUID=e2cf53c5-11d e-4d57-a532-878901afd9b4 ro locale=zh_CN singleinitrd/boot/initrd.img-2.6.27-7-generictitle Ubuntu 8.10,memtest86+uuid e2cf53c5-11de-4d57-a532-878901afd9b4kernel/boot/memtest86+.binquiet将第二阶段的引导加载程序加载到内存中之后,就可以对文件系统进行查询了,并将默认的内核映像和initrd映像加载到内存中。当这些映像文件准备好之后,阶段2的引导加载程序就可以调用内核映像。正如上面配置文件描述的那样,我的ubuntu启动会将加载/boot/vmlinuz-2.6.27-11-generic(zImage/bzImage格式的kernel映像)和/boot/initrd.img-2.6.27-11-generic(cpio格式的initrd映像)。接下来就是kernel引导加载过程,这个过程包括如下6步。执行一个对硬件做些基本设置的例程;(,/arch/i386/boot/head.S中的start例程)设置一个基本的环境(堆栈等),并清除Block Started by Symbol(BSS);(./arch/i386/boot/compressed/head.S中的startup_32例程)通过连接在映像中的函数来解压内核;(./arch/i386/boot/compressed/misc.c中的decompress_kernel C函数)启动swapper(0进程)进程,初始化页表,启用CPU内存分页。然后会为任何可选的浮点单元(FPU)检测CPU的类型,并将其存储起来供以后使用;(./arch/i386/kernel/head.S中的startup_32函数)调用linux kernl main函数,进入与体系结构无关的Linux内核部分。(init/main.c中的start_kernel函数)这会调用一系列初始化函数来设置中断,执行进一步的内存配置,并加载已初始化的RAM盘。最后启动init进程,这是第一个用户空间进程(user-space process);(./arch/i386/kernel/process.c中的kernel_thread)最后,启动空任务。现在调度器就可以接管控制权了(在调用cpu_idle之后)。通过启用中断,抢占式的调度器就可以周期性地接管控制权,从而提供多任务处理能力。上面第5步加载的RAM盘(initrd)是由阶段2引导加载程序加载到内存中的,它用来加载必要的磁盘驱动内核模块,来挂载真正磁盘的root文件系统。引导加载的最后的一步就是执行init(1进程),该进程会根据配置来启动服务。一般的配置都会写在inittab里,不过我这里用的ubuntu使用的是upstart,它是基于事件驱动的,发生什么event怎么处理,在这里init进程会产生startup event,upstart据此来启动rc.*配置的进程。不过无论如何,此时引导加载程序已经放权了。这里抄录一段LILO与GURB的优缺点对比。LILO没有交互式命令界面,而GRUB拥有。LILO不支持网络引导,而GRUB支持。LILO将关于可以引导的操作系统位置的信息物理上存储在MBR中。如果修改了LILO配置文件,必须将LILO第一阶段引导加载程序重写到MBR。相对于GRUB,这是一个更为危险的选择,因为错误配置的MBR可能会让系统无法引导。使用GRUB,如果配置文件配置错误,则只是默认转到GRUB命令行界面。关于kernel和initrd两个映像。技术含量很高的,嵌入式开发中bootloader可是很大一块。值得深入,只可惜现在的技术水平,哎kernel/boot/vmlinuz-2.6.27-7-genericinitrd/boot/initrd.img-2.6.27-7-generic initrd映像是打包的RAM盘根文件系统。一般initrd.img-2.6.27-7-generic是一个cpio包文件,老版本也有gzip压缩格式的。通过cpio命令将其解包到当前目录中,如下。cpio使用方法可参见cpio命令详解。Shell代码zcat initrd.img-2.6.27-11-generic|cpio-i-d-no-absolute-filenameszcat initrd.img-2.6.27-11-generic|cpio-i-d-no-absolute-filenames在我这里解包后的根文件系统包括如下内容。从上面的directory tree可以看到initrd中主要包括的就是磁盘、网络、文件系统的驱动lkm文件。其中还有最主要是的init shell脚本,它包括了初使化的全过程。Shell代码#!/bin/shechoLoading,please wait.-d/dev|mkdir-m 0755/dev-d/root|mkdir-m 0700/root-d/sys|mkdir/sys-d/proc|mkdir/proc-d/tmp|mkdir/tmpmkdir-p/var/lockmount-t sysfs-o nodev,noexec,nosuid none/sysmount-t proc-o nodev,noexec,nosuid none/proc#Note that this only becomes/dev on the real filesystem if udevs scripts#are used;which they will be,but its worth pointing outmount-t tmpfs-o mode=0755 udev/dev-e/dev/console|mknod-m 0600/dev/console c5 1-e/dev/null|mknod/dev/null c1 3/dev/.initramfs-toolsmkdir/dev/.initramfs#Export the dpkg architectureexport DPKG_ARCH=./conf/arch.conf#Set modprobe envexport MODPROBE_OPTIONS=-Qb#Export relevant variablesexport ROOT=export ROOTDELAY=export ROOTFLAGS=export ROOTFSTYPE=export break=export init=/sbin/initexport quiet=nexport readonly=yexport rootmnt=/rootexport debug=export panic=export blacklist=export resume_offset=#Bring in the main config./conf/initramfs.conffor conf in conf/conf.d/*;do-f$conf&.$confdone./scripts/functions#Parse command line optionsfor xin$(cat/proc/cmdline);docase$x ininit=*)init=$x#init=;root=*)ROOT=$x#root=case$ROOT inLABEL=*)ROOT=/dev/disk/by-label/$ROOT#LABEL=;UUID=*)ROOT=/dev/disk/by-uuid/$ROOT#UUID=;/dev/nfs)-z$BOOT&BOOT=nfs;esac;rootflags=*)ROOTFLAGS=-o$x#rootflags=;rootfstype=*)ROOTFSTYPE=$x#rootfstype=;rootdelay=*)ROOTDELAY=$x#rootdelay=case$ROOTDELAYin*!:digit:.*)ROOTDELAY=;esac;resumedelay=*)RESUMEDELAY=$x#resumedelay=;loop=*)LOOP=$x#loop=;loopflags=*)LOOPFLAGS=-o$x#loopflags=;loopfstype=*)LOOPFSTYPE=$x#loopfstype=;cryptopts=*)cryptopts=$x#cryptopts=;nfsroot=*)NFSROOT=$x#nfsroot=;netboot=*)NETBOOT=$x#netboot=;ip=*)IPOPTS=$x#ip=;boot=*)BOOT=$x#boot=;resume=*)RESUME=$x#resume=;resume_offset=*)resume_offset=$x#resume_offset=;noresume)noresume=y;panic=*)panic=$x#panic=case$panicin*!:digit:.*)panic=;esac;quiet)quiet=y;ro)readonly=y;rw)readonly=n;debug)debug=yquiet=nexec/tmp/initramfs.debug 2&1set-x;debug=*)debug=yquiet=nset-x;break=*)break=$x#break=;break)break=premount;blacklist=*)blacklist=$x#blacklist=;esacdoneif-z$noresume;thenexport resume=$RESUMEelseexport noresumefidepmod-amaybe_break top#export BOOT variable value for compcache,#so we know if we run from casperexport BOOT#Dont do log messages here to avoid confusing usplashrun_scripts/scripts/init-topmaybe_break moduleslog_begin_msgLoading essential drivers.load_moduleslog_end_msgmaybe_break premount$quiet!=y&log_begin_msgRunning/scripts/init-premountrun_scripts/scripts/init-premount$quiet!=y&log_end_msgmaybe_break mountlog_begin_msgMounting root file system./scripts/$BOOTparse_numeric$ROOTmountrootlog_end_msgmaybe_break bottom$quiet!=y&log_begin_msgRunning/scripts/init-bottomrun_scripts/scripts/init-bottom$quiet!=y&log_end_msg#Move virtual filesystems over to the real filesystemmount-n-o move/sys$rootmnt/sysmount-n-o move/proc$rootmnt/proc#Check init bootargif-n$init&!-x$rootmnt$init;thenechoTarget filesystem doesnt have$init.init=fi#Search for valid initif-z$init;thenfor init in/sbin/init/etc/init/bin/init/bin/sh;doif!-x$rootmnt$init;thencontinuefibreakdonefi#No init on rootmountif!-x$rootmnt$init;thenpanicNo init found.Try passing init=bootarg.fi#Confuses/etc/init.d/rcif-n$debug;thenunset debugfi#Chain to real filesystemmaybe_break initexec run-init$rootmnt$init$rootmnt/dev/console$rootmnt/dev/console 2&1panicCould not execute run-init.#!/bin/shechoLoading,please wait.-d/dev|mkdir-m 0755/dev-d/root|mkdir-m 0700/root-d/sys|mkdir/sys-d/proc|mkdir/proc-d/tmp|mkdir/tmpmkdir-p/var/lockmount-t sysfs-o nodev,noexec,nosuid none/sys mount-t proc-o nodev,noexec,nosuid none/proc#Note that this only becomes/dev on the real filesystem if udevs scripts#are used;which they will be,but its worth pointing outmount-t tmpfs-o mode=0755 udev/dev-e/dev/console|mknod-m 0600/dev/console c5 1-e/dev/null|mknod/dev/null c1 3/dev/.initramfs-toolsmkdir/dev/.initramfs#Export the dpkg architectureexport DPKG_ARCH=./conf/arch.conf#Set modprobe envexport MODPROBE_OPTIONS=-Qb#Export relevant variablesexport ROOT=export ROOTDELAY=export ROOTFLAGS=export ROOTFSTYPE=export break=export init=/sbin/initexport quiet=nexport readonly=yexport rootmnt=/rootexport debug=export panic=export blacklist=export resume_offset=#Bring in the main config./conf/initramfs.conffor conf in conf/conf.d/*;do-f$conf&.$confdone./scripts/functions#Parse command line optionsfor xin$(cat/proc/cmdline);do case$x in init=*)init=$x#init=;root=*)ROOT=$x#root=case$ROOT in LABEL=*)ROOT=/dev/disk/by-label/$ROOT#LABEL=;UUID=*)ROOT=/dev/disk/by-uuid/$ROOT#UUID=;/dev/nfs)-z$BOOT&BOOT=nfs;esac;rootflags=*)ROOTFLAGS=-o$x#rootflags=;rootfstype=*)ROOTFSTYPE=$x#rootfstype=;rootdelay=*)ROOTDELAY=$x#rootdelay=case$ROOTDELAYin*!:digit:.*)ROOTDELAY=;esac;resumedelay=*)RESUMEDELAY=$x#resumedelay=;loop=*)LOOP=$x#loop=;loopflags=*)LOOPFLAGS=-o$x#loopflags=;loopfstype=*)LOOPFSTYPE=$x#loopfstype=;cryptopts=*)cryptopts=$x#cryptopts=;nfsroot=*)NFSROOT=$x#nfsroot=;netboot=*)NETBOOT=$x#netboot=;ip=*)IPOPTS=$x#ip=;boot=*)BOOT=$x#boot=;resume=*)RESUME=$x#resume=;resume_offset=*)resume_offset=$x#resume_offset=;noresume)noresume=y;panic=*)panic=$x#panic=case$panicin*!:digit:.*)panic=;esac;quiet)quiet=y;ro)readonly=y;rw)readonly=n;debug)debug=y quiet=n exec/tmp/initramfs.debug 2&1 set-x;debug=*)debug=y quiet=n set-x;break=*)break=$x#break=;break)break=premount;blacklist=*)blacklist=$x#blacklist=;esacdoneif-z$noresume;then export resume=$RESUMEelse export noresumefidepmod-amaybe_break top#export BOOT variable value for compcache,#so we know if we run from casperexport BOOT#Dont do log messages here to avoid confusing usplashrun_scripts/scripts/init-topmaybe_break moduleslog_begin_msgLoading essential drivers.load_moduleslog_end_msgmaybe_break premount$quiet!=y&log_begin_msgRunning/scripts/init-premountrun_scripts/scripts/init-premount$quiet!=y&log_end_msgmaybe_
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 体育绩效管理方法
- 辽宁省2025八年级语文上学期期末学情评估新人教版
- 2025年护理学基础知识考试试题库及答案(共670题)
- 核医学科甲状腺功能亢进放射治疗方案
- 八年级历史第22课全面内战的爆发(导学案)
- 护理部护士考试题及答案
- 2025年工会知识竞赛题库和参考答案
- 湖北生物中考试题及答案2025
- 宁夏回族自治区口腔种植医师资格证职业认证试卷与答案
- 弘鑫机电招聘考试题及答案
- GB/T 41782.2-2022物联网系统互操作性第2部分:网络连通性
- GB/T 1186-1992压缩空气用橡胶软管(2.5MPa以下)
- GB/T 10061-2008筛板筛孔的标记方法
- 水暖维修工理论考核试题及答案
- 2023年团课考试试题库
- 山茶花文化鉴赏课件
- 围手术期间循环紊乱的防治策略课件
- 六年级上册数学课件-3.6 分数连除和乘除混合运算丨苏教版 (共22张PPT)
- 新华师大版九年级下册初中数学全册教案
- DB4403∕T 36-2019 中小学生营养配餐指南
- 临床技术操作规范重症医学分册(共41页)
评论
0/150
提交评论