📄 00000042.htm
字号:
<HTML><HEAD> <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER>发信人: yyh (阿欢&2000年终于快到了), 信区: Linux <BR>标 题: Linux的启动和核心介绍, Xiao Man <BR>发信站: BBS 水木清华站 (Sun Dec 12 22:05:52 1999) <BR> <BR>前几天大家对Linux的启动有些讨论。 <BR>于是整理了一下前段时间与他人交流的提纲,希望起到抛砖引玉的作用。 <BR><A HREF="mailto:xiaoman04@hotmail.com">xiaoman04@hotmail.com</A> <BR>这是一次对Linux介绍后的整理。 <BR>对象是一些刚对Linux核心感兴趣,并且准备进一步研究和改造的同志。 <BR>因为是由提纲整理而成,有些乱,见谅! <BR> <BR>四部分内容: <BR>一、Linux核心源码结构介绍 <BR>二、编译和配置的过程 <BR>三、系统启动顺序的相关文件 <BR>四、核心改造的一些经验 <BR>一、 <BR>当我们安装好一个Linux系统,通常核心源码存放在/usr/src/linux/目录。 <BR>下面先看看这目录下的各个子目录及文件。 <BR>[/]#cd /usr/src/linux <BR>[linux]#ls -aF <BR>./ MAINTAINERS drivers/ kernel/ scripts/ <BR>../ Makefile fs/ lib/ <BR>COPYING README include/ mm/ <BR>CREDITS Rules.make init/ modules/ <BR>Documentation/ arch/ ipc/ net/ <BR>下面我们逐一描述: <BR>COPYING <BR>## GPL版权申明,看后你至少应该知道,你对具有GPL版权的源代码改动而 <BR>形成的程序,或使用GPL工具产生的程序,具有使用GPL发表的义务。其中之一就是 <BR>公开源代码。 <BR>CREDITS <BR>## 光荣榜,你应当感谢的一些人的信息,其中的每一个人都对Linux做出过 <BR>很大贡献。 <BR>Documentation/ <BR>## 文档目录,可有选择地看一下你感兴趣的部分 <BR>MAINTAINERS <BR>## 维护人员列表,对当前版本的内核各部分都有谁负责,如果你研究的 <BR>够深入,可以与他们讨论 <BR>Makefile <BR>## 如果你在UNIX编译过程序,可以看明白 <BR>README <BR>## Linus 所写,核心及其编译配置方法简单介绍 <BR>Rules.make <BR>## make时使用的一些共同规则 <BR>arch/ <BR>## architecture(体系结构)我关心的i386启动过程在其中, <BR>## 包括Linux在多种平台下的实现。如果要移植系统到一个新的 <BR>##CPU环境中,这就是你要关心的目录 <BR>drivers/ <BR>## 驱动程序目录,包含大量设备驱动的实现,按类别分子目录 <BR>fs/ <BR>## 文件系统,实现了当前流行的几乎所有文件系统。Cool <BR>include/ <BR>## 嵌入文件目录 <BR>init/ <BR>## 初始化文件,包含main.c和version.c两个文件。Initialize <BR>ipc/ <BR>## ipc的实现,与SYS V兼容 <BR>kernel/ <BR>## 最核心代码,调度,中断,信号等的处理 <BR>lib/ <BR>## 一些工具。 <BR>mm/ <BR>## 内存管理,Memory Manager,虚拟页、缓冲的实现。 <BR>modules/ <BR>## 模块文件目录,用于存放编译时产生的模块目标文件(参考编译过程) <BR>net/ <BR>## 网络实现,包括TCP/IP在内的大量网络协议的实现。 <BR>scripts/ <BR>## 描述文件,脚本,用于对核心的配置。 <BR> <BR>二、 <BR>构造内核 <BR>常用命令包括: <BR>make config, dep, clean, mrproper, zImage, bzImage, modules, modules_install <BR> <BR>(1) make config <BR>核心配置,调用./scripts/Configure 按照arch/i386/config.in 来进行 <BR>配置。 <BR>命令执行完后产生文件.config,其中保存着配置信息。 <BR>下一次再做make config将产生新的.config文件,原.config被改名为.config.old <BR>(2)make dep <BR>寻找依存关系。 <BR>产生两个文件.depend和.hdepend <BR>其中.hdepend表示每个.h文件都包含其它哪些嵌入文件。 <BR>而.depend 文件有多个,在每个会产生目标文件(.o)文件的目录下均有, <BR>它表示每个目标文件都依赖哪些嵌入文件(.h)。 <BR> <BR>(3)make clean <BR>清出以前构核所产生的所有目标文件、模块文件、核心以及一些临时文件等, <BR>不产生任何文件 <BR> <BR>(4)make rmproper <BR>删除所有因构核过程中产生的所有文件,及除了做make clean外,还要 <BR>删除.config,.depend等文件,把核心源码恢复到最原始的状态。 <BR>下次构核时就必须重新配置了。 <BR> <BR>(5)make, make zImage, make bzImage <BR>make: <BR>构核。通过各目录的Makefile文件进行。 <BR>会在各个目录下产生一大堆目标文件,若核心代码没有错误,将 <BR>产生文件vmlinux,这就是所构的核心。并产生映射文件System.map <BR>通过各目录的Makefile文件进行。 <BR>.version 文件中的数加1,表示版本号(又产生一个新的版本了),让你 <BR>明白,你已经对核心改动过多少次了。 <BR>make zImage: <BR>在make的基础上产生压缩的核心映象文件./arch/$(ARCH)/boot/zImage <BR>以及在./arch/$(ARCH)/boot/compresed/目录下产生一些临时文件。 <BR>make bzImage: <BR>在make 的基础上产生压缩比例更大的核心映象文件 <BR>./arch/$(ARCH)/boot/bzImage <BR>以及在./arch/$(ARCH)/boot/compresed/目录下产生一些临时文件。 <BR>在核心太大时进行。 <BR>(6)make modules <BR>编译模块文件,你在make config时所配置的所有模块将在这时编译, <BR>形成模块目标文件,并把这些目标文件存放在modules目录中。 <BR>使用如下命令看一看。 <BR>ls modules <BR>(7)make modules_install <BR>把上面编译好的模块目标文件目录/lib/modules/$KERNEL_VERSION/ 中。 <BR>比如我的版本是2.0.36,做完这个操作后可使用下面的命令看看: <BR>ls /lib/modules/2.0.36/ <BR> <BR>相关的命令还有很多,有兴趣可看相关资料和Makefile文件。 <BR>另外注意,这儿我们产生了一些隐含文件 <BR>.config <BR>.oldconfig <BR>.depend <BR>.hdepend <BR>.version <BR>它们的意义应该很清楚了。 <BR>三、 <BR>系统的启动顺序及相关文件 <BR>仍在核心源码目录下,看以下几个文件 <BR>./arch/$ARCH/boot/bootsect.s <BR>./arch/$ARCH/boot/setup.s <BR>./init/main.c <BR> <BR>bootsect.S 及 setup.S <BR> 这个程序是linux kernel的第一个程序,包括了linux自己的bootstrap程序, <BR>但是在说明这个程序前,必须先说明一般IBM PC开机时的动作(此处的开机是指 <BR>"打开PC的电源"): <BR> 一般PC在电源一开时,是由内存中地址FFFF:0000开始执行(这个地址一定 <BR>在ROM BIOS中,ROM BIOS一般是在FEOOOh到FFFFFh中),而此处的内容则是一个 <BR>jump指令,jump到另一个位於ROM BIOS中的位置,开始执行一系列的动作,包 <BR>括了检查RAM,keyboard,显示器,软硬磁盘等等,这些动作是由系统测试代码 <BR>(system test code)来执行的,随着制作BIOS厂商的不同而会有些许差异,但都 <BR>是大同小异,读者可自行观察自家机器开机时,萤幕上所显示的检查讯息。 <BR> 紧接着系统测试码之后,控制权会转移给ROM中的启动程序 <BR>(ROM bootstrap routine),这个程序会将磁盘上的第零轨第零扇区读入 <BR>内存中(这就是一般所谓的boot sector,如果你曾接触过电脑病 <BR>毒,就大概听过它的大名),至於被读到内存的哪里呢? --绝对 <BR>位置07C0:0000(即07C00h处),这是IBM系列PC的特性。而位在linux开机 <BR>磁盘的boot sector上的正是linux的bootsect程序,也就是说,bootsect是 <BR>第一个被读入内存中并执行的程序。现在,我们可以开始来 <BR>看看到底bootsect做了什么。 <BR>第一步 <BR> 首先,bootsect将它"自己"从被ROM BIOS载入的绝对地址0x7C00处搬到 <BR>0x90000处,然后利用一个jmpi(jump indirectly)的指令,跳到新位置的 <BR>jmpi的下一行去执行, <BR>第二步 <BR> 接着,将其他segment registers包括DS,ES,SS都指向0x9000这个位置, <BR>与CS看齐。另外将SP及DX指向一任意位移地址( offset ),这个地址等一下 <BR>会用来存放磁盘参数表(disk para- meter table ) <BR>第三步 <BR> 接着利用BIOS中断服务int 13h的第0号功能,重置磁盘控制器,使得刚才 <BR>的设定发挥功能。 <BR> <BR>第四步 <BR> 完成重置磁盘控制器之后,bootsect就从磁盘上读入紧邻着bootsect的setup <BR>程序,也就是setup.S,此读入动作是利用BIOS中断服务int 13h的第2号功能。 <BR>setup的image将会读入至程序所指定的内存绝对地址0x90200处,也就是在内存 <BR>中紧邻着bootsect 所在的位置。待setup的image读入内存后,利用BIOS中断服 <BR>务int 13h的第8号功能读取目前磁盘的参数。 <BR>第五步 <BR> 再来,就要读入真正linux的kernel了,也就是你可以在linux的根目录下看 <BR>到的"vmlinuz" 。在读入前,将会先呼叫BIOS中断服务int 10h 的第3号功能, <BR>读取游标位置,之后再呼叫BIOS 中断服务int 10h的第13h号功能,在萤幕上输 <BR>出字串"Loading",这个字串在boot linux时都会首先被看到,相信大家应该觉 <BR>得很眼熟吧。 <BR>第六步 <BR> 接下来做的事是检查root device,之后就仿照一开始的方法,利用indirect <BR>jump 跳至刚刚已读入的setup部份 <BR>比较 <BR> 把大家所熟知的MS DOS 与linux的开机部份做个粗浅的比较,MS DOS 由位於 <BR>磁盘上boot sector的boot程序负责把IO.SYS载入内存中,而IO.SYS则负有把DOS <BR>的kernel --MSDOS.SYS载入内存的重责大任。而linux则是由位於boot sector 的 <BR>bootsect程序负责把setup及linux的kernel载入内存中,再将控制权交给setup。 <BR>##这几步内容主要参照一个台湾同胞写的文档,setup.s的内容希望有人补充。 <BR> <BR> <BR>start_kernel() <BR>当核心被载入后,首先进入的函数就是start_kernel。 <BR>./init/main.c 中函数start_kernel包含核心的启动过程及顺序。 <BR>通过它来看核心整个初始化过程。 <BR>首先进行一系列初始化,包括: <BR>trap_init(); ##./arch/i386/kernel/traps.c 陷入 <BR>init_IRQ(); ##./arch/i386/kernel/irq.c setup IRQ <BR>sched_init(); ##./kernel/sched.c 调度初始化,并初始化bottom_half <BR>time_init(); ##./arch/i386/kernel/time.c <BR>init_modules(); ##模块初始化 <BR>mem_init(memory_start,memory_end); <BR>buffer_init(); ## ./fs/buffer.c 缓冲区 <BR>sock_init(); ## ./net/socket.c socket初始化,并初始化各协议(TCP等) <BR>ipc_init(); <BR>sysctl_init(); <BR>然后通过调用kernelthread()产生init进程,全权交由init进程处理。调用cpu_idle(N <BR>ULL)休息。 <BR>感兴趣又有时间的同志可以写一个startkernel()函数的详细分析报告。 <BR> <BR> <BR> <BR>下面看一看init进程的工作: <BR>首先创建进程 <BR>bdflush ##./fs/buffer.c 缓冲区管理 <BR>和kswapd ##./mm/vmscan.c 虚拟内存管理 <BR>这两个进程非常重要 <BR>系统初始化(系统调用setup) <BR>系统初始化包含设备初始化及各文件系统初始化。 <BR>sys_setup (./fs/filesystems.c) <BR>| <BR>|-device_setup <BR>| | <BR>| -- chr_dev_init(); ##字符设备 <BR>| blk_dev_init(); ##块设备 <BR>| scsi_dev_init(); ##SCSI <BR>| net_dev_init(); ##网络设备 <BR>| console_map_init(); ##控制台 <BR>|-binfmt_setup(); <BR>|-init_nls() ##各文件系统初始化 <BR>|-init_ext_fs() <BR>|-init_ext2_fs() <BR>. . <BR>. . <BR>. . <BR>|-init_autofs_fs() <BR>--mount_root() ##mount root fs <BR>##从这儿看看设备及文件的初始化顺序,加入我们的设备时就有了大局观。 <BR>执行/etc/rc ( rc.sysinit, rc.local, rc.# ) 和 <BR>执行/bin/sh <BR>______________________________________________________ <BR>END <BR> <BR> <BR> <BR> <BR>-- <BR>※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 162.105.17.237] <BR><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -