]> Zhao Yanbai Git Server - kernel.git/commitdiff
support preempt
authorAceVest <zhaoyanbai@126.com>
Wed, 7 May 2014 16:40:27 +0000 (00:40 +0800)
committerAceVest <zhaoyanbai@126.com>
Wed, 7 May 2014 16:40:27 +0000 (00:40 +0800)
boot/multiboot.S
include/system.h
include/task.h
kernel/interrupts.S
kernel/irq.c
kernel/sched.c
kernel/syscall.S
lib/string.c
setup/setup.c

index dcce87bab3993c55015f0f0470c05300e72e4140..7b8feb3162da19163abf1a2ffeda31f38708dcf2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *--------------------------------------------------------------------------
- *   File Name: reboot.S
+ *   File Name: multiboot.S
  * 
  * Description: none
  * 
index f0f66e96b8962fadfa230b37533ff04effd0caf5..61c816728361655b7bdd7adaddea44111797ceb4 100644 (file)
 #include <assert.h>
 #define KRNLADDR    PAGE_OFFSET
 
+#define PT_REGS_EDI     0
+#define PT_REGS_ESI     4
+#define PT_REGS_EBP     8
+#define PT_REGS_EBX     12
+#define PT_REGS_EDX     16
+#define PT_REGS_ECX     20
+#define PT_REGS_EAX     24
+#define PT_REGS_DS      28
+#define PT_REGS_ES      32
+#define PT_REGS_FS      36
+#define PT_REGS_GS      40
+#define PT_REGS_IRQ     44
+#define PT_REGS_EIP     48
+#define PT_REGS_CS      52
+#define PT_REGS_EFLAGS  56
+#define PT_REGS_ESP     60
+#define PT_REGS_SS      64
+
 #ifndef    ASM
 #include "types.h"
 #include "printk.h"
@@ -105,7 +123,6 @@ typedef struct pt_regs
     u32    edi;
     u32    esi;
     u32    ebp;
-    u32    esp;
     u32    ebx;
     u32    edx;
     u32    ecx;
@@ -122,7 +139,7 @@ typedef struct pt_regs
     u32    eip;
     u16    cs, _cs;
     u32    eflags;
-    u32    _esp;
+    u32    esp;
     u16    ss, _ss;
 } __attribute__((packed)) pt_regs_t;
 
@@ -168,17 +185,28 @@ extern    System system;
 
 #endif
 
-
 #define SAVE_REGS       \
     cld;                \
-    pushl    %gs;       \
-    pushl    %fs;       \
-    pushl    %es;       \
-    pushl    %ds;       \
-    pushal;
+    pushl   %gs;        \
+    pushl   %fs;        \
+    pushl   %es;        \
+    pushl   %ds;        \
+    pushl   %eax;       \
+    pushl   %ecx;       \
+    pushl   %edx;       \
+    pushl   %ebx;       \
+    pushl   %ebp;       \
+    pushl   %esi;       \
+    pushl   %edi;
 
 #define RESTORE_REGS    \
-    popal;              \
+    popl    %edi;       \
+    popl    %esi;       \
+    popl    %ebp;       \
+    popl    %ebx;       \
+    popl    %edx;       \
+    popl    %ecx;       \
+    popl    %eax;       \
     popl    %ds;        \
     popl    %es;        \
     popl    %fs;        \
index 73df36f7b1b452d09f66abaa361f8f4203684a5b..f16cb618a58abad5442c75ad0549f2e3b0d9382f 100644 (file)
@@ -15,6 +15,8 @@
 
 #define TASK_SIZE 4096
 
+#define TI_preempt_cnt  0
+
 #ifndef ASM
 #include <page.h>
 #include <list.h>
@@ -37,12 +39,13 @@ typedef union task_union
 {
     struct
     {
+        unsigned long   preempt_cnt;
+
         pt_regs_t        regs;
 
-        unsigned long    esp0;    /* 指示发生在用户态的中断在进入
-                       内核态后的栈位置 */
+        unsigned long    esp0;    /* kernel stack */
 
-        /* 进程切换时用 */
+        /* for context switch */
         unsigned long    esp;
         unsigned long    eip;
 
index 942f8cf58bbc4795d5722b2a28318b31a8e6610b..8ddd209ec2df508098a5e00c0927fe3c6fe32c58 100644 (file)
@@ -16,6 +16,7 @@
 #define ASM
 #include <linkage.h>
 #include <system.h>
+#include <task.h>
 
 #define IRQ_SYMBL(a,b)    irq_0x##a##b_handler
 #define IRQ_LIST(x)    \
@@ -68,7 +69,7 @@ DEF_IRQ(0,F)
 _irq_handler:
     SAVE_REGS
 
-    movw    %ss,%ax
+    movw    %ss, %ax
     movw    %ax, %ds
     movw    %ax, %es
     movw    %ax, %fs
@@ -77,11 +78,26 @@ _irq_handler:
     movl    %esp, %eax
     call    irq_handler
 
+    movl    $-TASK_SIZE, %ebp
+    andl    %esp, %ebp
+
+    movl    PT_REGS_CS(%esp), %eax
+    testl   $0x0003, %eax
+    jz      resume_kernel
+
+resched:
+
     call    schedule
 
-    # movl    current, %esp
-        
+restore_regs:
+
     RESTORE_REGS
     
-    addl    $4,%esp    /* 跳过中断号. */
+    addl    $4, %esp
+
     iret
+
+resume_kernel:
+    cmpl    $0, TI_preempt_cnt(%ebp)
+    jz      resched
+    jmp     restore_regs
index 5ce8c42bd26f51a4a7c993b587a81eeca045fb8c..f92fac0de4c00a248f9548506b304809042e5313 100644 (file)
@@ -17,6 +17,7 @@
 #include <irq.h>
 #include <errno.h>
 #include <assert.h>
+#include <task.h>
 
 irq_desc_t irq_desc[NR_IRQS];
 
@@ -45,8 +46,11 @@ __attribute__ ((regparm(1))) void irq_handler(pt_regs_t *regs)
     irq_desc_t *p = irq_desc + irq;
     irq_action_t *action = p->action;
 
+    current->preempt_cnt++;
+
     p->chip->ack(irq);
     sti();
+
     while(action)
     {
         //action->handler(regs, irq);
@@ -54,7 +58,10 @@ __attribute__ ((regparm(1))) void irq_handler(pt_regs_t *regs)
         action = action->next;
     }
 
+    cli();
     p->chip->enable(irq);
+
+    current->preempt_cnt--;
 }
 
 
index 3afe834fcabed5bf2ae2a8b74ed1ca6fe57cf8e4..0a5ea9c3c547c81589e7352ee0f6de5432ea557a 100644 (file)
@@ -55,6 +55,11 @@ void init_root_tsk()
 {
     int i;
 
+    // never use memset to init root_task
+    // because the stack is at top of the root_task
+    // memset((char*)&root_task, 0, sizeof(root_task));
+
+    root_task.preempt_cnt = 0;
     root_task.pid    = get_next_pid();
     root_task.ppid    = 0;
     INIT_LIST_HEAD(&root_task.list);
index d0b0c90b13128066b905968458494aeadf643e9c..6dbce73a981b9a8e6974b93effec31a957a1376a 100644 (file)
@@ -28,9 +28,6 @@
 .global ret_from_fork_krnl
 .global sysexit
 
-#define EAX 28
-#define EDX 20
-
 syscall_entry:
     movl    (%esp),%esp
 
@@ -57,7 +54,7 @@ syscall_entry:
     call    *sysc_handler_table(,%eax,4)
 
 syscall_exit:
-    movl    %eax, EAX(%esp)
+    movl    %eax, PT_REGS_EAX(%esp)
 
     RESTORE_REGS
 
@@ -78,7 +75,7 @@ ret_from_fork_user:
     jmp     syscall_exit
 
 ret_from_fork_krnl:
-    movl    EDX(%esp), %edx
+    movl    PT_REGS_EDX(%esp), %edx
     call    *%edx
     #call    do_exit
 
index c8bae0f47c8e8b956e581a49f40788ac1ad5091b..87d01b7bfb04a00c52d409e59be85da0aed829f8 100644 (file)
@@ -67,7 +67,7 @@ void *memcpy(void *dest, const void *src, size_t size)
     return dest;
 }
 
-void    memset(char *dest, char ch, size_t size)
+void memset(char *dest, char ch, size_t size)
 {
     while(size--) *dest++ = ch;
 }
index fe42875a2a9dcd63eeff4d4c6573b15bd788c61e..ee845f57287c881a1b490925e42dfbf2cedb8754 100644 (file)
@@ -66,10 +66,10 @@ void setup_kernel()
     setup_sysc();
     setup_pci();
 
-    setup_irqs();
-
     setup_tasks();
 
+    setup_irqs();
+
     return;
     while(1); // TODO MODIFY CODE BELOW