Linux系统分析实验(一):时间片轮转多道程序内核
注:后三位416
原创作品转载请注明出处<https://github.com/mengning/linuxkernel/
实验环境
Ubuntu16.04虚拟机
VMware workstation 12 Player
实验步骤
-
下载
linux3.9.4
版本内核源码并打上mykernel
的补丁wget <https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.9.4.tar.xz>
wget <https://raw.github.com/mengning/mykernel/master/mykernel_for_linux3.9.4sc.patch>
tar -xvf linux-3.9.4.tar
cd linux-3.9.4
patch -p1 < ../mykernel_for_linux3.9.4sc.patch
-
编译
make allnoconfig make
编译报错:缺少compiler-gcc5.h
的头文件。cd
到include/linux
下发现只有compiler-gcc4.h
,我们将该文件重命名为compiler-gcc5.h:mv compiler-gcc4.h compiler-gcc5.h
。
-
安装qemu启动内核
sudo apt-get install qemu # install QEMU sudo ln -s /usr/bin/qemu-system-i386 /usr/bin/qemu qemu -kernel arch/x86/boot/bzImage # 使用qemu启动内核
mykernel
代码分析
从孟宁老师的主页上获取源码 https://github.com/mengning/mykernel 下载mymain.c ,myinterrupt.c 和 mypcb.h
三个文件。
mypcb.h
:
该头文件包含一个thread
结构体线程的上下文(指令指针和栈顶指针)。PCB结构定义了进程控制块:
(1)pid
进程标识符;
(2)state
状态,-1表示不可运行,0表示可运行,>0
表示停止;
(3)定义了一个栈空间;
(4)一个Thread
变量;
(5)任务入口点;
(6)下一个PCB
的指针;
struct Thread {
unsigned long ip;//point to cpu run address
unsigned long sp;//point to the thread stack's top address
//todo add other attrubte of system thread
};
//PCB Struct
typedef struct PCB{
int pid; // pcb id
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
char stack[KERNEL_STACK_SIZE];// each pcb stack size is 1024*8
/* CPU-specific state of this task */
struct Thread thread;
unsigned long task_entry;//the task execute entry memory address
struct PCB *next;//pcb is a circular linked list
unsigned long priority;// task priority
//todo add other attrubte of process control block
}tPCB;
myinterrupt.c
:
主要实现定时器中断,每隔1000ms进行my_need_sched
的检查,如果不为1,则置为1使其进入就绪队列。my_schedule函数具体实现了进程的切换。声明了两个指针,prev
和next
,分别指向当前进程和下一个进程。
void my_timer_handler(void)
{
#