Linux操作系统分析.pdf
.基于x86的Linux启动代码分析小结和作业.Linux操作系统分析2 基于x86的Linux启动代码分析陈香兰()计算机应用教研室计算机学院嵌入式系统实验室苏州研究院中国科学技术大学Fall 2010陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.Outline.1基于x86的Linux启动代码分析.2小结和作业陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.源代码来源内核版本:2.6.26ftp:/ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.26.tar.gz解压缩后,成功编译一次建立Source Insight工程Windows+Source InsightWine+Source Insight安装wine:sudo apt-get install wine在wine中安装SourceInsight:wine XXX.exe陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.基于x86的Linux启动代码分析了解linux的源码组织看目录结构了解linux的内核代码结构看Makefile了解基于x86的linux的boot image的结构看Makefile文件和链接描述文件掌握x86的启动流程阅读启动源码文件陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.Linux-2.6.26阅读linux目录下的README关于Linux的介绍(WHAT IS LINUX?)该版本内核支持的体系结构(ON WHAT HARDWAREDOES IT RUN?)Linux源代码目录中的文档目录(DOCUMENTATION)如何配置、编译、安装INSTALLING the kernelBUILD directory for the kernelCONFIGURING the kernelCOMPILING the kernel等等陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.Linux内核源代码中的主要子目录 IDocumentation 内核方面的相关文档。arch 与体系结构相关的代码。对应于每个支持的体系结构,有一个相应的目录如x86、arm、alpha等。每个体系结构子目录下包含几个主要的子目录:kernel 与体系结构相关的核心代码mm 与体系结构相关的内存管理代码lib 与体系结构相关的库代码include 内核头文件。对每种支持的体系结构有相应的子目录,如asm-x86、asm-arm、asm-alpha等。符号链接asm,如“asm-asm-x86”。实际上,“#include asm/xxxx.h”?陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.Linux内核源代码中的主要子目录 IIinit 内核初始化代码。提供main.c,包含start kernel函数。kernel 内核管理代码。mm 内存管理代码。ipc 进程间通讯代码。net 网络部分代码。lib 与体系结构无关的内核库代码。drivers 设备驱动代码。每类设备有相应的子目录,如char、block、net等fs 文件系统代码。每个支持文件系统有相应的子目录,如ext2、proc等。modules 可动态加载的模块。Scripts 配置核心的脚本文件。等等陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.考虑Arch为i386 考察如下目录观察Linux源码的根目录观察arch目录观察arch下的x86目录arch/x86/bootarch/x86/boot/compressedarch/x86/kernel观察Linux的init目录陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.阅读documentation/i386/boot.txt I由于一些历史的原因,基于x86的Linux的启动比较复杂这个文档(THE LINUX/I386 BOOT PROTOCOL)包含如下内容.1Linux/i386的启动协议(若干个).2内存布局图(MEMORY LAYOUT).3实模式下的内核头结构及细节(THE REAL-MODE KERNEL HEADER).4内核的命令行(THE KERNEL COMMAND LINE).5MEMORY LAYOUT OF THE REAL-MODE CODE.6启动配置示例(SAMPLE BOOT CONFIGURATION).7装载Linux的剩余部分(LOADING THE REST OF THE KERNEL)陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.阅读documentation/i386/boot.txt II.8特殊的命令行参数(SPECIAL COMMAND LINE OPTIONS).9运行内核(RUNNING THE KERNEL).10高级启动回调函数(ADVANCED BOOT LOADER HOOKS).1132-bit BOOT PROTOCOL陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.阅读Linux源码根目录下的Makefile找到缺省目标all找到vmlinux目标,并阅读陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.解释:关于$(call if changed rule,vmlinux)rule vmlinux陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业链接描述文件?链接顺序:vmlinux-initvmlinux-main陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.参见“Documentation/kbuild/makefiles.txt”陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业注意:vmlinux-initvmlinux-mainvmlinux-dirs陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.主要目标文件的编译.vmlinux不妨以core-y为例,观察体系相关和体系无关部分的代码是如何被包含进来的陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.x86的启动文件.根据vmlinux-init找到head-y,init-y关于arch/x86/Makefile的引入根Makefile中以include的方式包含了X86体系结构相关部分的Makefile在这个Makefile中其中,变量BITS为32或者64,我们只考虑32位的情况在根Makefile中可以看到vmlinux包含如下内容i386/kernel/head 32.S等+init/main.c+init/version.o+CORE FILES+DRIVERS+NETWORKS+LIBS陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.为便于阅读,了解关于命令输出的相关内容.陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.make XXX若make install在x86的Makefile中有install规则若make bzImage/zImage等,则要找到对应的目标然后进行bzImage/zImage可在arch/x86的Makefile中找到相应规则其他的zXXX/bzXXX也都依赖于boot下的zImage/bzImage它们最终都找到i386/boot/Makefile陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.考虑boot bzImage IMake bzImage 在arch/X86/Makefile中z代表压缩;b代表大内核到boot目录下的Makefile观察boot目录和boot下的Makefile观察compressed目录及该目录下的Makefile陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.考虑boot bzImage II.最后:.在Linux内核源代码顶层目录下生成一个vmlinuxarch/x86/kernel/head 32.S+init/main.c+compressed下的vmlinux为compressed/head 32.S+压缩后的顶层目录下的vmlinux boot下的bzImage为boot下header.S等(即setup.bin)+compressed/vmlinux陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.x86的启动(小结)boot/header.S等compressed/head 32.S等kernel/head 32.S等init/main.c陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.I386机器的启动层次.1BIOS(Basic I/O System).2Bootloader软盘启动硬盘启动嵌套boot loader例如:grub、lilo、.3Linux kernel.Bootloader必须完成内核代码的加载,然后跳转到入口处运行.陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.BIOS I加电,RESET引脚.CPU加电后,将会初始化程序指针到某个约定好的地址上取指令运行,在这个地指处,往往安排了启动相关的代码,例如BIOS或者reset向量处理入口.初始化寄存器;CS:IP=0 xfffffff0,in ROMROM?BIOSBIOS启动内容POST(上电自检)初始化硬件设备搜索一个操作系统来启动根据配置,操作系统可以在软盘/硬盘/CD ROM上把对应设备的第一个扇区的内容(bootloader或部分)拷贝到RAM(0 x7c00)处跳转到0 x7c00处执行陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.Bootloader(引导装载程序)BIOS调用Bootloader把操作系统内核映像装载到RAM中考虑IBM PC的启动.软盘启动:.BIOS拷贝第一个扇区的内容(bootsect)到RAM(0 x7c00)中.硬盘启动:.硬盘的第一个扇区:主引导记录MBR,Master Boot RecordMBR存储该硬盘的分区表+一小段引导程序这个引导程序用来装载OS所在分区的第一个扇区(bootloader)的内容到RAM中这个引导程序也可以被替换陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.Linux的BootLoader典型的有:LILO和GrubLILO(Linux Loader)可以被安装在OS分区的第一个扇区(启动扇区)也可以代替MBR中的引导程序事实上,LILO的代码尺寸大于一个扇区,因此被分成两个部分MBR或启动扇区部分剩余部分第一部分也被BIOS装载到RAM中0 x7c00的位置第一部分在运行时将自己完整的装载到RAM中通常LILO或GRUB会显示一个已安装操作系统的列表按照用户的选择(或者按照缺省项)装载目标操作系统运行可能装载操作系统指定的启动代码运行(嵌套的情况)可能直接装载操作系统内核来运行陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.LILO的OS启动过程显示“Loading”header内容被装载到RAM的0 x90000操作系统内核的其他内容被装载到对于小内核:0 x10000(即64K处),称为低装载对于大内核:0 x100000(即1M处),称为高装载跳转到0 x90200处运行陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.I386内核的启动启动方式软盘启动:Linux2.6.26不支持硬盘启动:从header的 start开始运行.在进入源代码讲解之前,先看一下加载i386内核的内存布局图.陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.硬件角度:I386实模式下的内存布局图陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.I386内核从实模式开始启动运行.什么是实模式?.实模式是为了兼容早期的CPU而设置的i386系统总是始于实模式实模式下地址总线:20位内存范围:01MB逻辑地址=段地址+段内偏移段地址=段寄存器中的值*16(或左移4位)段寄存器:cs/ds/es/fs/gs段寄存器长度:16bit段长:16位偏移=64KB陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.加载I386内核的内存布局图zImage/Image的内核加载器所使用的经典的内存布局(1M=0 x100000)参见boot.txt陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.硬盘启动,两阶段引导装载LILO(LInuxLOader)第一个扇区装载LINUXheader.S等0 x90000,其中 start在0 x90200处系统0 x100000 x100000跳转到 start陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.启动第一步,小结总之,在跳转到header.S的 start的时候,内存里面的代码布局为0 x90000:header.S 前512字节内容0 x90200:header.S 的 start及其后低装载:0 x10000:带解压的vmlinux高装载:0 x100000:带解压的vmlinux实模式下的内核头结构包括512字节的最后和 start 之后的一些位置从偏移0 x1F1开始,具体描述参见documentation/i386/boot.txt陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.Header.S之 start:0 x90200start:跳转到start of setup检查setup的signature清除BSS段跳转到main执行其中,Main用来初始化硬件设备并为内核程序的执行建立环境内存检测、键盘、视频、go to protected mode陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.关于保护模式在setup.bin中,从实模式保护模式保护模式下,地址总线32位,访存范围为4GB原来的段寄存器现在被称作段选择子,与GDT表配合使用GDT表由gdtr指示其位置和长度使用特殊的指令进行操作:sgdt/lgdt陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.图示陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.段描述符的格式陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业一般装载gdt和idt之后,要重新装载段寄存器cs、ds、es、fs、gscs通常通过一条长跳转指令装载其他数据段寄存器直接设置如在arch/x86/boot/header.S陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.go to protected mode Iarch/x86/boot/main.c中,main函数最后调用go to protected mode函数arch/x86/boot/pm.c中陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.go to protected mode II这里是code32 start的定义在陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.go to protected mode IIImain函数在一开始就调用了copy boot params陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.arch/boot/compressed具有自解压功能的vmlinux.binzImage中,在0 x1000处关于100000,10000,1000(参见move kernel arround)bzImage中,在0 x100000处compressed/head 32.S的startup 32初始化段寄存器和一个临时堆栈初始化BSS段解压缩decompress kernel无论高装载或低装载解压缩后,都在物理地址0 x100000(1MB)处跳转到0 x100000处.linux-2.6.26archx86configsi386 defconfig中定义CONFIG PHYSICAL START=0 x100000陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业解压缩后,vmlinux在0 x100000处根据vmlinux.lds,vmlinux的地址被链接为0 xc0000000+0 x100000处如何正确运行呢?最初是实模式,然后进入保护模式,还没有分页、映射好期间,没有长跳转,只使用采用相对地址的近距离跳转不使用符号名陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.Kernel/Head 32.SStartup 32初始化段寄存器设置页目录和页表,分页建立进程0的内核堆栈Setup idt拷贝系统参数识别处理器GDT、IDTi386 start kernel陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.如何进入start kernel?.?如何从08M的空间中转入3G以上的地址空间中运行的?.陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.关于页目录和页表的定义及初始化 Iarch/x86/kernel/head 32.S中定义了swap pg dirarch/x86/kernel/vmlinux 32.lds.S文件中陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.关于页目录和页表的定义及初始化 II分页使能在使用页目录和页表之前,首先要进行页目录和页表的初始化(部分)陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.关于页目录和页表的定义及初始化 III陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.关于页目录和页表的定义及初始化 IV陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.关于kernel/head 32.S的内核堆栈陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.控制寄存器(Control Registers)CR0CR1CR2CR3.大多与内存相关.陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.CR0 ICR0,MSW register(Machine Status Word,32-bit version)包含系统控制位,用于控制操作模式和状态Instruction:lmswTo turn on the PE-bit(enables protected-mode)LINUX setup.S(旧版本):movw$1,%axlmsw%axjmp flush instr/why?flush instr:陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.CR0 IIin Linux-2.6.26/arch/x86/boot/pmjump.S陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.CR1、CR2、CR3CR1:保留CR2:在缺页异常的时候,记录缺页地址CR3:记录页目录所在的物理地址和两个标记(PCD&PWT)陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.小结.1基于x86的Linux启动代码分析.2小结和作业陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.作业2i386实模式下是如何解决20位地址空间和16位段寄存器之间的不匹配问题的?i386保护模式下的段寄存器的内容与实模式下段寄存器的内容一样么?如何解释?陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.Project2基于x86的linux-2.6.26的启动分析首先进行Makefile的分析,了解bzImage的代码结构考虑grub为启动引导程序,分析代码的启动过程。提供详细分析报告陈香兰()Linux操作系统分析.基于x86的Linux启动代码分析小结和作业.Thanks!.The end.陈香兰()Linux操作系统分析