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

3 篇文章 0 订阅

内核源码下载:

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)()
{
    ...
}

 

 

 

86

 

 

第一章 走进linux 1.1 GNU与Linux的成长 1.2 Linux的开发模式和运作机制 1.3走进Linux内核 1.4 分析Linux内核的意义 1.5 Linux内核结构 1.6 Linux内核源代码 1.7 Linux内核源代码分析工具 第二章 Linux运行的硬件基础 2.1 i386的寄存器 2.2 内存地址 2.3 段机制和描述符 2.4 分页机制 2.5 Linux中的分页机制 2.6 Linux中的汇编语言 第三章中断机制 3.1 中断基本知识 3.2中断描述符表的初始化 3.3异常处理 3.4 中断处理 3.5中断的后半部分处理机制 第四章 进程描述 4.1 进程和程序(Process and Program) 4.2 Linux中的进程概述 4.3 task_struct结构描述 4.4 task_struct结构在内存中的存放 4.5 进程组织的方式 4.6 内核线程 4.7 进程的权能 4.8 内核同步 第五章进程调度 5.1 Linux时间系统 5.2 时钟中断 5.3 Linux的调度程序-Schedule( ) 5.4 进程切换 第六章 Linux内存管理 6.1 Linux的内存管理概述 6.2 Linux内存管理的初始化 6.3 内存的分配和回收 6.4 地址映射机制 6.5 请页机制 6.6 交换机制 6.7 缓存和刷新机制 6.8 进程的创建和执行 第七章 进程间通信 7.1 管道 7.2 信号(signal) 7.3 System V 的IPC机制 第八章 虚拟文件系统 8.1 概述 8.2 VFS中的数据结构 8.3 高速缓存 8.4 文件系统的注册、安装与拆卸 8.5 限额机制 8.6 具体文件系统举例 8.7 文件系统的系统调用 8 .8 Linux2.4文件系统的移植问题 第九章 Ext2文件系统 9.1 基本概念 9.2 Ext2的磁盘布局和数据结构 9.3 文件的访问权限和安全 9.4 链接文件 9.5 分配策略 第十章 模块机制 10.1 概述 10.2 实现机制 10.3 模块的装入和卸载 10.4 内核版本 10.5 编写内核模块 第十一章 设备驱动程序 11.1 概述 11.2 设备驱动基础 11.3 块设备驱动程序 11.4 字符设备驱动程序 第十二章 网络 12.1 概述 12.2 网络协议 12.3 套接字(socket) 12.4 套接字缓冲区(sk_buff) 12.5 网络设备接口 第十三章 启动系统 13.1 初始化流程 13.2 初始化的任务 13.3 Linux 的Boot Loarder 13.4 进入操作系统 13.5 main.c中的初始化 13.6 建立init进程 附录: 1 Linux 2.4内核API 2.1 驱动程序的基本函数 2.2 双向循环链表的操作 2.3 基本C库函数 2.4 Linux内存管理中Slab缓冲区 2.5 Linux中的VFS 2.6 Linux的连网 2.7 网络设备支持 2.8 模块支持 2.9 硬件接口 2.10 块设备 2.11 USB 设备
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值