北京大学软件学院模板[001].ppt

上传人:ga****84 文档编号:327235 上传时间:2018-09-22 格式:PPT 页数:53 大小:395.50KB
下载 相关 举报
北京大学软件学院模板[001].ppt_第1页
第1页 / 共53页
北京大学软件学院模板[001].ppt_第2页
第2页 / 共53页
北京大学软件学院模板[001].ppt_第3页
第3页 / 共53页
北京大学软件学院模板[001].ppt_第4页
第4页 / 共53页
北京大学软件学院模板[001].ppt_第5页
第5页 / 共53页
点击查看更多>>
资源描述

1、第一讲:linux概述,Linux的特点及发展简史Linux内核的特点Linux内核的结构及主要组成部分Linux系统启动过程,Linux的特点及发展简史,1991: Finnish student Linus Torvalds started working on update of MinixPOSIX-compliant kernel,Unix-like OSOpen source: entire kernel source available free usingGPL(GNU Public License ) distribution: “ free” as in freedom (

2、not zero cost)Written mainly in C, Some Assembler,返回,Linux内核的特点,Unix内核是单内核、单模块设计它是一个不可分割的静态可执行体,必须以完整、单独的可执行块的形式在一个单独的地址空间运行Windows NT和Mach是微内核的典型实例微内核的功能被划分为多个独立的过程,每个过程叫做一个服务器。Linux内核与Unix内核一样是单内核,多模块设计Linux内核运行在单独的内核地址空间。与Unix内核不同的是,Linux内核汲取微内核的思想具备模块化设计、抢占式内核、支持内核线程以及动态装载内核模块的能力所有模块全部运行在内核态,直接调

3、用函数,无需消息传递支持多称多处理SMP机制,返回,Linux内核的结构及主要组成部分,Linux内核主要由五个子系统组成:进程调度,内存管理,虚拟文件系统,网络接口,进程间通信。,arch:包含与硬件体系结构相关的代码,每种平台占一个相应的目录。比如:32位PC相关的代码存放在i386目录下,ARM平台相关的代码存放在arm目录下。在每个平台的目录中,还有一些子目录。其中比较重要的包括kernel(内核核心部分)、mm(内存管理)、lib(硬件相关工具函数)和boot(引导程序)等。Documentation:关于内核各部分的通用解释和注释。drivers:设备驱动程序,每个不同的驱动占用一

4、个子目录。fs:各种支持的文件系统,如ext、fat、ntfs等。include:内核头文件。其中,include/asm-*/中是体系结构相关的头文件(*表示体系结构的名称,比如:include/asm-arm)。include/linux中是内核基本的头文件。init:内核C语言部分的初始化代码(注意不是系统引导代码)。ipc:进程间通信的代码。,kernel:内核的最核心部分,包括进程调度、定时器等,和平台相关的一部分代码放在arch/*/kernel目录下。lib:各种库文件代码。mm:内存管理代码,和平台相关的一部分代码放在arch/*/mm目录下。net:网络相关代码,实现了各种常

5、见的网络协议。crypto:常用加密和散列算法(如AES、SHA等),还有一些压缩和CRC校验算法。scripts:用于配置内核文件的脚本文件。sound:常用音频设备的驱动程序等。usr:实现了一个cpio。cpio可以从cpio或tar格式的归档包中存入和读取文件,归档包是一种包含其他文件和有关信息的文件。,返回,Linux系统启动过程,针对linux系统的单x86 cpu的版本,基础知识系统引导,基础知识,Linux源代码中的C语言代码Linux源代码中的汇编语言代码:两种完全的汇编代码,以.s作为文件名后缀嵌入在c程序中的汇编代码。,C语言代码,Linux主体是用GNU的c语言编写从c

6、+中吸收了“inline”和“const”支持“属性描述符”(attribute)增加了新的基本数据类型“long long int”用于支持64位cpu,汇编语言代码,与一般的386汇编语言采用intel定义不同,它采用的是AT&T定义的格式。主要差别如下:Intel中多使用大写字母,而这里大多使用小写字母寄存器名前面要加“%”作为前缀,指令的源操作数与目标操作数的顺序与intel的正好相反。AT&T格式中,源在前,目标在后,汇编语言代码,访问内存的指令的操作数大小(即宽度)由操作码名称的最后一个字母决定,用作操作码后缀的字母有b(8位),w(16位),l(32位),e.g movb直接操作

7、数要加“$”作为前缀,intel中不用基本格式asm(“汇编语句” :输出寄存器 :输入寄存器 :会被修改的寄存器);输出和输入寄存器统一按顺序编号,起始是%0,基础知识,Linux的启动是指从系统加电到控制台显示登录提示为止的运行阶段:主要相关的代码是在arch/i386/boot中:bootsect.S,这是linux引导扇区的源代码setup.S这是辅助程序的一部分video.S这是辅助程序的另外一部分,用于引导过程中的屏幕显示,I386的启动代码文件,在arch/i386/boot目录下在arch/i386/boot/compressed目录下,I386的体系结构相关部分的启动代码都采

8、用汇编码写的,启动扇区中的启动代码,其目标码必然是512字节,I386初始化,内核解压缩,在arch/i386/kernel目录下的.S文件在init目录下,32位启动代码,这是体系结构无关部分,i386体系结构相关部分的启动,其目的就是进入main.c中的start_kernel处执行,基础知识,另外,子目录compressed中还有两个源代码文件head.S,misc.c。用于内核映象的解压缩。也属于辅助程序一部分。经过编译,汇编和连接后就形成三个部分:引导扇区的映象bootsetc,辅助程序setup和内核映象本身。大小不超过508KB的内核引导映象称为小映象zImage;否则称为大内核

9、bzImage,返回,BIOS引导linux引导( Boot Loader )核心初始化Init进程,返回,BIOS引导,加电开机后,运行地址0xffff0,即ROM BIOS地址上电自检;对硬件设备进行检测和连接,并将测得的数据送到BIOS数据区;从硬盘启动时,读入零柱面零磁道1扇区MBR(Master Boot Record)MBR从活动分区读入Boot Loader(linux引导程序),将制权交Boot Loader。将其装入起始地址为0x7c00的内存空间,然后跳转到0x7c00开始执行引导扇区的代码,返回,MBR,硬盘的第一扇区称为主引导记录(MBR, MASTER BOOT RE

10、CORD)MBR 的长度为512字节。第一部分为引导(PRE-BOOT)区,占了446个字节第二部分为分区表(PARTITION PABLE),共有64个字节,记录硬盘的分区信息。,返回,linux引导( Boot Loader ),作用:将OS读入内存,并将控制权交给OS的初始化程序几种:自己的 (bootsect.S)Lilo/GRUB不管哪种方式引导,最终都要引出setup.s,返回,Linux引导,该引导扇区内的代码就是bootsect.S汇编后生成的二进制代码该段代码(bootsect.S)将自身转移到0x90000处,然后跳转到那里继续执行,并通过bios提供的“int 0x13”

11、调用从磁盘上读入setup和内核的映象,然后跳转到setup的代码中,为执行内核映象做准备对部分代码的解释如下所示:,系统引导bootsect.S中的部分代码,movw$BOOTSEG, %axmovw%ax, %ds# %ds = BOOTSEG,将ds段寄存器设为0x7c00movw$INITSEG, %axmovw%ax, %es# %ax = %es = INITSEG,将es段寄存器设为0x9000movw$256, %cx#移动计数值256subw%si, %si#源地址ds:si=0x07c0:0x0000subw%di, %di#目标地es:di=0x9000:0x0000cl

12、d#清方向标志位rep#重复执行直到cx=0movsw#移动1个字ljmp$INITSEG, $go#间接跳转,INITSEG指出跳转到的段地址go:movw$0x4000-12, %di# 0x4000 is an arbitrary value =# length of bootsect + length of# setup + room for stack;# 12 is disk parm size.movw%ax, %ds# 将ds,ss都置成移动后代码所在的段处0x9000movw%ax, %ssmovw%di, %sp# 设置堆栈put stack at INITSEG:0x40

13、00-12.,系统引导bootsect.S中部分代码的解释,这段代码将启动扇区代码由0x7C00移至0x90000处。Linux将地址为0x90000的代码段称为INITSEG。然后跳转到go标志,准备一块堆栈,栈底位于$INITSEG:0x4000-12,系统引导bootsect.S中部分代码,load_setup:xorb%ah,%ah#ah=0x02读磁盘扇区到内存;al=需读出的扇区数,xorb%dl,%dlint$0x13xorw%dx,%dxmovb$0x02,%clmovw$0x0200,%bxmovb$0x02,%ahmovbsetup_sects,%alint$0x13jnc

14、ok_load_setuppushw%axcallprint_nlmovw%sp,%bpcallprint_hexpopw%axjmpload_setupok_load_setup:,系统引导bootsect.S中部分代码的解释,该段代码利用BIOS中提供的读磁盘调用“int 0x13”从磁盘将setup.S装入到9000:0200(linux中称之为SETUPPSEG段),即紧跟在bootsect.S之后,共四个扇区如果载入失败,则不断尝试循环。除非某次尝试成功,否则只有等待系统重启,返回,Linux的Boot Loader,典型的有:LILO和GrubLILO(Linux Loader)可

15、以被安装在OS分区的第一个扇区(启动扇区)也可以代替MBR中的引导程序事实上,LILO的代码尺寸大于一个扇区,因此被分成两个部分MBR或启动扇区部分剩余部分第一部分也被BIOS装载到RAM中0x7c00的位置第一部分在运行时将自己完整的装载到RAM中,通过lilo来进行引导,Lilo将用户在启动时输入的命令和参数存储在empty_zero_page(0x5000)的后半页,供arch/i386/kernel/setup.c文件的setup_arch()函数使用Lilo完成任务后,跳转至setup.S程序,转入实模式下的系统初始化,GRUB配置,配置文件 /boot/grub/grub.conf

16、,default 2timeout 30color white/blue blue/green title Fedora Coreroot (hd0,4) kernel /boot/vmlinuz-2.6.15 ro root=/dev/hda5 Initrd /boot/initrd-2.6.15.imgtitle Windowsroot (hd0,3)chainloader +1,缺省菜单项设置超时值菜单颜色,代表第一块硬盘的第5个分区,标题,将rhgb quiet改为single quiet按ENTER键完成修改并booting进入Linux单用户模式,返回,系统初始化,开始时实模式,后

17、来转入保护模式相关的:Setup.s 实模式Head.s 保护模式Start kernel() 0号进程,Setup的工作,setup.S连同内核映象由bootsect.S装入。setup.S从BIOS获取计算机系统的参数,放到内存参数区,供保护模式下代码使用读video.s,设置显示模式进入保护模式;辅助程序setup为内核映象的执行做好准备,然后跳转到0x100000(head.s入口)开始内核本身的执行,此后就是内核的初始化过程控制权交给 Head.s。,Head.s工作,保护模式下的核心初始化模块从0x10000开始执行初始化寄存器和数据区核心代码解压缩页表初始化初始化idt,gdt和

18、ldt启动核心star_kernel(),初始化寄存器和数据区,Arch/i386/boot/compressed目录下的head.S是段保护模式的汇编程序,先设置堆栈,然后调用同目录 下的misc.c文件的decompress_kernel()函数解压缩设置堆栈与寄存器检查A20线是否有效数据区BSS全部清零转入核心代码解压缩过程,核心代码解压缩,调用mics.c中的decompress_kernel开始解压缩。解压缩的步骤为:设置output_bufferMakecrc:建立一张CRC(校验)表(lib/inflate.c)调用gunzip()解压缩,同时比较CRC表,如果不一致说明解压出

19、错。检查kernel的大小解除压缩以后的内核映象放在0x10000处,调转到此处执行。,页表初始化,进行解压缩后,核心系统的入口就是arch/i386/kernel目录下的head.S。系统先初始化寄存器和数据区,然后执行以下步骤:将ds,es,fs,gs寄存器初始化为_KERNEL_DS的值进行两级页表的部分初始化。其中第一级swapper_pg_dir是页目录,页目录的第一个表项所指的第二级页表称为pg0,页表初始化,清空BSS区(未初始化数据区)跳转到setup_idt处对idt表进行初始化复制bootup参数到empty_zero_page检查cpu类型下面详细解释一下如何进行两级页表

20、的初始化:先把swapper_pg_dir清零Pg0登记在页目录的第0项和第768项,即把线性地址0和3G都指向pg0,初始化二级页表pg0和pg1Cpu控制寄存器的初始化:使CR3指向swapper_page_dir,将CR0的PG位置位(cpu的paging功能启动位)。Cpu的页管理功能便生效两级页表初始化的图示如下:,初始化idt,gdt,ldt(三步),1、初始化gdtGdt表项数=2个内核态段+两个用户态段+4个空闲表项+4个APM段+2NRTASK个用于LDT和TSS描述的段。Gdt的初始化的代码如下页图示:,ENTRY(cpu_gdt_table).quad 0x0000000

21、000000000/* NULL descriptor */.quad 0x0000000000000000/* 0x0b reserved */.quad 0x0000000000000000/* 0x13 reserved */.quad 0x0000000000000000/* 0x1b reserved */.quad 0x00cffa000000ffff/* 0x23 user 4GB code at 0x00000000 */.quad 0x00cff2000000ffff/* 0x2b user 4GB data at 0x00000000 */.quad 0x000000000

22、0000000/* 0x33 TLS entry 1 */.quad 0x0000000000000000/* 0x3b TLS entry 2 */.quad 0x0000000000000000/* 0x43 TLS entry 3 */.quad 0x0000000000000000/* 0x4b reserved */.quad 0x0000000000000000/* 0x53 reserved */.quad 0x0000000000000000/* 0x5b reserved */.quad 0x00cf9a000000ffff/* 0x60 kernel 4GB code at

23、 0x00000000 */.quad 0x00cf92000000ffff/* 0x68 kernel 4GB data at 0x00000000 */.quad 0x0000000000000000/* 0x70 TSS descriptor */.quad 0x0000000000000000/* 0x78 LDT descriptor */,/* Segments used for calling PnP BIOS */.quad 0x00c09a0000000000/* 0x80 32-bit code */.quad 0x00809a0000000000/* 0x88 16-bi

24、t code */.quad 0x0080920000000000/* 0x90 16-bit data */.quad 0x0080920000000000/* 0x98 16-bit data */.quad 0x0080920000000000/* 0xa0 16-bit data */* * The APM segments have byte granularity and their bases * and limits are set at run time. */.quad 0x00409a0000000000/* 0xa8 APM CS code */.quad 0x0000

25、9a0000000000/* 0xb0 APM CS 16 code (16 bit) */.quad 0x0040920000000000/* 0xb8 APM DS data */#if CONFIG_SMP.fill (NR_CPUS-1)*GDT_ENTRIES,8,0 /* other CPUs GDT */#endif,2、设定idt寄存器为idt_descr变量的当前值,指向idt表(共256项),但目前不允许中断(尚未设置中断门)3、在新的页管理方式下,重新设置堆栈,段选择寄存器,描述符寄存器。,返回,启动核心star_kernel(),前面对cpu进行了初始化,并启动了保护模

26、式现在的任务是初始化内核的核心数据结构,这些数据结构主要涉及:中断管理进程管理内存管理设备管理各种数据结构纷繁复杂,需要对各部分进行分析,启动核心,进入保护模式后,系统从start_kernel处开始执行,Start_kernel()函数变成0号进程,不再返回Start_kernel显示版本信息,调用setup_arch() (arch/i386/kernel/setup.c):初始化核心的数据结构最后,调用kernel_thread()创建init进程,进行系统配置该部分的代码在init/main.c中,启动核心,核心数据结构的初始化调用paging_init()初始化页表调用mem_ini

27、t()初始化页描述符调用trap_init()和init_IRQ()完成IDT最后的初始化工作调用k_mem_cache_init()和kmem_cache_sizes_init()初始化slab分配器,启动核心,调用time_init()初始化系统日期和时间调用kernel_thread为进程1创建内核线程父进程创建init子进程之后,返回执行cpu_idle,返回,Init进程和系统配置,Init进程(1号进程)首先创建一些后台进程来维护系统,然后进行系统配置,执行shell编写的初始化程序。然后转入用户态运行Init进程的执行流程如下,static int init(void * unu

28、sed)lock_kernel();smp_init();#if CONFIG_SMPmigration_init();#endifdo_basic_setup();prepare_namespace();/* * Ok, we have completed the initial bootup, and * were essentially up and running. Get rid of the * initmem segments and start the user-mode stuff. */free_initmem();unlock_kernel();if (open(/dev

29、/console, O_RDWR, 0) 0)printk(Warning: unable to open an initial,console.n);(void) dup(0);(void) dup(0);/* * We try each of these until one succeeds. * * The Bourne shell can be used instead of init if we are * trying to recover a really broken machine. */if (execute_command)execve(execute_command,a

30、rgv_init,envp_init);execve(/sbin/init,argv_init,envp_init);execve(/etc/init,argv_init,envp_init);execve(/bin/init,argv_init,envp_init);execve(/bin/sh,argv_init,envp_init);panic(No init found. Try passing init= option to kernel.);,对init进程的解释,首先调用函数do_basic_setup()做系统初始化的工作(这之前系统只启动了cpu,内存和一些进程管理方面的工作

31、)调用free_initmem()函数,将初始化过程中使用的范围在_init_begin和_init_end之间的页面释放给空闲页面链表打开一个控制台设备如果存在指定命令就执行,否则,按顺序执行:,Init进程,如果存在“/sbin/init”文件,则跳转去执行“/sbin/init”如果存在“/etc/init”文件,则跳转去执行“/etc/init”如果存在“/bin/init”文件,则跳转去执行“/bin/init”如果存在“/bin/sh”文件,则跳转去执行“/bin/sh”,返回,思考题,在i386中,内核可执行代码在内存中的首地址是否可随意选择?为什么?主引导扇区位于硬盘什么位置?如果一个硬盘的主引导扇区有故障,此硬盘是否还可以使用?在没有LILO的情况下,系统是怎么样引导的进入保护模式为什么要打开A20地址线?Linux内核在实模式下的初始化完成哪些功能?进程0和init进程的主要任务是什么?,Q&A,本讲结束 !,

展开阅读全文
相关资源
相关搜索
资源标签

当前位置:首页 > 重点行业资料库 > 1

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。