- 第5章 Linux内核体系结构
- 5.9 Linux 0.11采用的文件系统
- 5.10 Linux内核源代码的目录结构
- 5.10.1 内核主目录linux
- 5.10.2 引导启动程序目录 boot
- 5.10.3 文件系统目录 fs
- 5.10.4 头文件主目录include
- 5.10.5 内核初始化程序目录init
- 5.10.6 内核程序主目录kernel
- 5.10.7 内核库函数目录lib
- 5.10.8 内存管理程序目录 mm
- 5.10.9 编译内核工具程序目录tools
- 5.11 内核系统与应用程序的关系
- 5.12 linux/Makefile文件
- 5.12.1 功能描述
- 5.12.2 代码注释
- 5.13 本章小结
- etc/ 目录主要含有一些系统配置文件;
- dev/ 含有设备特殊文件,用于使用文件操作语句操作设备;
- bin/ 存放系统执行程序。如sh、mkfs、fdisk等
- usr/ 存放函数库、手册和其他一些文件
- usr/bin 存放用户常用的普通指令
- var/ 用于存放系统运行时可变的数据或者是日志等信息
文件系统举例:
软盘启动的Linux 0.11系统中,bootimage是引导启动文件,rootimage用于提供根文件系统。
Linux0.11是单内核模式系统,文件之间关系非常紧密。
14个子目录,102个代码文件。
14个子目录,1个Makefile文件。
5.10.2 引导启动程序目录 boot包括3个汇编语言文件,最先被编译。
Linux0.11 内核文件系统采用了1.0版本的MINIX文件系统。fs/目录是文件系统实现程序的目录,包括17个C语言程序,其关系如图所示。
可四个部分:
- 高速缓冲管理
- 低层文件操作
- 文件数据访问
- 文件高层函数
所有对文件系统中数据的访问,都需要首先读取到高速缓冲区中。
各个文件的作用:
-
file_table.c 目前只定义了一个文件句柄(描述符)结构数组
-
ioctl.c 引用kernel/chr_drv/tty.c中的函数,实现字符设备的io控制功能
-
exec.c 包含一个执行程序函数do_execve(),是所有exec()函数簇中的主要函数。
-
fcntl.c 程序用于实现文件i/o控制的系统调用函数。
-
read_write.c 程序用于实现文件读/写和定位三个系统调用函数。
-
stat.c 程序中实现了两个获取文件状态的系统调用函数
-
open.c 程序主要包含实现修改文件属性和创建与关闭文件的调用函数。
-
char_dev.c 主要包含字符设备读写函数rw_char()。
-
pipe.c 程序中包含管道读写函数和创建管道的系统调用
-
file_dev.c 程序中包含基于i节点和描述符结构的文件读写函数。
-
namei.c 程序主要包括文件系统中目录名和文件名的操作函数和系统调用函数。
-
blocl_dev.c 程序包含块数据读和写函数
-
inode.c 程序中包含针对文件系统i节点操作的函数
-
truncate.c 程序用于在删除文件时释放文件所占用的设备数据空间。
-
bitmap.c 程序用于处理文件系统中i节点和逻辑数据块的位图
-
super.c 程序中包含对文件系统超级块的处理函数
-
buffer.c 程序主要用于对内存高速缓冲区进行处理
-
虚框中的ll_rw_block是块设备的底层读函数。在kernel/blk_drv/ll_rw_block.c中
头文件功能可以直接在这里查找。
5.10.5 内核初始化程序目录init 5.10.6 内核程序主目录kernelLinux/kernel目录中共包含12个代码文件和一个Makefile文件,还包括三个子目录。
块设备驱动程序子目录kernel/blk_drv
用户是通过文件系统来访问设备的,设备驱动程序为文件系统实现了调用接口。用户进程和块设备之间采用高速缓冲机制。
字符设备驱动程序子目录kernel/chr_drv
实现了对串行端口rs-232、串行终端、键盘和控制台终端设备的驱动。
这些都不是太能看懂,后面慢慢理解。
协处理器仿真和操作程序子目录kernel/math
目前只有一个C程序math_emulate.c。
与普通用户程序不同,内核代码不能使用标准C函数库及其他一些函数库。主要因为C函数库很大。因此在内核源代码中专门有一个lib/目录提供内核需要用到的一些函数。内核函数库与静态库的实现方法完全一样。
5.10.8 内存管理程序目录 mm 5.10.9 编译内核工具程序目录tools 5.11 内核系统与应用程序的关系在Linux系统中,内核为用户提供了两方面的支持。
- 系统调用接口,也即中断调用 int0x80
- 通过开发环境库函数或内核库函数与内核进行信息交流。
系统调用主要给系统软件编程或用于库函数的实现,一般用户开发通过调用如libc等库函数来使用内核资源。这些库或资源通常被称为应用编程接口(API)。
在UNIX类操作系统中,最为普遍使用的是基于POSIX标准的API接口。
应用程序不应该直接使用系统调用,这样系统的移植性就不好了。
LSB(Linux Standard Base)Linux标准库
Linux在线手册第2部分是系统调用。
Linux在线手册的第3部分是系统提供的库函数。
Makefile文件中‘#’开头的是注释行,‘=’赋值语句定义了一些参数或命令的缩写。
原始Makefile代码
#
# if you want the ram-disk device, define this to be the
# size in blocks.
#
RAMDISK = #-DRAMDISK=512
AS86 =as86 -0 -a
LD86 =ld86 -0
AS =gas
LD =gld
LDFLAGS =-s -x -M
CC =gcc $(RAMDISK)
CFLAGS =-Wall -O -fstrength-reduce -fomit-frame-pointer
-fcombine-regs -mstring-insns
CPP =cpp -nostdinc -Iinclude
#
# ROOT_DEV specifies the default root-device when making the image.
# This can be either FLOPPY, /dev/xxxx or empty, in which case the
# default of /dev/hd6 is used by 'build'.
#
ROOT_DEV=/dev/hd6
ARCHIVES=kernel/kernel.o mm/mm.o fs/fs.o
DRIVERS =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a
MATH =kernel/math/math.a
LIBS =lib/lib.a
.c.s:
$(CC) $(CFLAGS)
-nostdinc -Iinclude -S -o $*.s $<
.s.o:
$(AS) -c -o $*.o $<
.c.o:
$(CC) $(CFLAGS)
-nostdinc -Iinclude -c -o $*.o $<
all: Image
Image: boot/bootsect boot/setup tools/system tools/build
tools/build boot/bootsect boot/setup tools/system $(ROOT_DEV) > Image
sync
disk: Image
dd bs=8192 if=Image of=/dev/PS0
tools/build: tools/build.c
$(CC) $(CFLAGS)
-o tools/build tools/build.c
boot/head.o: boot/head.s
tools/system: boot/head.o init/main.o
$(ARCHIVES) $(DRIVERS) $(MATH) $(LIBS)
$(LD) $(LDFLAGS) boot/head.o init/main.o
$(ARCHIVES)
$(DRIVERS)
$(MATH)
$(LIBS)
-o tools/system > System.map
kernel/math/math.a:
(cd kernel/math; make)
kernel/blk_drv/blk_drv.a:
(cd kernel/blk_drv; make)
kernel/chr_drv/chr_drv.a:
(cd kernel/chr_drv; make)
kernel/kernel.o:
(cd kernel; make)
mm/mm.o:
(cd mm; make)
fs/fs.o:
(cd fs; make)
lib/lib.a:
(cd lib; make)
boot/setup: boot/setup.s
$(AS86) -o boot/setup.o boot/setup.s
$(LD86) -s -o boot/setup boot/setup.o
boot/bootsect: boot/bootsect.s
$(AS86) -o boot/bootsect.o boot/bootsect.s
$(LD86) -s -o boot/bootsect boot/bootsect.o
tmp.s: boot/bootsect.s tools/system
(echo -n "SYSSIZE = (";ls -l tools/system | grep system
| cut -c25-31 | tr ' 12' ' '; echo "+ 15 ) / 16") > tmp.s
cat boot/bootsect.s >> tmp.s
clean:
rm -f Image System.map tmp_make core boot/bootsect boot/setup
rm -f init/*.o tools/system tools/build boot/*.o
(cd mm;make clean)
(cd fs;make clean)
(cd kernel;make clean)
(cd lib;make clean)
backup: clean
(cd .. ; tar cf - linux | compress - > backup.Z)
sync
dep:
sed '/### Dependencies/q' < Makefile > tmp_make
(for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done) >> tmp_make
cp tmp_make Makefile
(cd fs; make dep)
(cd kernel; make dep)
(cd mm; make dep)
### Dependencies:
init/main.o : init/main.c include/unistd.h include/sys/stat.h
include/sys/types.h include/sys/times.h include/sys/utsname.h
include/utime.h include/time.h include/linux/tty.h include/termios.h
include/linux/sched.h include/linux/head.h include/linux/fs.h
include/linux/mm.h include/signal.h include/asm/system.h include/asm/io.h
include/stddef.h include/stdarg.h include/fcntl.h
linus在编写linux0.11的时候在自己电脑上应该是运行的unix系统。
sed:参考Sed Command in Linux/Unix with examples
sed ‘/### Dependencies/q’ < Makefile > tmp_make 中的q表示停止,大概意思是在Makefile文件中搜索一行‘### Dependencies:’然后停止,然后把这一行之后的所有的行删除。然后把删除后的Makefile写入到tmp_make中。
具体的注释可以看书,部分可以参考第4章 80x86保护模式及其编程(3)——一个简单的多任务内核实例中对makefile的注释。这段很多还是没有太清楚,后面慢慢学习Makefile,gcc和linux指令。



