《Linux内核原理与分析》第三周作业
教材学习总结
第三章 进程管理
进程是Unix操作系统抽象概念中最基本的一种,是正在执行的程序代码的实时结果;线程,是在进程中活动的对象。而Linux实现线程的机制非常独特,从内核的角度来说,它并没有线程的概念。Linux把所有的线程都当作进程来实现。在进程的创建中,Unix分解到两个单独的函数中去执行:fork()和exec(),Linux的fork()使用写时拷贝(copy-on-write)页实现。最后,内核释放它所占有的资源,在进程调用exit(),进程终结。
第五章 系统调用
系统调用在用户空间进程和硬件设备之间添加了一个中间层,为用户空间提供了一种硬件的抽象借口,系统调用保证了系统的稳定和安全。应用程序通过在用户空间实现的应用编程接口(API)而不是直接通过系统调用来编程,因为应用程序使用的这种编程接口实际上并不需要和内核提供的系统调用对应。要访问系统调用(syscall),通常通过C库中定义的函数调用来进行。在Linux中,每个系统调用被赋予一个独一无二的系统调用号,来关联系统调用。在参数验证中,为了向用户空间读取数据,内核提供了copy_from_user();为了从用户空间读取数据,内核提供了copy_from_user(),同样都需要三个参数。最后一项检查针对是否有合法权限,调用者可以使用capable()函数来检查是否有权能对指定的资源进行操作,如果返回非0值,调用者就有权进行操作,返回0则无权操作。在系统调用上下文中,内核在执行系统调用的时候处于新城上下文,current指针指向当前任务。通常,系统调用靠C库支持。用户程序通过包含标准头文件并和C库链接,就可以使用系统调用。
视频学习总结
计算机工作的三大法宝:
存储结构计算机、函数调用堆栈和中断机制
堆栈相关的寄存器
-esp 堆栈指针,指向栈顶
-ebp 基址指针,指向指针
-push 栈顶地址减少4个字节(32位)
-pop 栈顶地址增加4个字节(由高地址向低地址增加)
其他关键寄存器
-cs:eip: 总是指向下一条的指令地址
call:将当前的cs:eip的值压入栈顶,cs:eip指向调用函数的入口地址
ret:从栈顶弹出来原来保存子啊这里的cs:eip的值,放入cs:eip中
深入理解函数调用堆栈的工作机制:
//建立被调用者函数的堆栈框架
push %ebp
movl %esp,%ebp
//被调用者函数体
//do sth
...
//拆除被调用者函数的堆栈框架
movl %ebp, %esp
popl %ebp
ret
C代码中嵌入汇编代码
内嵌汇编语法
asm(
汇编语句模板:
输出部分:
输入部分);
格式为:
asm("statements":output_regs:input_regs:clobbered_regs);
实验操作:
使用实验楼的虚拟机打开shell,通过cd LinuxKernel/linux-3.9.4
qemu -Kernel arch/x86/boot/bzImage 打开程序执行结果:
之后通过cd mykernel 可以看到qemu窗口输出的内容的myinterrupt.c
以及mymain.c
简单的操作系统内核源代码分析
在mykernel基础上构造一个简单的操作系统内核
struct Thread { //Thread 用来储存ip和sp
unsigned long ip;
unsigned long sp;
};
typedef struct PCB{
int pid; //进程的id号
volatile long state; //进程的状态
char stack[KERNEL_STACK_SIZE]; //内核堆栈
struct Thread thread; //Thread 结构体
unsigned long task_entry; //进程的起始入口
struct PCB *next; //指向下一个进程的指针
}tPCB;
void my_schedule(void); //函数执行的调度器