程序员人生 网站导航

linux0.11学习笔记(1)

栏目:互联网时间:2014-11-07 08:54:03

发布软件包包括内容:

bootimage.Z - 具有美国键盘代码的紧缩启动映像文件;

rootimage.Z - 以1200kB 紧缩的根文件系统映像文件;
linux-0.11.tar.Z- 内核源代码文件;
as86.tar.Z - linux bruce evans'2进制履行文件;
是16 位的汇编程序和装入程序;

INSTALL-0.11 - 更新过的安装信息文件。


不足的地方:不包括有关进程等待队列、虚拟文件系统、TCP/IP网络等方面的1些当前非常重要的代码。


目录:

Linux/目录下:各个文件夹和内核代码的整体Makefile文件的内容。

boot/目录下的3个汇编程序,其中包括磁盘引导程序bootsect.s、32 位运行启动代码程序head.s 和获得BIOS 中参数的setup.s 汇编程序。

init/目录中内核系统的初始化程序main.c。它是内核完成所有初始化工作并进入正常运行的关键地方。

kenel/目录中的所有程序

fs/目录中的文件系统程序

mm/目录中的内存管理程序。要透彻地理解这方面的内容,需要对Intel 80X86 微处理器的保护模式运行方式有足够的理解,包括有较为完全的有关80X86 保护模式运行方式的说明,这些知识基本上是从Intel 80386 http://www.wfuyu.com编程手册(Intel 80386 Programmer's ReferenceManual) 中摘录下来的

include/目录中的所有头文件进行详细说明,基本上对每个定义、每个常量或数据
结构都进行了详细注释。

lib/目录中的所有文件。由于这个版本较低,所以这里的内容其实不是很多,可以很快地看完。

tools/目录下的build.c 程序。这个程序其实不会包括在编译生成的内核映像(image)文件中,它仅用于将内核中的磁盘引导程序块与其它主要内核模块连接成1个完全了内核映像(kernelimage)文件。


在Linux 操作系统上,这些程序包括X 窗口系统、shell 命令解释系统和那些内核编程接口等系统程序


在单内核模式的系统中,操作系统所提供服务的流程为:利用主程序使用指定的参数值履行系统调用指令(int x80),使CPU 从用户态(User Mode)切换到核心态(Kernel Model),然后操作系统根据具体的参数值调用特定的系统调用服务程序,而这些服务程序则根据需要再底层的1些支持函数以完成特定的功能。在完成了利用程序所要求的服务后,操作系统又从核心态切换回用户态,返回到利用程序中继续履行后面的指令。因此概要地讲,单内核模式的内核也可粗略地分为3个层次:调用服务的主程序层、履行系统调用的服务层和支持系统调用的底层函数。


Linux 内核主要由5 个模块构成,它们分别是:进程调度模块、内存管理模块、文件系统模块、进程间通讯模块和网络接口模块。


进程调度模块用来负责控制进程对CPU 资源的使用。所采取的调度策略是各进程能够公平公道地访问CPU,同时保证内核能正时地履行硬件操作。内存管理模块用于确保所有进程能够安全地同享机器主内存区,同时,内存管理模块还支持虚拟内存管理方式,使得Linux 支持进程使用比实际内存空间更多大的内存容量。并可以利用文件系统把暂时不用的内存数据块会被交换到外部存储装备上去,当需要时再交换回来。文件系统模块用于支持对外部装备的驱动和存储。虚拟文件系统模块通过向所有的外部存储装备提供1个通用的文件接口,隐藏了各种硬件装备的不同细节。从而提供并支持与其它操作系统兼容的多种文件系统格式。进程间通讯模块子系统用于支持多种进程间的信息交换方式。网络接口模块提供对多种网络通讯标准的访问并支持许多网络硬件。


linux
├─ boot 系统引导汇编程序
├─ fs 文件系统
├─ include 头文件(*.h)
│ ├─ asm 与CPU 体系结构相干的部份
│ ├─ linux Linux 内核专用部份
│ └─ sys 系统数据结构部份
├─ init 内核初始化程序
├─ kernel 内核进程调度、信号处理、系统调用等程序
│ ├─ blk_drv 块装备驱动程序
│ ├─ chr_drv 字符装备驱动程序
│ └─ math 数学协处理器仿真处理程序
├─ lib 内核库函数
├─ mm 内存管理程序
└─ tools 生成内核Image 文件的工具程序


码目录中含有14 个子目录,总共包括102 个代码文件


bootsect.s 程序是磁盘引导块程序,编译后会驻留在磁盘的第1个扇区中(引导扇区,0 磁道(柱面),0 磁头,第1 个扇区)。在PC 机加电ROM BIOS 自检后,将被BIOS 加载到内存0x7C00 处进行履行。
setup.s 程序主要用于读取机器的硬件配置参数,并把内核模块system 移动到适当的内存位置处。
head.s 程序会被编译连接在system 模块的最前部份,主要进行硬件装备的探测设置和内存管理页面的初始设置工作。


头文件目录中总共有32 个.h 头文件。其中主目录下有13 个,asm 子目录中有4 个,linux 子目录中有10 个,sys 子目录中有5 个


<a.out.h> a.out 头文件,定义了a.out 履行文件格式和1些宏。
<const.h> 常数符号头文件,目前仅定义了i 节点中i_mode 字段的各标志位。
<ctype.h> 字符类型头文件。定义了1些有关字符类型判断和转换的宏。
<errno.h> 毛病号头文件。包括系统中各种出错号。(Linus 从minix 中引进的)。
<fcntl.h> 文件控制头文件。用于文件及其描写符的操作控制常数符号的定义。
<signal.h> 信号头文件。定义信号符号常量,信号结构和信号操作函数原型。
<stdarg.h> 标准参数头文件。以宏的情势定义变量参数列表。主要说明了-个类型(va_list)和
3个宏(va_start, va_arg 和va_end),用于vsprintf、vprintf、vfprintf 函数。
<stddef.h> 标准定义头文件。定义了NULL, offsetof(TYPE, MEMBER)。
<string.h> 字符串头文件。主要定义了1些有关字符串操作的嵌入函数。
<termios.h> 终端输入输出函数头文件。主要定义控制异步通讯口的终端接口。
<time.h> 时间类型头文件。其中最主要定义了tm 结构和1些有关时间的函数原形。
<unistd.h> Linux 标准头文件。定义了各种符号常数和类型,并申明了各种函数。如定义了
__LIBRARY__,则还包括系统调用号和内嵌汇编_syscall0()等。
<utime.h> 用户时间头文件。定义了访问和修改时间结构和utime()原型。


<asm/io.h> io 头文件。以宏的嵌入汇编程序情势定义对io 端口操作的函数。
<asm/memory.h> 内存拷贝头文件。含有memcpy()嵌入式汇编宏函数。
<asm/segment.h> 段操作头文件。定义了有关段寄存器操作的嵌入式汇编函数。

<asm/system.h> 系统头文件。定义了设置或修改描写符/中断门等的嵌入式汇编宏。


<linux/config.h> 内核配置头文件。定义键盘语言和硬盘类型(HD_TYPE)可选项。
<linux/fdreg.h> 软驱头文件。含有软盘控制器参数的1些定义。
<linux/fs.h> 文件系统头文件。定义文件表结构(file,buffer_head,m_inode 等)。
<linux/hdreg.h> 硬盘参数头文件。定义访问硬盘寄存器端口,状态码,分区表等信息。
<linux/head.h> head 头文件,定义了段描写符的简单结构,和几个选择符常量。
<linux/kernel.h> 内核头文件。含有1些内核经常使用函数的原形定义。
<linux/mm.h> 内存管理头文件。含有页面大小定义和1些页面释放函数原型。
<linux/sched.h> 调度程序头文件,定义了任务结构task_struct、初始任务0 的数据,还有1些有关描写符参数设置和获得的嵌入式汇编函数宏语句。
<linux/sys.h> 系统调用头文件。含有72 个系统调用C 函数处理程序,以'sys_'开头。
<linux/tty.h> tty 头文件,定义了有关tty_io,串行通讯方面的参数、常数。


<sys/stat.h> 文件状态头文件。含有文件或文件系统状态结构stat{}和常量。
<sys/times.h> 定义了进程中运行时间结构tms 和times()函数原型。
<sys/types.h> 类型头文件。定义了基本的系统数据类型。
<sys/utsname.h> 系统名称结构头文件。
<sys/wait.h> 等待调用头文件。定义系统调用wait()核waitpid()及相干常数符号。


件main.c用于履行内核所有的初始化工作,然后移到用户模式创建新进程,并在控制台装备上运行shell 程序。


exit.c 程序主要包括用于处理进程终止的系统调用。包括进程释放、会话(进程组)终止和程序退
出处理函数和杀死进程、终止进程、挂起进程等系统调用函数。
fork.c 程序给出了sys_fork()系统调用中使用了两个C 语言函数:find_empty_process()和
copy_process()。
mktime.c 程序包括1个内核使用的时间函数mktime(),用于计算从1970 年1 月1 日0 时起到开机
当日的秒数,作为开机秒时间。仅在init/main.c 中被调用1次。
panic.程序包括1个显示内核出错信息并停机的函数panic()。
printk.c 程序包括1个内核专用信息显示函数printk()。
sched.c 程序中包括有关调度的基本函数(sleep_on、wakeup、schedule 等)和1些简单的系统调
用函数。另外还有几个与定时相干的软盘操作函数。
signal.c 程序中包括了有关信号处理的4 个系统调用和1个在对应的中断处理程序中处理信号的
函数do_signal()。
sys.c 程序包括很多系统调用函数,其中有些还没有实现。
system_call.s 程序实现了linux 系统调用(int 0x80)的接口处理进程,实际的处理进程则包括
在各系统调用相应的C 语言处理函数中,这些处理函数散布在全部linux 内核代码中。
vsprintf.c 程序实现了现在已归入标准库函数中的字符串格式化函数。


内核的编译:

1,修改makefile

a. 将gas =>as, gld=>ld。现在gas 和gld 已直接改名称为as 和ld 了。
b. as(原gas)已不用-c 选项,所以要将Makefile, 因此需要去掉其-c 编译选项。在内核主目录Linux下makefile 文件中,是在34 行上。
c. 去掉gcc 的编译标志选项:-fcombine-regs、-mstring-insns 和所有子目录中Makefile 中的这两个选项。在94 年的gcc 手册中就已找不到-fcombine-regs 选项,而-string-insns 是Linus 自己对gcc的修改增加的选项,所以你我的gcc 中肯定不包括这个优化选项。
d. 在gcc 的编译标志选项中,增加-m386 选项。这样在RedHat 9 下编译出的内核映像文件中就不含有80486 及以上CPU 的指令,因此该内核就能够运行在80386 机器上

2,as86 编译程序不能辨认c 语言的注释语句,因此需要使用!注释掉boot/bootsect.s 文件中的C 注释语句。

3,原来align 后面带的数值是指对起内存位置的幂次值,而现在则需要直接给出对起的整数地址值。因此,原来的语句:

.align 3
需要修改成(2 的3 次幂值2^3=8):
.align 8

4,由于对as 的不断改进,目前其自动化程度愈来愈高,因此已不需要人工指定1个变量需使用的CPU 寄存器。因此内核代码中的__asm__("ax")需要全部去掉。例如s/bitmap.c 文件的第20 行、26 行上,fs/namei.c 文件的第65 行上等。在嵌入汇编代码中,另外还需要去掉所有对寄存器内容无效的声明。例如include/string.h 中第84 行:
:"si","di","ax","cx");

需要修改成:

: );


(32)

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐