Linux启动过程分析.ppt
《Linux启动过程分析.ppt》由会员分享,可在线阅读,更多相关《Linux启动过程分析.ppt(47页珍藏版)》请在三一办公上搜索。
1、Linux内核分析与实例精讲,大连理工大学软件学院 邱铁 综合楼413,Tel:0411-87571632E_mail:,第2.2章 Linux的启动,源代码简介启动代码简介Linux内核代码组成分析Linux的启动层次Linux的启动分析,Linux系统的引导过程主要引导阶段,bootload加载阶段 LINUX启动阶段,在嵌入式系统中,一般的环境初始化都是在bootload中完成的。由bootload完成基本硬件环境的初始化之后,会将kernel image加载到一个区域.在x86中,开机之后的环境初始化是由bios提供的功能来完成的.然后跳转到活动分区对应的引导程序。,首先来看kerne
2、l image:Linux的系统映像其实是一个引导层加上kernel代码映像构成.不妨去查看一下关于make bzimage的过程.它是通过生成的build工具,由生成的文件将kenel压缩链接在一起。,启动过程要从head.s部分跳转到kernel code部份,因此需要将kernel code加载到一个固定的地址.对于压缩的kernel.会加载到0 x1000.对于完成的kernel.会将其加载到0 x100000.,对于head.S生成之后的文件,包含自带的一段启动程序和一段初始化代码.启动程序段位于head.S生成文件的前512 B的bootload会跳转到加载位置的512偏移处开始执
3、行.head.S的链接脚本内容如下:14.bsdata:*(.bsdata)15 16.=497;17.header:*(.header)18.inittext:*(.inittext),.section.header,a.globlhdrhdr:setup_sects:.byte SETUPSECTSroot_flags:.word ROOT_RDONLY,#下面的代码是初始化hdr的成员.程序的执行流程会在_start通过jump的机器码跳转出去 hdr:setup_sects:.byte SETUPSECTS root_flags:.word ROOT_RDONLY syssize:.l
4、ong SYSSIZE ram_size:.word RAMDISK vid_mode:.word SVGA_MODE root_dev:.word ROOT_DEV boot_flag:.word 0 xAA55,#offset 512,entry point#这里是偏移512字节的地方。bootload加载kernel之后的入口.globl _start _start:#这里实际上是jmp的操作码.byte 0 xeb#short(2-byte)jump.byte start_of_setup-1f,.header的偏移是在497处.那512的偏移刚好到了_start.这也就是从bootl
5、oad跳转进来的入口.hdr中存放的就是引导的各项参数.对应着一个struct setup_header 结构,_start通过jmp的操作码跳转到了start_of_setup.,#跳转后的入口 start_of_setup:#如果定义了SAFE_RESET_DISK_CONTROLLER 重启磁盘控制器#ifdef SAFE_RESET_DISK_CONTROLLER#Reset the disk controller.movw$0 x0000,%ax#Reset disk controller movb$0 x80,%dl#All disks int$0 x13#endif,#设置es寄
6、存器值为ds的内容#Force%es=%ds movw%ds,%ax movw%ax,%es cld#为了调用高级语言作准备,接下来要call c fuction.先设置好堆栈#Apparently some ancient versions of LILO invoked the kernel with%ss!=%ds,#which happened to work by accident for the old code.Recalculate the stack#pointer if%ss is invalid.Otherwise leave it alone,LOADLIN sets
7、up the#stack behind its own code,so we cant blindly put it directly past the heap.movw%ss,%dx cmpw%ax,%dx#%ds=%ss?movw%sp,%dx,#We will have entered with%cs=%ds+0 x20,normalize%cs so#it is on par with the other segments.pushw%ds pushw$6f lretw 6:#判断setup_sig 与$0 x5a5aaa55是否相等,在link的时候,会将setup_sig设为$0
8、 x5a5aaa55#Check signature at end of setup cmpl$0 x5a5aaa55,setup_sig jne setup_bad,#清空BSS#Zero the bss movw$_bss_start,%di movw$_end+3,%cx xorl%eax,%eax subw%di,%cx shrw$2,%cx rep;stosl#跳转到main#Jump to C code(should not return)calll main,设置好了堆栈之后,call main,跳转到了用C写的函数里.在这个函数里会初始化一部份硬件环境.Main的代码如下:vo
9、id main(void)/*First,copy the boot header into the zeropage*/copy_boot_params();/*End of heap check*/init_heap();,/*Make sure we have all the proper CPU support*/验证CPU 是否有效 if(validate_cpu()puts(Unable to boot-please use a kernel appropriate for your CPU.n);die();/*Tell the BIOS what CPU mode we int
10、end to run in.*/设置CPU的工作模式 set_bios_mode();,/*Detect memory layout*/调用int 0 x15 向bios 了解当前的内存布局 detect_memory();/*Set keyboard repeat rate(why?)*/keyboard_set_repeat();/*Query MCA information*/检查IBM 微通道总线 query_mca();,/*Set the video mode*/set_video();/*Do the last things and invoke protected mode*/
11、通过这个跳转到保护模式了 go_to_protected_mode();在copy_boot_params()中,会将hdr的值copy到一个全局变量boot_params中.static void copy_boot_params(void)memcpy(,在detect_memory()中会调用0 x15完成对内存的初步探测.并将其保存在boot_params.e820_map Main()最终会调用go_to_protected_mode().这个函数会将其转换到保护模式.void go_to_protected_mode(void)/*Hook before leaving real
12、mode,also disables interrupts*/禁用中断 realmode_switch_hook();,/*Move the kernel/setup to their final resting places*/移动kernel到0 x10000 move_kernel_around();/*Enable the A20 gate*/置位键盘的a20 引脚 if(enable_a20()puts(A20 gate not responding,unable to boot.n);die();,/*Reset coprocessor(IGNNE#)*/重置协处理器 reset_
13、coprocessor();/*Mask all interrupts in the PIC*/在pic中屏弊掉所有中断 mask_all_interrupts();/*Actual transition to protected mode.*/建立临时的idt 和gdt 并将IDT清空 setup_idt();setup_gdt();,/跳转到内核的起点处即header.S/对于压缩的kernel来说,这里还是从0 x1000处运行,并没有跳转到转移中运行 protected_mode_jump(boot_params.hdr.code32_start,(u32),调用setup_idt()
14、和setup_gdt()建立一个临时的IDT和GDT.代码如下:static void setup_idt(void)static const struct gdt_ptr null_idt=0,0;asm volatile(lidtl%0:m(null_idt);可以看到,这个临时的IDT是空的.,static void setup_gdt(void)/*There are machines which are known to not boot with the GDT being 8-byte unaligned.Intel recommends 16 byte alignment.*/
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux 启动 过程 分析
链接地址:https://www.31ppt.com/p-5437942.html