һ������mykernel
ϵͳ��Ubuntu 16.04 64λ�汾
ǰ��������Git �Լ���������ԭװUbuntu��δ���ӵ�������������漰������Ӧ����ͨ��sudo apt-get install + ���밲װ������)
����������ʦ�IJ���һ����ִ�м�����ɲ���
��Ҫע���һ����make��ʱ����ܻ����������/include/linux���Ҳ���compiler-gcc5.h����makeʧ�ܡ�������Ϊmykernel�ǻ���linuxԭ����3.9.4�ں�д�ģ���ʱgcc�İ汾��û�е�5���ڶ�Ӧ���ļ�����ֻ��compiler-gcc4.h compiler-gcc3.h compiler-gcc.h�������Ҫ�Լ�����compiler-gcc5.h����������makeĿ¼���ļ����е�/include/linux�У�ע�ⲻҪ������ϵͳ/usr/include���ˡ�
�ź�compiler-gcc5.h������make���ɳɹ�make��������ʹ��qemu -kernel arch/x86/boot/bzImage���ɲ鿴�ļ���������������ͼ��
���Կ����粿���ļ�������ԣ�my_start_kernel��ִ�У�ͬʱmy_timer_handlerʱ���жϴ�������������ִ�С�
��������������е�mymain.c myinterrupt.c mypcb.h��ע�����ڴ����İ汾������ǰ�ĵ���bug�汾����ʹ��git�汾�����鿴�ɰ汾�����أ�������mykernel�ļ����е�mymain.c myinterrupt.c�������ϼ�Ŀ¼��make��Ȼ��ʹ��qemu -kernel arch/x86/boot/bzImage���ɿ�������ͼ������������ͼ��Ϊ����3�л�������0�������
������ʱ��Ƭ��ת��������ں˴������
������������������ɵĹ��ܾ���һ���Ŀ�ʵ�ּ�ʱ��Ƭ��ת�Ķ��������ںˡ����潫����ʵ��ʵ�����Ϲ��ܵ�mypcb.h��myinterrupt.c�Լ�mymain.c��������
1��mypcb.h
mypcb.h�ļ�����Ҫ�ǶԽ��̵�PCB�������ݽṹ�Ķ��壬һЩ�����Ķ��壬�Լ�my_schedule��������������Щ������������������������ļ��С�mypcb.h����������£�
#define MAX_TASK_NUM 4
#define KERNEL_STACK_SIZE 1024*2
struct Thread {
unsigned long ip; //eip
unsigned long sp; //esp
};
typedef struct PCB{
int pid;
volatile long state; //-1 means unrunnable, 0 means runnable, >0 means stopped
unsigned long stack[KERNEL_STACK_SIZE];
/* CPU-specific state of this task */
struct Thread thread;
unsigned long task_entry;
struct PCB *next;
}tPCB;
void my_schedule(void);
�꣺
MAX_TASK_NUM ������������Ϊ4
KERNEL_STACK_SIZE ����ÿ�����̶�ջ�Ĵ�С
PCB��
pid ���̵�Ψһ��ʶ���������ֽ���
state ���̵�ǰ��״̬��֮��������Ϊvolatile��ϣ����������Ҫ��������Ż�����֤ÿ�ζ��ܴ��ڴ��л�ȡ��ֵ��
stack[KERNEL_STACK_SIZE] ���̵Ķ�ջ
thread ���̵�ip������ָ�룩��sp��ջ��ָ�룩
task_entry ���̵����
next ��һ��PCB��������PCB���������γɻ����Ӷ�����ѭ���л����̡�
2��mymain.c
ǰ16����һЩͷ�ļ��Լ�mypcb.h�ļ��İ�����
��������һ��PCB������task��һ��ָ��ǰ���н��̵�my_current_taskָ�룬�Լ���������Ƿ���Ҫ���ȵ�my_need_sched������ֵΪ1ʱ��ʾ������Ҫ���ȣ�֮��������ΪvolatileҲ����Ϊϣ���ܾ�������������в���Ҫ���Ż�����֤�ò�������Ч�ԡ�
������__init my_start_kernel��������PCB�ij�ʼ��������ϸ�ڲ������͡���Ҫ�����Ƕ�ÿ�����̵�PCB�������Խ��и�ֵ����������PCBͨ��nextָ�����ӡ���ʼ����ɺ�ʹ��asm����Ƕ�����룩����ǰ���̣�0�Ž���װ���ڴ��С�ÿ�����̵���ڵ�ַ�������涨���my_process������������Ƕasm�ľ�����Ϣ�ɲμ�������ʦ�γ���GCC����ĵ���
P.S.�˴���һ��������ĵط����ڣ�forѭ���ж�����task���г�ʼ��ʱʹ����memcpyֱ�ӽ��Ѿ���ʼ����0�Ž�����Ϣ���Ƶ����������ϣ�����������Ե���Ϣ�����ġ����Ǻ������Խ�memcpyɾ����ֱ�ӶԽ��̵�ÿһ��������0�Ž�����Ϣ���и�ֵ��ȴ���������С���һ����һ�ֺ�1�Ž��̵�3�Ž����ٵ�0�Ž���ʱ�����������Щ������ͷ�ԣ�ϣ�����˽���˿������Ը�֪��
my_process��һ����ѭ������ÿѭ��һǧ��������Ϣ���鿴�Ƿ��е����������У����е��ȣ����Ⱥ�������Ⱥ�Ľ��̵���Ϣ�����ޣ������������Ϣ�����Ⱥ���Ϊmy_schedule��
2��myinterrupt.c
����17-20�е������У�ǰ����������mymain.c�ж���ı��������ⲿ������ֻ��time_count�Ƕ��壬ģ����Ҫ���Ľ����Ƿ���ȵ�ʱ��Ƭ���������my_timer_handler��
void my_timer_handler(void)
{
#if 1
if(time_count%1000 == 0 && my_need_sched != 1)
{
printk(KERN_NOTICE ">>>my_timer_handler here<<<\n");
my_need_sched = 1;
}
time_count ++ ;
#endif
return;
}
����ѭ��һǧ�Σ��ҵ���λΪ0ʱ��������1��ʹ��my_main.c�е�my_process���Խ����������ȡ�
my_schedule����������Ĺؼ�����ʵ�ֵ��ǽ��̵��������л�����˵��Ҫ���ǽ�ǰһ�����̵������Ϣ���棬��������һ�����̵������Ϣ���Ӷ���ɽ��̵��л���
�����������������һ������Ǹý����Ѿ�ִ�й�����stateΪ0��,��ʱִ������һ�δ��룺
my_current_task = next;
printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid);
/* switch to next process */
asm volatile(
"pushl %%ebp\n\t" /* save ebp */
"movl %%esp,%0\n\t" /* save esp */
"movl %2,%%esp\n\t" /* restore esp */
"movl $1f,%1\n\t" /* save eip */
"pushl %3\n\t"
"ret\n\t" /* restore eip */
"1:\t" /* next process start here */
"popl %%ebp\n\t"
: "=m" (prev->thread.sp),"=m" (prev->thread.ip)
: "m" (next->thread.sp),"m" (next->thread.ip)
);
���Խ����̵��л�������һ����Ӧ�ĺ������ã����Ⱥ浱ǰ���̵�ebp��esp��Ȼ����½��̶ϵ�ָ�esp�����浱ǰ���̵�eip�������½��̵�eip��
�ڶ��������������δִ�й�����state��Ϊ0������ִ������Ĵ�����н����л���������Ĵ��벻ͬ���ǣ����ﻹ���½��̵�ebp�����˸�ֵ�����½��̵�sp������esp��ebp��
next -> state = 0;
my_current_task = next;
printk(KERN_NOTICE ">>>switch %d to %d<<<\n", prev -> pid, next -> pid);
asm volatile(
"pushl %%ebp\n\t"
"movl %%esp, %0\n\t"
"movl %2, %%esp\n\t"
"movl %2, %%ebp\n\t"
"movl $1f, %1\n\t"
"pushl %3\n\t"
"ret\n\t"
: "=m" (prev -> thread.sp), "=m" (prev -> thread.ip)
: "m" (next -> thread.sp), "m" (next -> thread.ip)
);
����������������Ի�ı���movl $1f, %1\n\t����ָ�$1f����˼�����Ѱ�ұ��Ϊ1�ĵط�������ط��ڵ�һ�����������У��ڵڶ�������������û�С������Һܺ������1�Ƿ�ָ��ͬһ���ط�������ʹ��objdump -s -d myinterrupt.o�����ɵ�myinterrupt.o�ļ����в鿴���������ͼ��ʾ��
�ɼ����߾������Ϊmovl $0x12f, 0x2008(%esi)���ɼ�������ָ��λ������ͬ�ģ���Ϊesi�����Ϸ�������Ϊ0�����������ʹ��mov $1b, %1ʱmake�ᱨ��˵���ҵ����1�������½���state��Ϊ0������У���ʹ��д��һ��Ҳ��õ���ȷ�ij�����������������ʵ���Dz�̫�����
����ʵ���ĵ�
���ϣ����ʵ������ò����ѣ������˼��Ҳ��̫�ѣ�Ū����˽����л���;��ò����ѣ�����ϸ�ڵ��������Щ���ѵġ���������������������ģ�����ϸ���ϵ��漰��һЩ�������ϸ�ڵĶ�����ʹ�����������Լ���ϸ�鿴��ʦ�Ŀγ�Ҳ���õ��ܺõĽ��͡���˵������ˮƽ��Ȼ����������Ҫ��ǿ��ϣ�����Ŀγ��ܸ���Ŭ����
�������ø��µ�ַ��//m.ajphoenix.com/linux/28950.html