学号后三位:069
原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/
始臣之解牛之时,所见无非全牛者。
三年之后,未尝见全牛也。
0、mykernel简介
mykernel是孟宁老师在2013年,在Linux内核繁杂的CPU初始化工作的基础上完成的一个虚拟、可编程的计算机硬件模拟环境。有了mykernel,稍有编程能力的学生就可以编写一个简单的时间片轮转调度的小型内核,并且能读懂代码,深刻理解如何在CPU的一个指令执行流上实现多个进程。
1、mykernel部署
使用实验楼的虚拟机打开shell
依次输入如下指令:
cd LinuxKernel/linux-3.9.4
rm -rf mykernel
patch -p1 < ../mykernel_for_linux3.9.4sc.patch
make allnoconfig
make //编译时间大概10分钟
qemu -kernel arch/x86/boot/bzImage
经过耐心的等待后,看到编译完成了。⬇️
在输入qemu -kernel arch/x86/boot/bzImage指令后,跳出如下界面。且有两类字符串不断交替输出。
实际上,
- my_timer_handler here字符串是由
myinterrupt.c
中my_timer_handler
函数控制输出的 - my_start_kernel here字符串是由
mymain.c
中my_start_kernel
函数控制输出的
可见如下截图:
由此,我们可以知道,在系统启动后会周期性的调用myinterrupt.c中my_timer_handler函数
以及mymain.c中my_start_kernel函数
。
2、内核代码分析
本部分是要完成一个简单的时间片轮转多道程序内核代码,源代码来自孟宁老师的GitHub。https://github.com/mengning/mykernel
主要包含三部分文件:
- myinterrupt.c
包含模拟中断的函数。 - mymain.c
包含模拟多个运行的进程的函数。 - mypcb.h
头文件,定义了一些结构体等内容。
将以上文件下载到实验楼虚拟机中。
git clone https://github.com/mengning/mykernel
将这三个文件拷贝到LinuxKernel/linux-3.9.4下的mykernel中,覆盖原文件并增加新文件:mypcb.h
在LinuxKernel/linux-3.9.4下,执行下面指令:
patch -p1 < ../mykernel_for_linux3.9.4sc.patch //一定要打补丁
make allnoconfig //第二次编译之前,一定要make clean,不然会出错
make
输入如下指令后:
qemu -kernel arch/x86/boot/bzImage
弹出窗口,显示进程的运行及切换过程:
在上图中可以看到,进程切换的过程。⬆️
下面具体分析下这三个文件的代码:
源代码:https://github.com/mengning/mykernel/blob/master/mypcb.h
宏定义:
#define MAX_TASK_NUM 4
定义了最大任务数
#define KERNEL_STACK_SIZE 1024*2
定义了堆栈内核大小
线程结构体:
struct Thread {
unsigned long ip;
ip指令指针
unsigned long sp;
sp堆栈指针
};
此文件中最关键的部分是,下面的PCB结构体:
typedef struct PCB{
int pid;
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
unsigned long stack[KERNEL_STACK_SIZE];
/* CPU-specific state of this task */
struct Thread thread;
unsigned long task_entry;
struct PCB *next;
}tPCB;
其中,
pid
表示进程号,是进程的标识符
state
表示进程的状态,-1表示不可运行;0表示可运行等