我来我网
https://5come5.cn
您尚未
登录
注册
|
菠菜
|
软件站
|
音乐站
|
邮箱1
|
邮箱2
|
风格选择
|
更多 »
vista
鍙よ壊涔﹂
card
wind
绮夌孩濂抽儙
帮助
统计与排行
无图版
我来我网·5come5 Forum
»
电脑技术
»
Linux专区
»
<<Linux0.11内核完全注释>>心得与相关资料[申精]
«
1
2
3
4
»
Pages: ( 2/4 total )
交 易
投 票
本页主题:
<<Linux0.11内核完全注释>>心得与相关资料[申精]
显示签名
|
打印
|
加为IE收藏
|
收藏主题
|
上一主题
|
下一主题
侨光
∷
性别:
∷
状态:
∷
等级:
品行端正
∷
发贴:
308
∷
威望:
0
∷
浮云:
1123
∷
在线等级:
∷
注册时间: 2005-10-03
∷
最后登陆: 2011-05-19
【
复制此帖地址
只看此人回复
】
5come5帮你背单词 [
payment
/'peim
ə
nt/
n. 支付,支付的款项
]
一些关于Linux的网上文章:
附件:
文章.part1.rar
(977 K) 下载次数:20
附件:
文章.part2.rar
(666 K) 下载次数:18
Posted: 2007-03-02 15:58 |
[15 楼]
侨光
∷
性别:
∷
状态:
∷
等级:
品行端正
∷
发贴:
308
∷
威望:
0
∷
浮云:
1123
∷
在线等级:
∷
注册时间: 2005-10-03
∷
最后登陆: 2011-05-19
【
复制此帖地址
只看此人回复
】
5come5帮你背单词 [
pumpkin
/'p
Λ
mpkin/
n. 南瓜
]
网上一些人的心得
附件:
Work.rar
(35 K) 下载次数:23
Posted: 2007-03-02 15:59 |
[16 楼]
侨光
∷
性别:
∷
状态:
∷
等级:
品行端正
∷
发贴:
308
∷
威望:
0
∷
浮云:
1123
∷
在线等级:
∷
注册时间: 2005-10-03
∷
最后登陆: 2011-05-19
【
复制此帖地址
只看此人回复
】
5come5帮你背单词 [
disorder
/dis'o:d
ə
/
n. 混乱,动乱,(身心机能的)失调
]
假期写的一些前六章的心得
附件:
读核札记.rar
(168 K) 下载次数:19
Posted: 2007-03-02 16:00 |
[17 楼]
侨光
∷
性别:
∷
状态:
∷
等级:
品行端正
∷
发贴:
308
∷
威望:
0
∷
浮云:
1123
∷
在线等级:
∷
注册时间: 2005-10-03
∷
最后登陆: 2011-05-19
【
复制此帖地址
只看此人回复
】
5come5帮你背单词 [
each
/i:t
∫
/
a. 各自的,每;pron. 第个,各自
]
“读核札记”
―――<<Linux内核0.11完全剖析>>
――――侨光
第一章 概述 1
第二章 微机组成结构 2
第三章 内核编程语言 3
第四章 80x86保护模式与编程 4
第五章 Linux内核体系结构 5
第六章 引导启动过程 12
第一章 概述
对Linux进行了概述,重要的就是Linux目录下的几个文件夹的关系和作用要弄清楚:
“Boot/” :里面包括磁盘引导程序bootsect.s,获取BIOS中参数的setup.s汇编程序和32位运行启动代码程序head.s。这三个汇编程序完成了把内核从块设备上引导加载到内存的工作,并对系统配置参数进行探测,完成了进入32位保护模式运行之前的所有工作,为内核系统执行进一步的初始化工作做好了准备。
“init/”:目录中内核系统的初始化程序main.c。它是内核完成所有初始化工作并进入正常运行的关键地方。在完成了系统所有的初始化工作后,创建了用于shell 的进程。
“kenel/”:目录中的所有程序。其中最重要的部分是进程调度函数schedule()、sleep_on()函数和有关系统调用的程序。
kernel/dev_blk/目录中的块设备程序进行了注释说明。该章主要含有硬盘、软盘等块设备的驱动程序,主要与文件系统和高速缓冲区打交道。
kernel/dev_chr/目录中的字符设备驱动程序进行注释说明。
kernel/math/目录中的数学协处理器的仿真程序。
“fs/”:目录中的文件系统程序。
“mm/”:目录中的内存管理程序。
“include/”:目录中的所有头文件。
“lib/”:目录中的所有文件。这些库函数文件主要向编译系统等系统程序提供了接口函数。
“tools/”:目录下的build.c 程序。这个程序并不会包括在编译生成的内核映像(image)文件中,它仅用于将内核中的磁盘引导程序块与其它主要内核模块连接成一个完整了内核映像(kernel image)文件。
Posted: 2007-03-02 16:02 |
[18 楼]
侨光
∷
性别:
∷
状态:
∷
等级:
品行端正
∷
发贴:
308
∷
威望:
0
∷
浮云:
1123
∷
在线等级:
∷
注册时间: 2005-10-03
∷
最后登陆: 2011-05-19
【
复制此帖地址
只看此人回复
】
5come5帮你背单词 [
housewife
/'hauswaif/
n. 家庭主妇
]
第二章 微机组成结构
介绍了微机的组成结构,建议先学习微机原理。
1 南北桥的作用:北桥用作CPU与内存模块和AGP视频控制器之间的传输接口,这些接口具有很高的传输速率。北桥芯片还起着存储器控制作用,因此Intel把记芯片标号为MCH(Memory Controller Hub)芯片。南桥用来管理低,中带的组件,例如,PCI总路线,IDE硬盘掊,USB端口等,因此南桥的名称为ICH(I/O Controller Hub),之所以用“南,北”桥来分别统称这两个芯片,是由于在Intel公司公布的典型PC主板上,它们分别位于主要主板的下端和上端,并起着与CPU进行通道桥接的作用。
2 主存储器:内存低地址1MB存放系统启动数据,如“ROM BIOS映射区”(大容量内存为了兼容,系统1MB以下物理内存合用分配上仍然保持与原来的PC机基本一致,人是原来系统ROM中的基本输出程序BIOS一直处于CPU能寻址的内存最高端位置处,而BIOS原来所在的位置将在计算机开机初始化时被用作BIOS的影子(shadow)区域,即BIOS代码仍然会衩复制到这个区域中),“其他卡上的ROM BIOS”,“显示缓冲区”,“中断向量表”,“BIOS数据区”等。
3 基本输入/输出程序BIOS:存放在ROM中的系统BIOS程序主要用于计算机开机时执行系统各部分的自检,建立起操作系统需要使用的各种配置表,例如中断向量表,硬盘参数表。并且把处理器和系统其余部分初始化到一个已知状态,而且还为DOS等操作系统提供硬件设备接口服务。
当计算机系统上电开机或者按了机箱上的复位按钮时,CPU会自动把代码段寄存器CS设置为0xF000,其段基址设置为0xFFFF0000,段长度设置为64KB。而IP被设置为0xFFF0,因此些时CPU(代码指针指向0xFFFFFFF0处,即4GB窨最后一个64KB的最后16字节处)。这里正是系统ROM BIOS存放的位置。并且BIOS会在这里存放一条跳转指令JMP,跳转到BIOS代码上64KB范围内的某一条指令开始执行。由于目前PC/AT微机中BIOS容量大多有1MB到2MB,并存储在闪存(Flash Memory)ROM中,因此为了能够执行或访问BIOS程序中超过64KB范围并且又远离0~1MB地址空间中的其他BIOS代码或数据,BIOS程序会首先使用一种称为32位大模式(Big mode)的技术把数据段寄存器的访问设置成4GB(而非原来的64KB),这样就可以在0到4GB范围内执行和操作数据。此后,BIOS在执行了一系列硬件检测与初始化操作之后,就会把与原来PC机兼容的64KB BIOS代码和数据复制到内存低端1MB末端的64KB处,然后跳转到这个地方并且让CPU进入真正的实地址模式下工作。最后BIOS就会从硬盘或其他块设备上把操作系统引导程序加载到内存0x7c00处,并跳转到这个地方继续执行引导程序。
4. CMOS存储器:在PC/AT机中,除需要使用内存和ROM BIOS以外,还使用只有很少存储容量的(只有64B或128B)CMOS(Complementary Metal Oxide Semiconductor,互䃼金属氧化物半导体)存储器来存放计算机的实时时钟信息和系统硬件配置信息。这部分内存通常和实时时钟芯片(Real Time Chip)做在一块集成块中。CMOS内存的地址空间在基本内存地址空间之外,需要使用I/O指令来访问。
Posted: 2007-03-02 16:04 |
[19 楼]
侨光
∷
性别:
∷
状态:
∷
等级:
品行端正
∷
发贴:
308
∷
威望:
0
∷
浮云:
1123
∷
在线等级:
∷
注册时间: 2005-10-03
∷
最后登陆: 2011-05-19
【
复制此帖地址
只看此人回复
】
5come5帮你背单词 [
brain
/brein/
n. 大脑,心智,智力
]
第三章 内核编程语言
这章开始是讲as的语法,后面是C语言内嵌的汇编,和一些目标文件格式。
内嵌函数:inline,可以让gcc把函数的代码集成到调用该函数的代码中去。当一个函数定义中使用inline与static关键词的组合,如果所有对该内嵌的调用都被替换而集成在调用者代码中,且程序中没有引用过该内嵌函数的地址,岕该内嵌函数自身的汇编代码就不会被引用过,gcc不会为该内嵌函数自身生成实际汇编代码!如果在定义一个函数时还指定了inline和extern关键词,那么该函数公用于内嵌集成,并在任何情况下都不会单独产生该函数自身的汇编代码,即使明确引用了该函数的地址也不会产生。
FAQ:在”include/string.h”t和”lib/strings.c”有什么关系呢?为什么要用多一份copy?“.h”和“.c”文件各是用来干嘛,联系与区别。
Answer:关键词inline和extern组合在一起的作用几乎类同一个宏定义。使用这种组合的方式是把带有组合关键词的一个函数定义放在头文件中,并且把不含关键词的另一个同样 放在一个库文件中。此时头文件中的会让绝大多数对该函数的调用被替换嵌入。如果还有没有被替换的对该函数的调用,那么就会使用(引用)库中的拷贝。Linux0.1x内核源代码中文件include/string.h,lib/string.c就是这种使用方式的一个例子。在对应的内核函数库目录中,lib/strings.c文件把关键词inline和extern都定义为空。实际是对string.h文件所有分类函数的一个拷贝(#include<string.h>).
“.h”是头文件。“.c”是函数文件。
Posted: 2007-03-02 16:08 |
[20 楼]
侨光
∷
性别:
∷
状态:
∷
等级:
品行端正
∷
发贴:
308
∷
威望:
0
∷
浮云:
1123
∷
在线等级:
∷
注册时间: 2005-10-03
∷
最后登陆: 2011-05-19
【
复制此帖地址
只看此人回复
】
5come5帮你背单词 [
flow
/fl
ə
u/
vi. (液体)流动,涌出,飘动;vt. 淹没;n. 流,水流,气流,流量
]
80x86保护模式与编程[size=3][/size]
这章讲了80X86的内存管理,保护模式,中断管理,任务管理等。
1. 内存管理
在内存管理中,有三张表是很重要的:“GDT(全局描述符表),LDT(局部描述符表),IDT(中断向量表)”,它们对应的寄存器分别为GDTR,LDTR,IDTR。它们的主要作用是通过选择符,找到相应的描述符,再从该描述符中找到段或页的基地址与相应属性,再加上逻辑地址中的偏移量,就可以实现寻址的功能(包括段寻址,页寻址大概原理就是这样,中断向量是根据“中断向量*8”实现――这个是386的中断向量表实现方式)。
关于内存管理,强烈推荐仔细阅读4.2-4.5“保护模式内存管理”,上面真的很经典地写出了内存地址的寻址与特权保护等相关内容,这点正是我们学微机原理时很模糊的地方!
对于保护机制,处理器分为0,1,2,3四种特权,其中0特权最高,3最低。在页表机制中“0,1,2”归类为“超级用户级”,而特权3被作为“普通用户级”。特权级高的代码可以访问低等级代码,反之不行。为了处理低等级访问高等级代码的问题,引入了“gate”的概念,其中共有4种gate描述符:“调用gate”,“陷阱gate”,“中断gate”,“任务gate”。
在不同特权级切换时,有一点要注意的,就是会开辟新的堆栈。在同一等级的代码调用时,被调用者不用把调用者的堆栈信息保存(即不用把ESP,EIP压栈),它们共用同一堆栈段。但不同等级的代码调用时,被调用者会把调用者的堆栈信息保存,而开辟新的堆栈。这点我就不是很明白了。是否每一等级特权都有自身的一个堆栈段?
这里说一下中断gate与陷阱gate的区别:它们惟一的区别在于处理器操作EFLAGS寄存器IF标志的方法。当通过中断gate访问一个导演或中断处理过程理,处理器会复位IF标志以防止其他中断一无所有当前中断处理过程(IF=0)。随后的IRET指令则会保存在堆栈上的内容恢复EFLAGS寄存器的IF标志。而通过陷阱gate访问处理过程并不会影响IF标志。
FAQ:何为一致性代码段为什么不同特权级任务切换需开辟新堆栈,同一特权级的不用?是否每一特权级有自向唯 一的堆栈段?
2 任务管理
任务(task)是处理器可以分配调度,执行和挂起的一个工作单元。一个任务由两部分构成:任务执行空间和任务状态段TSS(Task-state segment)。一个任务使用指向其TSS段选择符来指定。当一个任务被加载进处理器中执行时,那么该任务的段选择符,基地址,段限长以及TSS段描述符属性就会被加载进任务寄存器TR(Task Register)中。如果使用了分页机制,那么任务使用的页目录表基地址就会被加载进控制寄存器CR3中。
当进行任务切换时,会保存当前任务的状态到TSS里面,TSS中的格式基本上把当前处理器中的信息保守起来了。包括:通用寄存器字段 “EAX,ECX,EDXEBXESP,EBP,ESI,EDI”寄存器的内容;段选择符字段“ES,CS,SS,DS,FS,和GS寄存器”的内容 ;标志寄存器EFLAGS字段;“前一任务链接(TSS选择符)”;指令指针EIP字段;LDT段选择符字段;CR3控制寄存器字段;高度陷阱T标志字段;I/O位图基地址字段等。见书图4-32.
当任务切换时,首先,根据选择符找到新的TSS描述符,并保存当前TSS状态
信息到原TSS;然后,根据新TSS描述符找到新的TSS段,并把TSS中各个字段信息加载到相应的寄存器(LDTR,EIP等),并对相关字位置复位(如忙标志B等)。其中最重要是把新任务TSS的段选择符和描述符加载任务寄存器TR。设置CR0寄存器的TS标志。
当任务嵌套时,NT标志位表示当前任务是否嵌套于前一个任务中,并通过任务链返回前一个任务。
关于多任务空间共享问题。有三种方法:一,通过使用GDT中的段描述符。二,通过共享的LDT。三,通过映射到线性地址空间公共区域的不同LDT中的段描述符。如果线性空间地址空间中的这个公共区域对每个任务都映射到物理地址空间的相同区域,那么这些段描述符就允许任务共享这些段。其中,第三种方法最好,通过描述符指向同一个线性共享空间,这样就避免了前两种方法中LDT中的其他描述符被访问的可能性。增加了安全性。
Posted: 2007-03-02 16:09 |
[21 楼]
侨光
∷
性别:
∷
状态:
∷
等级:
品行端正
∷
发贴:
308
∷
威望:
0
∷
浮云:
1123
∷
在线等级:
∷
注册时间: 2005-10-03
∷
最后登陆: 2011-05-19
【
复制此帖地址
只看此人回复
】
5come5帮你背单词 [
intervene
/int
ə
'vi:n/
vi. 干预,干涉,介入
]
Linux内核体系结构
Linux 内核对内存的使用方法:
linux使用了分页机制,大大增加了进程可以使用的内存空间,在linux中“4096 字节”为一页,总可以使用的线性地址有4G,每个进程所使用的线性空间为64M。在“include/linux/sched.h”中“task_struct”中的” unsigned long start_code, end_code, end_data, brk, start_stack;”定义了了进程代码段,数据段,堆栈段所在的线性地址。通过分页要机制,可以找到相应的物理地址。在这里面,任务使用的页目录表基地址就会被加载进控制寄存器CR3中。而任务寄存器TR中存放着16位的段选择符以及当前任务TSS段的整个描述符。原文中的描述写得很详细,推荐好好看一下。
以下是原文:
“在linux 0.11 内核中,为了有效地使用系统的物理内存,内存被划分成几个功能区域,见下图:
其中,linux 内核程序占据在物理内存的开始部分,接下来是用于供硬盘或软盘等块设备使用的高速缓冲区部分。当一个进程需要读取块设备中的数据时,系统会首先将数据读到高速缓冲区中;当有数据需要写到块设备上去时,系统也是先将数据放到高速缓冲区中,然后由块设备驱动程序写到设备上。最后部分是供所有程序可以随时申请使用的主内存区部分。内核程序在使用主内存区时,也同样要首先向内核的内存管理模块提出申请,在申请成功后方能使用。对于含有RAM 虚拟盘的系统,主内存区头部还要划去一部分,共虚拟盘存放数据。
由于计算机系统中所含的实际物理内存容量是有限制的。为了能有效地使用这些物理内存,Linux 采用了Intel CPU 的内存分页管理机制,使用虚拟线性地址与实际物理内存地址映射的方法让所有同时执行的程序共同使用有限的内存。内存分页管理的基本原理是将整个主内存区域划分成4096 字节为一页的内存页面。程序申请使用内存时,就以内存页为单位进行分配。
在使用这种内存分页管理方法时,每个执行中的进程(任务)可以使用比实际内存容量大得多的线性地址空间。对于Intel 80386 系统,其CPU 可以提供多达4G 的线性地址空间。对于linux 0.11 内核,系统设置全局描述符表GDT 中的段描述符项数最大为256,其中2 项空闲、2 项系统使用,每个进程使用两项。因此,此时系统可以最多容纳(256-4)/2 + 1=127 个任务,并且虚拟地址范围是 ((256-4)/2)* 64MB 约等于8G。但0.11 内核中人工定义最大任务数NR_TASKS = 64 个,每个进程虚拟地址(或线性地址)范围是64M,并且各个进程的虚拟地址起始位置是(任务号-1)*64MB。因此所使用的虚拟地址空间范围是64MB*64 =4G,见图2.7 所示。4G 正好与CPU 的线性地址空间范围或物理地址空间范围相同.
linux 0.11 中,在进行地址映射时,我们需要分清3 种地址之间的变换:a. 进程虚拟地址,是从虚拟地址0 开始计,最大64M;b. CPU 的线性地址空间(0--4G);c. 实际物理内存地址。进程的虚拟地址需要首先通过其局部段描述符变换为CPU 整个线性地址空间中的地址,然后再使用页目录表PDT(一级页表)和页表PT(二级页表)映射到实际物理地址页上。因此两种变换不能混淆。为了使用实际物理内存,每个进程的线性地址通过二级内存页表动态地映射到主内存区域的不同内存页上。因此每个进程最大可用的虚拟内存空间是64MB。每个进程的逻辑地址通过加上任务号*64M,即可转换为线性地址。”
根目录下的Makefile文件:
Makefile 文件相当于程序编译过程中的批处理文件。是工具程序make 运行时的输入数据文件。只要在含有Makefile 的当前目录中键入make 命令,它就会依据Makefile 文件中的设置对源程序或目标代码文件进行编译、链节或进行安装等活动。
Make 的执行过程分为两个不同的阶段。在第一个阶段,它读取所有的makefile 文件以及包含的makefile文件等,记录所有的变量及其值、隐式的或显式的规则,并构造出所有目标对象及其先决条件的一幅全景图。在第二阶段期间,make 就使用这些内部结构来确定哪个目标对象需要被重建,并且使用相应的规则来操作。
根目录下的Makefile 文件的主要作用是指示make 程序最终使用[屏蔽]编译连接成的tools/目录中的build 执行程序将所有内核编译代码连接和合并成一个可运行的内核映像文件image。具体是对boot/中的bootsect.s、setup.s 使用8086 汇编器进行编译,分别生成各自的执行模块。再对源代码中的其它所有程序使用GNU 的编译器gcc/gas 进行编译,并连接成模块system。再用build 工具将这三块组合成一个内核映象文件image.基本编译连接/组合结构如下图所示。
图5.2 内核编译连接/组合结构
(下面是Makefile代码中的文件关系:)
linux/Makefile 文件
Image: boot/bootsect boot/setup tools/system tools/build
# 说明目标(Image 文件)是由
# 分号后面的4 个元素产生,分别是boot/目录中的bootsect 和
# setup 文件、tools/目录中的system 和build 文件。
tools/build boot/bootsect boot/setup tools/system $(ROOT_DEV) > Image
sync # 这两行是执行的命令。第一行表示使用tools 目录下的build 工具
# 程序(下面会说明如何生成)将bootsect、setup 和system 文件
# 以$(ROOT_DEV)为根文件系统设备组装成内核映像文件Image。
# 第二行的sync 同步命令是迫使缓冲块数据立即写盘并更新超级块。
disk: Image # 表示disk 这个目标要由Image 产生。
dd bs=8192 if=Image of=/dev/PS0 # dd 为UNIX 标准命令:复制一个文件,根据选项
# 进行转换和格式化。bs=表示一次读/写的字节数。
# if=表示输入的文件,of=表示输出到的文件。
# 这里/dev/PS0 是指第一个软盘驱动器(设备文件)。
(在此产生system模块:)
tools/build: tools/build.c # 由tools 目录下的build.c 程序生成执行程序build。
$(CC) $(CFLAGS) \
-o tools/build tools/build.c # 编译生成执行程序build 的命令。
boot/head.o: boot/head.s # 利用上面给出的.s.o 规则生成head.o 目标文件。
tools/system: boot/head.o init/main.o \
$(ARCHIVES) $(DRIVERS) $(MATH) $(LIBS) # 表示tools 目录中的system 文件
# 要由分号右边所列的元素生成。
$(LD) $(LDFLAGS) boot/head.o init/main.o \
$(ARCHIVES) \
$(DRIVERS) \
$(MATH) \
$(LIBS) \
-o tools/system > System.map # 生成system 的命令。最后的 > System.map 表示
# gld 需要将连接映象重定向存放在System.map 文件中。
# 关于System.map 文件的用途:System.map 文件用于存放内核符号表信息。符号表是所有符号及其对应地址的一个列表。
(此处产生各块块的.o目标文件:)
kernel/math/math.a: # 数学协处理函数文件math.a 由下一行上的命令实现。
(cd kernel/math; make) # 进入kernel/math/目录;运行make 工具程序。
# 下面从66--82 行的含义与此处的类似。
kernel/blk_drv/blk_drv.a: # 块设备函数文件blk_drv.a
(cd kernel/blk_drv; make)
kernel/chr_drv/chr_drv.a: # 字符设备函数文件chr_drv.a
(cd kernel/chr_drv; make)
kernel/kernel.o: # 内核目标模块kernel.o
(cd kernel; make)
mm/mm.o: # 内存管理模块mm.o
(cd mm; make)
fs/fs.o: # 文件系统目标模块fs.o
(cd fs; make)
lib/lib.a: # 库函数lib.a
2.8 linux/Makefile 文件
(cd lib; make)
boot/setup: boot/setup.s # 这里开始的三行是使用8086 汇编和连接器
$(AS86) -o boot/setup.o boot/setup.s # 对setup.s 文件进行编译生成setup 文件。
$(LD86) -s -o boot/setup boot/setup.o # -s 选项表示要去除目标文件中的符号信息。
boot/bootsect: boot/bootsect.s # 同上。生成bootsect.o 磁盘引导块。
$(AS86) -o boot/bootsect.o boot/bootsect.s
$(LD86) -s -o boot/bootsect boot/bootsect.o
tmp.s: boot/bootsect.s tools/system # 这四行的作用是在bootsect.s 程序开头添加
# 一行有关system 文件长度信息。方法是首先生成含有“SYSSIZE = system 文件实际长度”
# 一行信息的tmp.s 文件,然后将bootsect.s 文件添加在其后。取得system 长度的方法是:
# 首先利用命令ls 对system 文件进行长列表显示,用grep 命令取得列表行上文件字节数字段
# 信息,并定向保存在tmp.s 临时文件中。cut 命令用于剪切字符串,tr 用于去除行尾的回车符。
# 其中:(实际长度 + 15)/16 用于获得用‘节’表示的长度信息。1 节 = 16 字节。
(echo -n "SYSSIZE = (";ls -l tools/system | grep system \
| cut -c25-31 | tr '\012' ' '; echo "+ 15 ) / 16") > tmp.s
cat boot/bootsect.s >> tmp.s
clean: # 当执行'make clean'时,就会执行98--103 行上的命令,去除所有编译连接生成的文件。
# 'rm'是文件删除命令,选项-f 含义是忽略不存在的文件,并且不显示删除信息。
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) # 进入mm/目录;执行该目录Makefile 文件中的clean 规则。
(cd fs;make clean)
(cd kernel;make clean)
(cd lib;make clean)
backup: clean # 该规则将首先执行上面的clean 规则,然后对linux/目录进行压缩,生成
# backup.Z 压缩文件。'cd .. '表示退到linux/的上一级(父)目录;
# 'tar cf - linux'表示对linux/目录执行tar 归档程序。-cf 表示需要创建
# 新的归档文件 '| compress -'表示将tar 程序的执行通过管道操作('|')
# 传递给压缩程序compress,并将压缩程序的输出存成backup.Z 文件。
(cd .. ; tar cf - linux | compress - > backup.Z)
sync # 迫使缓冲块数据立即写盘并更新磁盘超级块。
(判断哪些文件需要重新编译,预处理后保守为新的Makefile文件)
dep:
# 该目标或规则用于各文件之间的依赖关系。创建的这些依赖关系是为了给make 用来确定是否需要要
# 重建一个目标对象的。比如当某个头文件被改动过后,make 就通过生成的依赖关系,重新编译与该
# 头文件有关的所有*.c 文件。具体方法如下:
# 使用字符串编辑程序sed 对Makefile 文件(这里即是自己)进行处理,输出为删除Makefile
# 文件中'### Dependencies'行后面的所有行(下面从118 开始的行),并生成tmp_make
# 临时文件(也即110 行的作用)。然后对init/目录下的每一个C 文件(其实只有一个文件
# main.c)执行gcc 预处理操作,-M 标志告诉预处理程序输出描述每个目标文件相关性的规则,
# 并且这些规则符合make 语法。对于每一个源文件,预处理程序输出一个make 规则,其结果
# 形式是相应源程序文件的目标文件名加上其依赖关系--该源文件中包含的所有头文件列表。
# 111 行中的$$i 实际上是$($i)的意思。这里$i 是这句前面的shell 变量的值。
# 然后把预处理结果都添加到临时文件tmp_make 中,然后将该临时文件复制成新的Makefile 文件。
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) # 对fs/目录下的Makefile 文件也作同样的处理。
2.8 linux/Makefile 文件
- 30 -
(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
FAQ:生成的”image”文件有什么用呢?PC机启动进程中什么时候进行Make链接?System.map和systemy文件的用处与怎么用呢?
是否在系统引导结束后,才调用Make程序生成内核映象文件image,再加载进内存,成为操作系统?
Posted: 2007-03-02 16:10 |
[22 楼]
侨光
∷
性别:
∷
状态:
∷
等级:
品行端正
∷
发贴:
308
∷
威望:
0
∷
浮云:
1123
∷
在线等级:
∷
注册时间: 2005-10-03
∷
最后登陆: 2011-05-19
【
复制此帖地址
只看此人回复
】
5come5帮你背单词 [
stop
/stop/
n. 停止,终止,公共汽车站;vt. 阻止,使停止;停止,逗留
]
第六章
引导启动程序
系统的引导
当PC启动时,Intel系列的CPU首先进入的是实模式,CS寄存器的值是0xffff,IP寄存器的值是0x0000.因此CPU开始的时候是执行位于地址0xFFFF0处的代码,也就是ROM-BIOS起始位置的代码。BIOS先进行一系列的系统自检,然后初始化位于地址0的中断向量表。最后BIOS将启动盘的第一个扇区(512KB)装入到绝对内存地址0x07c00,并跳转到这里开始执行此处的代码。这里的启动盘可以是硬盘也可为软盘或启动光盘(我想应该把启动光碟也包括进去的)。
当Linux系统开始运行时,将自己装入到绝对地址0x90000,再将其后的2k字节(setup文件)装入到地址0x90200处,最后将内核文件装入到0x10000。这个过程是由系统的引导程序完成的,这个程序是用汇编语言编写的,放在启动盘的第一扇区,由BIOS加载到内存当中。当引导程序将系统装入内存时,会显示“Loading…”这条信息。装入完成后,控制转向另一个实模式下运行的汇编语言代码/boot/Setup.s。
Setup.s部分首先设置一些系统的硬件设备,然后将内核文件从0x10000处移至0x00000处。这时系统转入保护模式,开始执行位于0x00000处的代码。内核文件的头部是用汇编语言写的,对应的文件是/boot/head.s。
Head.s这个部分会将IDT(中断向量表)、GDT(全局段描述符表)和LDT(局部段描述表)的首地址装入到相应的寄存器中,初始化处理器,设置好内存页面,最终调用/init/main.c文件的main()函数,这个函数是用C语言编写。
原文描述:
“Linux 的最最前面部分是用8086 汇编语言编写的(boot/bootsect.s),它将由BIOS 读入到内存绝对地址0x7C00(31KB)处,当它被执行时就会把自己移到绝对地址0x90000(576KB)处,并把启动设备中后2kB 字节代码(boot/setup.s)读入到内存0x90200 处,而内核的其它部分(system 模块)则被读入到从地址0x10000开始处,因为当时system 模块的长度不会超过0x80000 字节大小(即512KB),所以它不会覆盖在0x90000处开始的bootsect 和setup 模块。随后将system 模块移动到内存起始处,这样system 模块中代码的地址也即等于实际的物理地址。便于对内核代码和数据的操作。
启动部分识别主机的某些特性以及vga 卡的类型。如果需要,它会要求用户为控制台选择显示模式。然后将整个系统从地址0x10000 移至0x0000 处,进入保护模式并跳转至系统的余下部分(在0x0000 处)。此时所有32 位运行方式的设置启动被完成: IDT、GDT 以及LDT 被加载,处理器和协处理器也已确认,分页工作也设置好了;最终调用init/main.c 中的main()程序。上述操作的源代码是在boot/head.S 中的,这可能是整个内核中最有诀窍的代码了。注意如果在前述任何一步中出了错,计算机就会死锁。在操作系统还没有完全运转之前是处理不了出错的。”
下图说明了系统引导的文件加载过程:
图6.1 文件加载过程
6.2 bootsect.s程序
bootsect.s 代码是磁盘引导块程序,驻留在磁盘的第一个扇区中(引导扇区,0 磁道(柱面),0 磁头,第1 个扇区)。在PC 机加电ROM BIOS 自检后,引导扇区由BIOS 加载到内存0x7C00 处,然后将自己移动到内存0x90000 处①。该程序的主要作用是首先将setup 模块(由setup.s 编译成)从磁盘加载到内存②,紧接着bootsect 的后面位置(0x90200),然后利用BIOS 中断0x13 取磁盘参数表中当前启动引导盘的参数③,接着在屏幕上显示“Loading system...”字符串④。再者将system 模块从磁盘上加载到内存0x10000 开始的地方⑤。随后确定根文件系统的设备号,若没有指定,则根据所保存的引导盘的每磁道扇区数判别出盘的类型
和种类(是1.44M A 盘?)并保存其设备号于root_dev(引导块的0x508 地址处),最后长跳转到setup 程序的开始处(0x90200)执行setup 程序。
下面把重要的代码段解释一下,整个内核我会上传上来的。
entry start ! 告知连接程序,程序从start 标号开始执行。
start: ! 47--56 行作用是将自身(bootsect)从目前段位置0x07c0(31k)
! 移动到0x9000(576k)处,共256 字(512 字节),然后跳转到
! 移动后代码的go 标号处,也即本程序的下一语句处。
mov ax,#BOOTSEG ! 将ds 段寄存器置为0x7C0;
mov ds,ax
mov ax,#INITSEG ! 将es 段寄存器置为0x9000;
mov es,ax
mov cx,#256 ! 移动计数值=256 字;
sub si,si ! 源地址 ds:si = 0x07C0:0x0000
sub di,di ! 目的地址 es:di = 0x9000:0x0000
rep ! 重复执行,直到cx = 0
movw ! 移动1 个字; (这里把BOOTSEG段上的代码copy到INITSEG段上,完成①)
jmpi go,INITSEG ! 间接跳转。这里INITSEG 指出跳转到的段地址。
go: mov ax,cs ! 将ds、es 和ss 都置成移动后代码所在的段处(0x9000)。
mov ds,ax !由于程序中有堆栈操作(push,pop,call),因此必须设置堆栈。
mov es,ax
! put stack at 0x9ff00. ! 将堆栈指针sp 指向0x9ff00(即0x9000:0xff00)处
mov ss,ax
mov sp,#0xFF00 ! arbitrary value >>512 (开辟堆栈用于保存过程变量)
! 由于代码段移动过了,所以要重新设置堆栈段的位置。
! sp 只要指向远大于512 偏移(即地址0x90200)处
! 都可以。因为从0x90200 地址开始处还要放置setup 程序,
! 而此时setup 程序大约为4 个扇区,因此sp 要指向大
! 于(0x200 + 0x200 * 4 + 堆栈大小)处。
(下面装载setup模块)
load_setup:
!利用BIOS 中断INT 0x13 将setup 模块从磁盘第2 个扇区
! 开始读到0x90200 开始处,共读4 个扇区。如果读出错,则复位驱动器,并
! 重试,没有退路。INT 0x13 的使用方法如下:
! 读扇区:
! ah = 0x02 - 读磁盘扇区到内存;al = 需要读出的扇区数量;
! ch = 磁道(柱面)号的低8 位; cl = 开始扇区(0-5 位),磁道号高2 位(6-7);
! dh = 磁头号; dl = 驱动器号(如果是硬盘则要置位7);
! es:bx ??指向数据缓冲区; 如果出错则CF 标志置位。
mov dx,#0x0000 ! drive 0, head 0
mov cx,#0x0002 ! sector 2, track 0
mov bx,#0x0200 ! address = 512, in INITSEG
mov ax,#0x0200+SETUPLEN ! service 2, nr of sectors (参数设置)
int 0x13 ! read it (调用中断执行Load setup②)
jnc ok_load_setup ! ok - continue
mov dx,#0x0000
mov ax,#0x0000 ! reset the diskette
int 0x13
j load_setup
! Get disk drive parameters, specifically nr of sectors/track
! 取磁盘驱动器的参数,特别是每道的扇区数量。
! 取磁盘驱动器参数INT 0x13 调用格式和返回信息如下:
! ah = 0x08 dl = 驱动器号(如果是硬盘则要置位7 为1)。
! 返回信息:
! 如果出错则CF 置位,并且ah = 状态码。
! ah = 0, al = 0, bl = 驱动器类型(AT/PS2)
! ch = 最大磁道号的低8 位,cl = 每磁道最大扇区数(位0-5),最大磁道号高2 位(位6-7)
! dh = 最大磁头数, dl = 驱动器数量,
! es:di -?? 软驱磁盘参数表。
mov dl,#0x00
mov ax,#0x0800 ! AH=8 is get drive parameters
int 0x13
mov ch,#0x00
seg cs ! 表示下一条语句的操作数在cs 段寄存器所指的段中。
mov sectors,cx ! 保存每磁道扇区数。
mov ax,#INITSEG
mov es,ax ! 因为上面取磁盘参数中断改掉了es 的值,这里重新改回。 (取磁盘参数,用于硬件初始化③)
! Print some inane message ! 在显示一些信息('Loading system ...'回车换行,共24 个字符)。
mov ah,#0x03 ! read cursor pos
xor bh,bh ! 读光标位置。
int 0x10
mov cx,#24 ! 共24 个字符。
mov bx,#0x0007 ! page 0, attribute 7 (normal)
mov bp,#msg1 ! 指向要显示的字符串。Msg1 是指针,指向字段”Loading system…”
mov ax,#0x1301 ! write string, move cursor
int 0x10 ! 写字符串并移动光标。 (在屏幕上显示”Loading system…”④)
Posted: 2007-03-02 16:10 |
[23 楼]
chenyukang
∷
性别:
∷
状态:
∷
等级:
人见人爱
∷
发贴:
2275
∷
威望:
0
∷
浮云:
1127
∷
在线等级:
∷
注册时间: 2006-09-24
∷
最后登陆: 2020-08-17
【
复制此帖地址
只看此人回复
】
5come5帮你背单词 [
deteriorate
/di'ti
ə
ri
ə
reit/
v. (使)恶化,败坏
]
APUE还没啃完
寒假看了点Kernel Primer
这本书图书馆有吗?
Posted: 2007-03-02 16:11 |
[24 楼]
iwant
∷
性别:
∷
状态:
∷
头衔:
我是你的GG
∷
等级:
希望之光
∷
发贴:
1659
∷
威望:
-1
∷
浮云:
1204
∷
在线等级:
∷
注册时间: 2005-03-10
∷
最后登陆: 2007-06-06
【
复制此帖地址
只看此人回复
】
5come5帮你背单词 [
helpless
/'helplis/
a. 无助的,无依靠的
]
刚好我有一本准备卖掉呢,要的PM我。
厚本原价¥78的那种
《LINUX内核完全剖析》是LZ说的那本书的升级版,内容比原来多了近一倍,
非常之详细。
Posted: 2007-03-02 16:13 |
[25 楼]
luwen
∷
性别:
∷
状态:
∷
头衔:
无我相
∷
等级:
人见人爱
∷
发贴:
4372
∷
威望:
0
∷
浮云:
1120
∷
在线等级:
∷
注册时间: 2006-09-14
∷
最后登陆: 2013-09-25
【
复制此帖地址
只看此人回复
】
5come5帮你背单词 [
transplant
/tr
æ
ns'pla:nt/
vt. 移植
]
恩,先谢了
Posted: 2007-03-02 16:15 |
[26 楼]
侨光
∷
性别:
∷
状态:
∷
等级:
品行端正
∷
发贴:
308
∷
威望:
0
∷
浮云:
1123
∷
在线等级:
∷
注册时间: 2005-10-03
∷
最后登陆: 2011-05-19
【
复制此帖地址
只看此人回复
】
5come5帮你背单词 [
formula
/'fo:mjul
ə
/
(formulae)公式 n. 公式,处方
]
楼上的把资料也放上来一起分享嘛,大家交流一下。
Posted: 2007-03-02 16:16 |
[27 楼]
chenyukang
∷
性别:
∷
状态:
∷
等级:
人见人爱
∷
发贴:
2275
∷
威望:
0
∷
浮云:
1127
∷
在线等级:
∷
注册时间: 2006-09-24
∷
最后登陆: 2020-08-17
【
复制此帖地址
只看此人回复
】
5come5帮你背单词 [
grumble
/'gr
Λ
mbl/
v. & n. (发)牢骚
]
Quote:
引用第27楼侨光于2007-03-02 16:16发表的
:
楼上的把资料也放上来一起分享嘛,大家交流一下。
有apue电子书 要不? 中文版
看的是图书馆的影印版
Posted: 2007-03-02 16:27 |
[28 楼]
侨光
∷
性别:
∷
状态:
∷
等级:
品行端正
∷
发贴:
308
∷
威望:
0
∷
浮云:
1123
∷
在线等级:
∷
注册时间: 2005-10-03
∷
最后登陆: 2011-05-19
【
复制此帖地址
只看此人回复
】
5come5帮你背单词 [
top
/top/
n. 顶,上端,首位,上面,盖子;a. 最高的,最优秀的;vt. 位…之首,居…之上,超过
]
放上来嘛,我下来看看
Posted: 2007-03-02 16:33 |
[29 楼]
«
1
2
3
4
»
Pages: ( 2/4 total )
快速跳至
|- 站务管理
|- 惩罚,奖励公布区
|- 会员咨询意见区
|- 申请区
|- 已批准申请区
|- 威望和荣誉会员推荐区
|- 5come5名人堂·Hall of Fame
>> 休闲娱乐
|- 灌水乐园 大杂烩
|- 精水区
|- 幽默天地
|- 开怀大笑(精华区)
|- 灵异空间
|- 运动新时空·菠菜交流
|- 动之风.漫之舞
|- 新货上架
|- 古董挖挖
|- 唯美贴图
|- 创意&美化&设计
|- 5COME5头像及签名档图片引用专区
|- 艺术摄影
|- 音乐咖啡屋
|- 音道乐经
>> 热点讨论
|- 工作交流
|- 求职信息
|- 就业精华区
|- 同城联谊
|- 留学专版
|- 情感物语
|- 情感物语精华区
|- 带走一片银杏叶
|- 精华区
|- 新闻直通车
|- 众志成城,抗震救灾
|- 衣食住行
|- 跳蚤市场
|- 旅游出行
>> 学术交流
|- 学业有成
|- 智力考场
|- 考研专版
|- 外语乐园
|- 考试·毕业设计
|- 电子设计·数学建模
|- 学生工作·社团交流·RX
|- 电脑技术
|- 电脑F.A.Q.
|- 软件交流
|- 硬件·数码
|- 程序员之家
|- Linux专区
|- 舞文弄墨
|- 历史&文化
|- 军临天下
|- 军事精华区
|- 财经频道
>> 游戏新干线[电子竞技俱乐部]
|- Blizz@rd游戏特区
|- WarCraft III
|- 魔兽区档案库
|- 魔兽争霸3博彩专区
|- StarCraft(new)
|- 暗黑专区
|- 休闲游戏区
|- PC GAME综合讨论区
|- 实况足球专区
|- Counter-Strike专区
|- TV GAME& 模拟器
|- 网络游戏
>> 资源交流
|- 恋影部落
|- 连续剧天地
|- 综艺开心档
|- 书香小筑
|- 小说发布
|- 资源交流
|- 综艺、体育、游戏资源发布
|- 音乐资源发布区
|- 电影电视剧发布区
|- 字幕园地
我来我网·5come5 Forum
»
Linux专区
Total 0.200063(s) query 7, Time now is:12-23 19:08, Gzip enabled
Powered by PHPWind v5.3, Localized by
5come5 Tech Team
,
黔ICP备16009856号