[书]深入分析Linux内核源代码

内核源码下载:

https://mirrors.edge.kernel.org/pub/linux/kernel/
http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/

本书基于2.4.16版本

分段分页

分段。Linux在启动过程中设置了段寄存器的值和全局描述符表GDT的内容。


段选择子:

// FILE: include/asm-i386/segment.h
#define __KERNEL_CS	0x10 	// 内核代码段, index=2 TI=0 RPL=0
#define __KERNEL_DS	0x18 	// 内核数据段, index=3 TI=0 RPL=0
#define __USER_CS	0x23 	// 用户代码段, index=4 TI=0 RPL=3
#define __USER_DS	0x2B 	// 用户数据段, index=5 TI=0 RPL=3

段描述符GDT:

1)段基址都为0x0000_0000;2)段界限都为0xffff; 3)粒度G都为1,即段长单位为4KB;

4)段的D位为1,即对这4个段的访问都为32位指令;5)段的P位为1,即4个段都在内存。

// FILE: arch/i386/kernel/head.S
ENTRY(gdt_table)
	.quad 0x0000000000000000	/* NULL descriptor */
	.quad 0x0000000000000000	/* not used */
	.quad 0x00cf9a000000ffff	/* 0x10 kernel 4GB code at 0x00000000 */
	.quad 0x00cf92000000ffff	/* 0x18 kernel 4GB data at 0x00000000 */
	.quad 0x00cffa000000ffff	/* 0x23 user   4GB code at 0x00000000 */
	.quad 0x00cff2000000ffff	/* 0x2b user   4GB data at 0x00000000 */
	.quad 0x0000000000000000	/* not used */
	.quad 0x0000000000000000	/* not used */

分页。

Linux没有把这几个类型直接定义长整数而是定义为一个结构,是为了让gcc在编译时进行更严格的类型检查。另外,还定义了几个宏来访问这些结构的成分。

// FILE: include/asm-i386/page.h
// These are used to make use of C type-checking..
typedef struct { unsigned long pte_low; } pte_t;
typedef struct { unsigned long pmd; } pmd_t;
typedef struct { unsigned long pgd; } pgd_t;

typedef struct { unsigned long pgprot; } pgprot_t;

#define pte_val(x)	((x).pte_low)
#define pmd_val(x)	((x).pmd)
#define pgd_val(x)	((x).pgd)
#define pgprot_val(x)	((x).pgprot)

页表项。把标志位定义为宏,而不是位段,更有利于编码。

// FILE: include/asm-i386/pgtable.h
#define _PAGE_PRESENT	0x001
#define _PAGE_RW	0x002
#define _PAGE_USER	0x004
#define _PAGE_PWT	0x008
#define _PAGE_PCD	0x010
#define _PAGE_ACCESSED	0x020
#define _PAGE_DIRTY	0x040
#define _PAGE_PSE	0x080	/* 4 MB (or 2MB) page, Pentium+, if present.. */
#define _PAGE_GLOBAL	0x100	/* Global TLB entry PPro+ */


extern pgd_t swapper_pg_dir[1024]; 	// 页目录表
/* page table for 0-4MB for everybody */
extern unsigned long pg0[1024]; 	// 一个临时页表

中断机制

Intel x86通过两片级联的中断控制器8259A来响应15个外中断源,每个8259A可管理8个中断源。

IRQ0 时钟;IRQ1 键盘

初始化中断控制器8259A

// FILE: arch/i386/kernel/i8259.c
void __init init_8259A(int auto_eoi)()
{
    ...
}

 

 

 

75

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章