《linux内核完全注释》第3章总结

本文是《Linux内核完全注释》第三章的总结,详细探讨了内核中的描述符机制、系统调用过程以及底层汇编和表格在其中的作用。通过对这些关键概念的解析,读者将能够更深入地理解Linux内核的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 /*

* 《linux内核完全注释》第3章
*  (C) 2010-10-2 yang hui yu
*  mail: gisyhy@163.com
*/
3.2.1 bootsect.s程序问题分析:
1)seg cs :表示下一条语句操作数强制使用该段作为数据段
比如:
seg cs
mov sectors,cx
等价于:
mov cs:[sectors],cx
2)test ax,0x0fff :test只是进行and操作,不返回结果,目的是改变标志位
比如:
test ax,0x0fff   !表示and ax,0x0fff,改变了zero flag
jne loop
3)各种跳转指令对应的flags:
jc: CF=1,有进位
js: SF=1,负号  
jo: OF=1,溢出  
jp: PF=1,偶数  
jz/je: ZF=1,零标志
ja: (比较无符号数) 高于
jb: (比较无符号数) 低于 
jg: (比较带符号数) 大于 
jl: (比较带符号数) 小于
4)flags寄存器标志:
15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
   OF DF    IF   TF   SF   ZF        AF        PF        CF
 
条件码标志有:
OF:(Overflow Flag)溢出标志,在运算过程中,如操作数超出了机器能表示的范围则称为溢出。此时OF标志位为1(OV),否则置0(NV)。
SF:(Sign Flag)符号标志,记录运算结果的符号,结果为负时置1(NG),否则置0(PL)。
ZF:(Zero Flag)零标志,运算结果为0时置1(ZR),否则置0(NZ)。
CF:(Carry Flag)进位标志,运算时,从最高有效位产生了进位值时置1(CY),否则置0(NC)。
AF:(Auxiliary carry Flag)辅助进位标志,记录运算时最低的4位(半个字节)产生的进位值。有进位值时置1否(AC),则置0(NA)。
PF:(Parity Flag)奇偶标志,用来为机器中传送信息时可能产生的代码出错情况提供检验条件,
当结果操作数中1的个数为偶数时置1(PE),否则置0(PO)。
 
控制标志有:
DF:(Direction Flag)方向标志,在串处理指令中控制处理信息的方向用,当DF置1(DN)每次操作后,
使变址寄存器SI和DI减量,这样就使串处理从高地址向低地址方向处理。当DF置0(UP)时,则反之。
IF:(Interrupt Flag)中断标志,当IF为1(EI)时,允许中断,否则IF为0(DI)关闭中断。
TF:(Trap Flag)陷井标志,用于单步方式操作,当TF为1时,每条指令执行完后产生陷井,
由系统控制计算机;当IF为0时,CPU正常工作不产生陷井。
3.2.2 setup.s程序问题分析:
1)进入保护模式:
将cr0的PE=1,即比特位0置1
2)GDT描述符:
1>gdtr寄存器6B:2B段限、4B基址
2>描述符项8B:
; usage: Descriptor Base, Limit, Attr
;        Base:  dd
;        Limit: dd (low 20 bits available)
;        Attr:  dw (lower 4 bits of higher byte are always 0)
%macro Descriptor 3
dw %2 & 0FFFFh ; 段界限 1 (2 字节)
dw %1 & 0FFFFh ; 段基址 1 (2 字节)
db (%1 >> 16) & 0FFh ; 段基址 2 (1 字节)
dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) ; 属性 1 + 段界限 2 + 属性 2 (2 字节)
db (%1 >> 24) & 0FFh ; 段基址 3 (1 字节)
%endmacro ; 共 8 字节
3)IDT描述符:
1>idtr寄存器6B:2B段限、4B基址
2>描述符项8B:
; usage: Gate Selector, Offset, DCount, Attr
;        Selector:  dw
;        Offset:    dd
;        DCount:    db
;        Attr:      db
%macro Gate 4
dw (%2 & 0FFFFh) ; 偏移 1 (2 字节)
dw %1 ; 选择符 (2 字节)
dw (%3 & 1Fh) | ((%4 << 8) & 0FF00h) ; 属性 (2 字节)
dw ((%2 >> 16) & 0FFFFh) ; 偏移 2 (2 字节)
%endmacro ; 共 8 字节
4)段选择符:
;选择符图示:
;         ┏━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┓
;         ┃ 15 ┃ 14 ┃ 13 ┃ 12 ┃ 11 ┃ 10 ┃ 9  ┃ 8  ┃ 7  ┃ 6  ┃ 5  ┃ 4  ┃ 3  ┃ 2  ┃ 1  ┃ 0  ┃
;         ┣━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━╋━━╋━━┻━━┫
;         ┃                                 描述符索引                                 ┃ TI ┃   RPL    ┃
;         ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━┻━━━━━┛
;
; RPL(Requested Privilege Level): 请求特权级,用于特权检查。
;
; TI(Table Indicator): 引用描述符表指示位
; TI=0 指示从全局描述符表GDT中读取描述符;
; TI=1 指示从局部描述符表LDT中读取描述符。
3.3.3 head.s程序问题分析:
1).align 2: 表示下一条语句的地址偏移的对齐字节数,这里表示按2^2=4字节对齐
比如:
0x0000: ...(假设该条语句为3个字节)
0x0003: ...(假设该条语句为3个字节)
.align 2
text:
如果没有".align 2",则text的地址为0x0006
但是由于按4字节对齐,text的地址为 0x0008
2).org 0x1000: 表示下一条语句的地址偏移为0x1000
3)cld/stosl: 字符串操作
cld: 自增
std: 自减
stosl: movl %eax,(%edi){以%es为选择符}
习题解答:
1、请说明Linux内核引导启动的完整过程。系统是在什么时候开始进入386保护模式?
答:
在setup.s执行完后,执行head.s代码时进入保护模式。
2、在本章所描述的内核启动程序中,为什么不直接将system模块搬到0x00000处而是
先搬到0x10000处,在搬到0x00000处呢?
答:
由于在setup.s还要利用BIOS的中断向量,而BIOS中断向量保存在0x00000处。
3、setup.s和head.s中都分别设置了一次全局描述符表GDT和中断描述符表IDT,这是
为什么?能否只在head.s中设置一次?
答:
不能,因为setup.s在跳到head.s时已经处于保护模式,必须设置好GDT和IDT。
4、若不使用as86汇编器,而用gas来编译bootset可以么?为什么Linus当时要使用as86呢?
答:
这样可以将bootsect.s和setup.s运行于实模式的代码编译成16位的,而system的代码
是在保护模式下运行的。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值