/*
*--------------------------------------------------------------------------
- * File Name: reboot.S
+ * File Name: multiboot.S
*
* Description: none
*
#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"
u32 edi;
u32 esi;
u32 ebp;
- u32 esp;
u32 ebx;
u32 edx;
u32 ecx;
u32 eip;
u16 cs, _cs;
u32 eflags;
- u32 _esp;
+ u32 esp;
u16 ss, _ss;
} __attribute__((packed)) pt_regs_t;
#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; \
#define TASK_SIZE 4096
+#define TI_preempt_cnt 0
+
#ifndef ASM
#include <page.h>
#include <list.h>
{
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;
#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) \
_irq_handler:
SAVE_REGS
- movw %ss,%ax
+ movw %ss, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
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
#include <irq.h>
#include <errno.h>
#include <assert.h>
+#include <task.h>
irq_desc_t irq_desc[NR_IRQS];
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);
action = action->next;
}
+ cli();
p->chip->enable(irq);
+
+ current->preempt_cnt--;
}
{
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);
.global ret_from_fork_krnl
.global sysexit
-#define EAX 28
-#define EDX 20
-
syscall_entry:
movl (%esp),%esp
call *sysc_handler_table(,%eax,4)
syscall_exit:
- movl %eax, EAX(%esp)
+ movl %eax, PT_REGS_EAX(%esp)
RESTORE_REGS
jmp syscall_exit
ret_from_fork_krnl:
- movl EDX(%esp), %edx
+ movl PT_REGS_EDX(%esp), %edx
call *%edx
#call do_exit
return dest;
}
-void memset(char *dest, char ch, size_t size)
+void memset(char *dest, char ch, size_t size)
{
while(size--) *dest++ = ch;
}
setup_sysc();
setup_pci();
- setup_irqs();
-
setup_tasks();
+ setup_irqs();
+
return;
while(1); // TODO MODIFY CODE BELOW