#include <hd.h>
#include <irq.h>
#include <system.h>
-//void hd_handler(pPtRegs regs, unsigned int irq)
-void hd_handler(unsigned int irq, pPtRegs regs, void *dev_id)
+//void hd_handler(pt_regs_t * regs, unsigned int irq)
+void hd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
{
printk("hd_handler:%d ", irq);
}
extern void reboot();
extern void poweroff();
-void kbd_handler(unsigned int irq, pPtRegs regs, void *dev_id)
+void kbd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
{
unsigned char ScanCode;
//printk("%s\n", dev_id);
typedef struct irqaction
{
- //void (*handler)(pPtRegs regs, unsigned int irq);
- void (*handler)(unsigned int irq, pPtRegs regs, void *dev_id);
+ //void (*handler)(pt_regs_t * regs, unsigned int irq);
+ void (*handler)(unsigned int irq, pt_regs_t * regs, void *dev_id);
const char *dev_name;
void *dev_id;
struct irqaction *next;
extern irq_desc_t irq_desc[];
extern irq_desc_t no_irq_desc;
int request_irq(unsigned int irq,
- //void (*handler)(pPtRegs, unsigned int),
- void (*handler)(unsigned int, pPtRegs, void *),
+ //void (*handler)(pt_regs_t *, unsigned int),
+ void (*handler)(unsigned int, pt_regs_t *, void *),
const char *devname,
void *dev_id);
#define bootmem_alloc_pages(n) alloc_bootmem((n)*PAGE_SIZE, PAGE_SIZE)
+
+kmem_cache_t *kmem_cache_create(const char *name, size_t size, size_t align);
+void *kmem_cache_alloc(kmem_cache_t *cache, gfp_t gfpflags);
};
+
// TODO Remove
typedef struct page_
{
#include <task.h>
#define NR_TASKS 3
-//pTask tTasks[NR_TASKS];
+//task_union * tTasks[NR_TASKS];
//void add_task();
-void SetupTasks();
+//void SetupTasks();
//void test_taskA();
//void test_taskB();
-//unsigned long schedule(pPtRegs regs);
+//unsigned long schedule(pt_regs_t * regs);
unsigned long schedule();
pid_t get_next_pid();
-void init_tsk_cr3(pTask);
+void init_tsk_cr3(task_union *);
inline void wake_up(pWaitQueue wq);
*--------------------------------------------------------------------------
*/
-#ifndef _SYSTEM_H
+#ifndef _SYSTEM_H
#define _SYSTEM_H
#include <page.h>
INDEX_EMP8,
INDEX_TSS,
};
-// pushad push eax, ecx, edx, ebx, esp, ebp, esi, edi
-typedef struct
+// pushal push eax, ecx, edx, ebx, esp, ebp, esi, edi
+typedef struct pt_regs
{
u32 edi;
u32 esi;
u32 ebp;
- u32 _esp;
+ u32 esp;
u32 ebx;
u32 edx;
u32 ecx;
- u32 eax; // 因为在系统调用中用来带调用号,就无法传送参数
- // 所以把eax放在这个位置
+ u32 eax;
u16 ds, _ds;
u16 es, _es;
u16 fs, _fs;
u32 eip;
u16 cs, _cs;
u32 eflags;
- u32 esp;
+ u32 _esp;
u16 ss, _ss;
-} PtRegs, *pPtRegs;
+} pt_regs_t;
typedef unsigned long Dev, *pDev;
#endif
-#define SAVE_REGS \
- cld; \
- pushl %gs; \
- pushl %fs; \
- pushl %es; \
- pushl %ds; \
+#define SAVE_REGS \
+ cld; \
+ pushl %gs; \
+ pushl %fs; \
+ pushl %es; \
+ pushl %ds; \
pushal;
#define RESTORE_REGS \
- popal; \
- popl %ds; \
- popl %es; \
- popl %fs; \
+ popal; \
+ popl %ds; \
+ popl %es; \
+ popl %fs; \
popl %gs;
-#define PRIVILEGE_KRNL 0x0
-#define PRIVILEGE_USER 0x3
+#define PRIVILEGE_KRNL 0x0
+#define PRIVILEGE_USER 0x3
-#define INDEX_UCODE 3
-#define INDEX_UDATA 4
-/* *8 == <<3 .但要用于汇编文件 <<3 不行. */
+#define INDEX_UCODE 3
+#define INDEX_UDATA 4
+/* *8 == <<3 . but <<3 is not right for asm code. */
#define SELECTOR_KRNL_CS (INDEX_KCODE*8)
#define SELECTOR_KRNL_DS (INDEX_KDATA*8)
#define SELECTOR_KRNL_SS SELECTOR_KRNL_DS
{
struct
{
- PtRegs regs;
+ pt_regs_t regs;
unsigned long esp0; /* 指示发生在用户态的中断在进入
内核态后的栈位置 */
};
unsigned char stack[TASK_SIZE];
-} task_struct;
+} task_union;
+task_union *alloc_task_union();
-typedef task_struct Task;
-typedef task_struct *pTask;
-#define ROOT_TSK_PID (1)
+static inline task_union *get_current()
+{
+ task_union *tsk;
+ asm("andl %%esp, %0;":"=r"(tsk):"0"(~(TASK_SIZE-1)));
+ return tsk;
+}
+
+#define current get_current()
+
+#define ROOT_TSK_PID (0)
-extern pTask current;
extern ListHead tsk_list;
#define add_tsk2list(tsk) list_add_tail((&(tsk)->list), &tsk_list)
static unsigned int jiffies = 0;
-void clk_handler(unsigned int irq, pPtRegs regs, void *dev_id)
+void clk_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
{
jiffies++;
/* 准备内核栈的数据并从ret_from_fork返回 */
- pPtRegs regs = ((pPtRegs)(TASK_SIZE+(unsigned long)current)) - 1;
+ pt_regs_t * regs = ((pt_regs_t *)(TASK_SIZE+(unsigned long)current)) - 1;
extern void ret_from_fork();
- memset((void*)regs, 0, sizeof(PtRegs));
+ memset((void*)regs, 0, sizeof(pt_regs_t));
regs->ss = SELECTOR_USER_DS;
regs->ds = SELECTOR_USER_DS;
regs->es = SELECTOR_USER_DS;
*/
#include <sched.h>
-#if 1
-int sysc_fork()
+
+int sysc_fork(pt_regs_t regs)
+{
+ return do_fork(®s, 0);
+}
+
+extern void ret_from_fork();
+int do_fork(pt_regs_t *regs, unsigned long flags)
{
- // 先分配一个进程控制结构
- task_struct *tsk;
- // TODO tsk = get_unused_task_pcb();
+ task_union *tsk;
+ tsk = alloc_task_union();
if(tsk == NULL)
panic("can not malloc PCB");
- //printk("CHILD:%08x\n", tsk);
-
- memcpy(tsk, current, sizeof(task_struct));
+ memcpy(tsk, current, sizeof(task_union));
tsk->pid = get_next_pid();
- tsk->ppid = current->pid;
+ tsk->ppid = current->pid;
+
+ pt_regs_t *child_regs = ((pt_regs_t *) (TASK_SIZE+(unsigned long) tsk)) - 1;
+
+ *child_regs = *regs;
+
+ child_regs->eax = 0;
+
+ regs->eax = 0x00;
+ tsk->esp0 = TASK_SIZE + (unsigned long) tsk;
+ tsk->esp = (unsigned long) child_regs;
+ tsk->eip = (unsigned long) ret_from_fork;
+
+ tsk->state = TASK_RUNNING;
+
+ return (int)tsk->pid;
+}
+#if 0
init_tsk_cr3(tsk);
int i, j;
//tsk->regs = *regs;
//tsk->regs.eax = 0x00;
//tsk->regs.eflags |= 0x200; //enable IF
- pPtRegs regs = ((pPtRegs)(TASK_SIZE+(unsigned long) tsk))-1;
+ //TODO pPtRegs regs = ((pPtRegs)(TASK_SIZE+(unsigned long) tsk))-1;
extern void ret_from_fork();
regs->eax = 0x00;
tsk->esp0 = TASK_SIZE + (unsigned long) tsk;
.ack = mask_ack_i8259_irq,
};
-void do_i8259_IRQ(pPtRegs regs, unsigned int irq)
+void do_i8259_IRQ(pt_regs_t * regs, unsigned int irq)
{
TSS tss;
System system;
+Desc idt[NIDT];
+Desc gdt[NGDT];
char __initdata kernel_init_stack[KRNL_INIT_STACK_SIZE] __attribute__ ((__aligned__(PAGE_SIZE)));
while(1)
{
asm("hlt;");
+ sysc_test();
//syscall0(SYSC_TEST);
}
pid_t pid;
while(1); \
}while(0);
-void doDivideError(PtRegs regs)
+void doDivideError(pt_regs_t regs)
{
DIE_MSG();
}
-void doDebug(PtRegs regs)
+void doDebug(pt_regs_t regs)
{
DIE_MSG();
}
-void doNMI(PtRegs regs)
+void doNMI(pt_regs_t regs)
{
DIE_MSG();
}
-void doBreakPoint(PtRegs regs)
+void doBreakPoint(pt_regs_t regs)
{
DIE_MSG();
}
-void doOverFlow(PtRegs regs)
+void doOverFlow(pt_regs_t regs)
{
DIE_MSG();
}
-void doBoundsCheck(PtRegs regs)
+void doBoundsCheck(pt_regs_t regs)
{
DIE_MSG();
}
-void doInvalidOpcode(PtRegs regs)
+void doInvalidOpcode(pt_regs_t regs)
{
DIE_MSG();
}
-void doDeviceNotAvailable(PtRegs regs)
+void doDeviceNotAvailable(pt_regs_t regs)
{
DIE_MSG();
}
-void doDoubleFault(PtRegs regs)
+void doDoubleFault(pt_regs_t regs)
{
DIE_MSG();
}
-void doCoprocSegOverRun(PtRegs regs)
+void doCoprocSegOverRun(pt_regs_t regs)
{
DIE_MSG();
}
-void doInvalidTss(PtRegs regs)
+void doInvalidTss(pt_regs_t regs)
{
DIE_MSG();
}
-void doSegNotPresent(PtRegs regs)
+void doSegNotPresent(pt_regs_t regs)
{
DIE_MSG();
}
-void doStackFault(PtRegs regs)
+void doStackFault(pt_regs_t regs)
{
DIE_MSG();
}
-void doGeneralProtection(PtRegs regs)
+void doGeneralProtection(pt_regs_t regs)
{
DIE_MSG();
}
-void doPageFault(PtRegs regs)
+void doPageFault(pt_regs_t regs)
{
//DIE_MSG();
void *addr;
do_wp_page(addr);
}
}
-void doCoprocError(PtRegs regs)
+void doCoprocError(pt_regs_t regs)
{
DIE_MSG();
}
.status = 0,
.depth = 0
};
-__attribute__ ((regparm(1))) void irq_handler(pPtRegs regs)
+__attribute__ ((regparm(1))) void irq_handler(pt_regs_t * regs)
{
unsigned int irq = regs->irq;
int request_irq( unsigned int irq,
- void (*handler)(unsigned int, pPtRegs, void *),
+ void (*handler)(unsigned int, pt_regs_t *, void *),
const char *devname,
void *dev_id)
{
+++ /dev/null
-/*
- * ------------------------------------------------------------------------
- * File Name: processor.c
- * Author: Zhao Yanbai
- * Thu Mar 27 23:44:12 2014
- * Description: none
- * ------------------------------------------------------------------------
- */
-#include "processor.h"
-
-Desc idt[NIDT];
-Desc gdt[NGDT];
#include "sched.h"
#include "assert.h"
+#include "mm.h"
-pTask current;
-
-task_struct root_task __attribute__((__aligned__(PAGE_SIZE)));
+task_union root_task __attribute__((__aligned__(PAGE_SIZE)));
pid_t get_next_pid()
{
return g_pid++;
}
-inline void load_cr3(pTask tsk)
+inline void load_cr3(task_union * tsk)
{
//printk("tsk %08x cr3: %08x\n",tsk, tsk->cr3);
asm("movl %%eax,%%cr3;"::"a"(tsk->cr3));
//int j=10000; while(j--);
}
-void init_tsk_cr3(pTask tsk)
+void init_tsk_cr3(task_union * tsk)
{
tsk->cr3 = pa2va(get_phys_pages(1));
*/
}
+kmem_cache_t *task_union_cache;
+
void setup_tasks()
{
- /* 初始化第一个特殊的进程 */
init_root_tsk();
+
+ kmem_cache_t *task_union_cache = kmem_cache_create("task_union", sizeof(task_union), PAGE_SIZE);
+ if(0 == task_union_cache)
+ panic("setup tasks failed. out of memory");
+
#if 0
add_task(test_taskB);
add_task(test_taskA);
#endif
}
+task_union *alloc_task_union()
+{
+ return (task_union *) kmem_cache_alloc(task_union_cache, 0);
+}
+
-task_struct *get_unused_task_pcb()
+task_union *get_unused_task_pcb()
{
unsigned int i;
for(i=0; i<TASK_CNT; ++i)
}
}
-inline pTask get_next_tsk()
+inline task_union * get_next_tsk()
{
#if 0
static unsigned int inx = 0;
unsigned int i = 0;
- task_struct *tsk = root_task;
+ task_union *tsk = root_task;
for(i=0; i<TASK_CNT; ++i)
{
inx = (inx + i) % TASK_CNT;
- task_struct *p = root_task + inx;
+ task_union *p = root_task + inx;
if(tsk->state == TASK_RUNNING)
{
return 0;
}
-inline void set_esp0(pTask tsk)
+inline void set_esp0(task_union * tsk)
{
tss.esp0 = tsk->esp0;
}
set_esp0(current);
}
-inline void context_switch(pTask prev, pTask next)
+inline void context_switch(task_union * prev, task_union * next)
{
- //pTask last;
+ //task_union * last;
unsigned long eax, ebx, ecx, edx, esi, edi;
//asm("xchg %bx, %bx");
asm volatile(
unsigned long schedule()
{
#if 0
- pTask tsk, prev, next;
+ task_union * tsk, prev, next;
cli(); // For Safe.
tsk = current;
syscall_entry:
movl (%esp),%esp
+ pushl $(SELECTOR_USER_SS)
+ pushl %ebp
+ pushfl
+ pushl $(SELECTOR_USER_CS)
+ pushl $sysexit
+ pushl $0
+
SAVE_REGS
- pushl %eax
+ pushl %eax
movw %ss, %ax
movw %ax, %ds
movw %ax, %es
movl %eax, EAX(%esp)
RESTORE_REGS
+
+ # addl $20, %esp # no need now
leal sysexit, %edx
movl %ebp, %ecx
#include <sched.h>
#include <assert.h>
#include <system.h>
-pTask tTasks[NR_TASKS];
+task_union * tTasks[NR_TASKS];
#if 0
void SetuptTasks()
{
#if 0
assert(fun != NULL);
- pTask tsk = NULL;
+ task_union * tsk = NULL;
tsk = kmalloc_old(sizeof(Task));
if(tsk == NULL)
panic("shit happens");
tsk->ppid = 0;
init_tsk_cr3(tsk);
- pPtRegs r;
+ pt_regs_t * r;
r = &tsk->regs;
- memset((void *)r, 0, sizeof(PtRegs));
+ memset((void *)r, 0, sizeof(pt_regs_t));
r->ds = r->es = r->fs = r->gs = SELECTOR_USER_DS;
r->eip = (unsigned long)fun;
r->cs = SELECTOR_USER_CS;
void add_task(void *fun)
{
assert(fun != NULL);
- pTask tsk = NULL;
+ task_union * tsk = NULL;
int i=0;
for(i=0; i<NR_TASKS; i++)
{
if(i == NR_TASKS)
panic("tasks full");
- pPtRegs r;
- r = &tsk->regs;//(pPtRegs)(TASK_SIZE + (unsigned long)tsk);
+ pt_regs_t * r;
+ r = &tsk->regs;//(pt_regs_t *)(TASK_SIZE + (unsigned long)tsk);
//printk("Add Tsk: tsk:%08x r:%08x ", tsk, r);
//r--;
- //printk("r:%08x sizeof regs:%x ", r, sizeof(PtRegs));
+ //printk("r:%08x sizeof regs:%x ", r, sizeof(pt_regs_t));
- memset((void *)r, 0, sizeof(PtRegs));
+ memset((void *)r, 0, sizeof(pt_regs_t));
//printk("USER CS: %x\n", SELECTOR_USER_CS);
//printk("USER DS: %x\n", SELECTOR_USER_DS);
r->ds = r->es = r->fs = r->gs = SELECTOR_USER_DS;
return true;
}
-kmem_cache_t *kmem_cache_create(const char *name,
- size_t size,
- size_t align)
-{
-
-
- return 0;
-}
-
static bool kmem_cache_init(kmem_cache_t *cache,
const char *name,
slub_free(cache, page, addr);
}
+kmem_cache_t *kmem_cache_create(const char *name, size_t size, size_t align)
+{
+ kmem_cache_t *cache = kmalloc(sizeof(kmem_cache_t), 0);
+ if(cache == 0)
+ return 0;
+
+ kmem_cache_init(cache, name, size, align);
+
+ list_add(&(cache->list), &slub_caches);
+
+ return cache;
+}
+
void init_slub_system()
{
irq_desc[i].chip = &i8259_chip;
}
- //extern void kbd_handler(pPtRegs, unsigned int); //extern void clk_handler(pPtRegs, unsigned int);
- //extern void hd_handler(pPtRegs, unsigned int);
- void kbd_handler(unsigned int irq, pPtRegs regs, void *dev_id);
- void clk_handler(unsigned int irq, pPtRegs regs, void *dev_id);
- void hd_handler(unsigned int irq, pPtRegs regs, void *dev_id);
+ //extern void kbd_handler(pt_regs_t *, unsigned int); //extern void clk_handler(pt_regs_t *, unsigned int);
+ //extern void hd_handler(pt_regs_t *, unsigned int);
+ void kbd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id);
+ void clk_handler(unsigned int irq, pt_regs_t * regs, void *dev_id);
+ void hd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id);
request_irq(0x00, clk_handler, "Intel 8254", "Clock Chip");
request_irq(0x01, kbd_handler, "Intel 8042", "PS/2 Keyboard");
request_irq(0x0E, hd_handler, "IDE", "IDE");