1.启动系统.当PC机加电开始启动时,80X86的处理器(CPU)在实模式下自检,开始执行物理地址0xFFFF0即ROM-BIOS的起始地址处的代码。PC机的BIOS进行系统自检,初始化中断向量表到物理地址0x0。然后把引导设备的第一个扇区加载到地址0x7C00,执行此处的指令。到这里与linux无关,x86系列的硬件设置如此.
linux的内核本身是不能自举的,所以lilo和loadlin的作用就是加载系统内核.有关lilo的原理可以参考lilo的readme.从加电到内核加载的过程是:加电->执行BIOS->加载第一扇区->lilo->加载内核.
Linux内核的最初部分代码是用汇编语言写的(文件是boot/bootsect.s)。当这段程序开始执行的时候,它首先把自身这部分代码移到绝对地址0x90000,把下面的2K代码从引导设备加载到地址0x90200上,内核的其余部分加载到地址0x10000处。在加载系统时显示“loading...”.
然后,程序控制权交给另一个实模式汇编程序(boot/Setup.S)。这部分程序标识主机系统的一些特性和VGA主板的类型。如果有必要,它让用户为控制台选择视频模式。接下来,此程序把整个系统从地址0x10000移到地址0x1000,进入保护模式。程序控制转给系统的其余部分即地址0x1000。
以上部分代码注释的极详细,如果你愿意k一下,源码附带的注释是你最好的帮助,另外,有人用中文注释了这些代码,似乎是在中国linux论坛上.你可以找找看.
下一个步骤是系统内核的解压过程,这部分代码在地址0x1000(文件/Boot/head.S),该段程序初始化寄存器,然后执行decompress_kernel(),这个函数源于zBoot/inflate.c、zBoot/unzip.c和zBoot/misc.c三个文件。解压后数据放在地址0x100000
(1
Meg),这就是为什么Linux不能在少于2M内存下运行的主要原因。进行解压的代码在地址0x101000执行,完成所有的32位模式设置:加载IDT,
GDT
和LDT,标识处理器和协处理器,设置内存叶面大小;最后执行start_kernel()。start_kernel()在init/main.c文件中,没有返回值。这没什么可解释的,如果你对保护模式有一点了解的话,可以很容易的读懂.如果你对保护模式不太了解的话,建议你读一下386/486汇编语言精要一书的第八章.那是一篇对保护模式的最好的入门文档.
2. 系统运行、 进程表、进程的创建与撤销、
执行程序。不解释了,随便找本unix或linux的编程书看看。我推荐的读物是unix操作系统的设计与实现的第二、三、四章,该书是中科院计算所95年编的,针对BSD4.3。再重复一次,源码是你最好的老师,参考书是为了了解原理用的.
3。文件系统。Linux在内核与文件系统之间提供一个标准接口层以便在它们之间交换信息,这个接口层称为“VFS”,虚拟文件系统。因此文件系统的代码分为两层:上层是核心数据表和数据结构的管理,下层是依赖于文件系统的函数集合以及涉及VFS的数据结构。所有依赖文件系统的函数在fs/*.c文件中。它们的主要功能是:
管理缓存;(buffer.c)
响应fcntl()和ioctl()系统调用;(fcntl.c ioctl.c)
在节点和缓存上映射pipes和fifos;(fifo.c pipe.c)
管理文件和节点表;(file_table.c inode.c)
加锁/解锁文件和目录;(locks.c)
映射节点名;(namei.c open.c)
实现灵活的select()函数;(select.c)
提供系统信息;(stat.c)
安装/卸载文件系统;(super.c)
执行可执行文件和内存信息转储;(exec.c)
加载不同的二进制格式;(bin_fmt*.c)
VFS接口由一些相对高级的操作组成,这些操作包括依赖于文件系统的函数和由具体文件系统完成的功能。最相关的结构有inode_operations
和file_operations,当然它们并不是孤立存在的,还有一些其它的数据结构。这些都在include/linux/fs.h文件中定义。
真实文件系统在内核的入口就是file_system_type结构,file_system_type列表在
fs/filesystems.c文件中,当出现mount操作时会引用它。对应相应文件系统类型的函数read_super填写结构super_block的内容,即顺序填写结构super_operations和type_sb_info,前者提供一个指向当前文件系统类型的一般性文件系统操作的指针,后者给出这一文件系统类型的特殊信息。
文件系统类型是一个链表,函数(un)register_filesystem是向内核注册/删除一个文件系统类型,在文件fs/super。C中实现。
文件系统类型的任务是通过执行低级的操作把相对高级的VFS操作映像到物理介质上(磁盘,网络等)。VFS的接口十分灵活,即支持传统的unix文件系统,也支持外来的msdos和umsdos等类型。
除了自身的目录,每种文件系统类型由以下元素组成:
1. 文件系统数组file_systems[]的入口;(fs/filesystem.c)
2. 超块包含文件;(include/linux/type_fs.h)
3. 节点包含文件;(include/linux/type_fs_i.h)
4. 一般性包含文件;(include/linux/type_fs.h)
5. 在文件include/linux/fs.h中两行#include,6. 即结构super_block和inode的入口;
文件系统自身目录包括了所有对节点和数据管理进行处理的相关代码
下面以Minix为例来看一看VFS的工作机制。
当minix文件系统安装以后,函数minix_read_super从安装设备读取数据填写结构
super_block。结构中s_op取得指向minix_sops指针,一般文件系统用minix_sops来进行分配超块操作。
新安装的文件系统链接到整个系统树上需要以下数据项:(假设sb是super_block结构,dir_i指向安装节点)
sb->s_mounted 指向安装的文件系统的根目录的节点;(MINUX_ROOT_INO)
dir_i->i_mount= sb->s_mounted;
sb->s_covered=dir_I;
卸载文件系统由do_umount来完成,这个操作将执行minix_put_super函数。
当存取一个文件时,将执行minix_read_inode函数,它把minix_inode的内容填写到系统范围内的inode结构中。inode->i_op要根据inode->imode来填写,inode->i_op负责对文件更深入的操作。Minix函数在fs/minix/inode.c文件中。
Inode_operations结构用于给具体的文件系统类型核心函数分配节点操作,结构的第一个入口是指向file_operations的指针,相当于i_op用于数据管理。Minix文件系统类型允许三种情况节点操作(目录、文件、逻辑链接),两种情况文件操作(不包括逻辑链接)。
目录操作(minix_readdir)在文件fs/minix/dir.c中,文件操作(读/写)在文件fs/minix/file.c中,逻辑链接在文件fs/minix/symlink.c中。
Minix目录的其余部分主要实现以下功能:
bitmap.c管理节点和块的分配和释放;
fsynk.c响应fsync()系统调用,管理直接和间接的块操作;
namei.c负责所有的与名相关的节点操作,如节点的创建和撤销等;
truncate.c进行文件的分段;
如果你读这里不知所云的话,建议你先读一下linux内核一书的第九章之后再读文件系统的源码.
4. 控制台驱动,太杂,不想打字了,看看linux从入门到精通a~z一书中的有关控制台的解释和代码吧.