// int debug_wait_queue_get();
#define __ring3text__ __attribute__((__section__(".ring3.text")))
-#define __ring3data__ __attribute__((__section__(".ring3.data"), __aligned__(PAGE_SIZE)))
-#define __ring3bss__ __attribute__((__section__(".ring3.bss"), __aligned__(PAGE_SIZE)))
-char __ring3data__ ring3_stack[PAGE_SIZE] = {0};
-char __ring3bss__ ring3_bss[PAGE_SIZE + 1234];
int ring3_sysctest();
void __ring3text__ __attribute__((__aligned__(PAGE_SIZE))) ring3_entry() {
while (1) {
- ring3_sysctest();
+ int __sysc_ret__ = 0;
+
+ // 下面这段汇编中的 ring3_entry 和 sysexit_return_address的地址都是内核地址
+ // 然而在用户态用的代码地址是从0x08000000开始的
+ // 因此为了算了systexit返回的正确地址
+ // 需要借助ring3_entry算出sysexit_return_address相对ring3_entry的偏移量
+ // 再把这个偏移量加上0x08000000就是正确的sysexit的地址
+
+ // 必需注意这里的sysexit_return_address并不是sysexit指令返回的地址
+ // sysexit指令返回的是编译在内核中的一段代码地址,这个地址已经被设成内核和用户态共享
+ // 在内核中的那段代码里会利用存在栈上的sysexit_return_address返回到
+ // sysexit_return_address处
+ asm volatile(
+ "leal sysexit_return_address, %%ebx;"
+ "subl %%ecx, %%ebx;"
+ "addl $0x08000000, %%ebx;" // 算出sysexit_return_address在用户态的实际地址
+ "pushl %%ebx;" // 把这个地址保存在栈上,内核sysexit会返回到一段共享代码上
+ // 共享代码会利用保存在栈上的地址返回到sysexit_return_address处
+ "pushl $0;"
+ "pushl $0;"
+ "pushl %%ebp;"
+ "movl %%esp, %%ebp;"
+ "sysenter;"
+ "sysexit_return_address:"
+ : "=a"(__sysc_ret__)
+ : "a"(SYSC_TEST), "c"(ring3_entry));
}
}
-static int __ring3text__ __volatile__ __ring3_syscall0(int nr) {
- int __sysc_ret__ = 0;
- extern void sysenter;
- asm volatile("leal sysenter, %%ebx;call *%%ebx;" : "=a"(__sysc_ret__) : "a"(nr));
- return __sysc_ret__;
-}
-int __ring3text__ _ring3_syscall0(int nr) { return __ring3_syscall0(nr); }
-int __ring3text__ ring3_sysctest() { return _ring3_syscall0(SYSC_TEST); }
-
-void user_task_entry() {
- // printk("user_task_entry: %08x\n", ring3_entry);
-
- // unsigned long ring3_text_page = va2pa(alloc_one_page(0));
- // unsigned long ring3_data_page = va2pa(alloc_one_page(0));
- // unsigned long ring3_bss_page = va2pa(alloc_one_page(0));
+void user_task_entry(char *name) {
+ strcpy(current->name, name);
unsigned long ring3_text_page = va2pa(ring3_entry);
- unsigned long ring3_data_page = va2pa(ring3_stack);
unsigned long ring3_bss_page = va2pa(alloc_one_page(0));
unsigned long *pt_text_page = (unsigned long *)(alloc_one_page(0));
- unsigned long *pt_data_page = (unsigned long *)(alloc_one_page(0));
unsigned long *pt_bss_page = (unsigned long *)(alloc_one_page(0));
+
unsigned long *p = (unsigned long *)(pa2va(current->cr3));
printk("page dir : %x %x %x %x\n", p, pt_text_page, ring3_text_page);
printk("pt bss page %x %x", pt_bss_page, ring3_bss_page);
// text: 0x0800_0000
- // data: 0x2000_0000
// bss: 0x3000_0000
unsigned long text_at = 0x08000000;
- unsigned long data_at = 0x20000000;
unsigned long bbs_at = 0x30000000;
- p[text_at >> 22] = (unsigned long)va2pa(pt_text_page) | PAGE_P | PAGE_WR | PAGE_US;
- pt_text_page[0] = ring3_text_page | 7;
- p[data_at >> 22] = (unsigned long)va2pa(pt_data_page) | PAGE_P | PAGE_WR | PAGE_US;
- pt_data_page[0] = ring3_data_page | 7;
+ p[text_at >> 22] = (unsigned long)va2pa(pt_text_page) | PAGE_P | PAGE_US;
+ pt_text_page[0] = ring3_text_page | PAGE_P | PAGE_US;
p[bbs_at >> 22] = (unsigned long)va2pa(pt_bss_page) | PAGE_P | PAGE_WR | PAGE_US;
- pt_bss_page[0] = ring3_bss_page | 7;
+ pt_bss_page[0] = ring3_bss_page | PAGE_P | PAGE_WR | PAGE_US;
//
LoadCR3(current->cr3);
asm volatile("sysexit;" ::"d"(0x08000000), "c"(0x30000000 + PAGE_SIZE - 100));
}
-void init_task_entry() {
+void init_task_entry(char *name) {
int cnt = 0;
pid_t id = sysc_getpid();
+ strcpy(current->name, name);
+
// 赋予不同的优先级
current->priority = id * 30;
if (current->priority <= 0) {
while (1) {
// sysc_test();
- printl(MPL_TASK_1 + id - 1, "task:%d [%08x] weight %d cnt %d", id, current, current->weight, cnt++);
+ // printl(MPL_TASK_0 + id, "task:%d [%08x] weight %d cnt %d", id, current, current->weight, cnt++);
// printl(MPL_TASK_1, "task:%d [%08x] weight %d cnt %d", id, current, current->weight, cnt++);
int v = 0; // debug_wait_queue_get();
// printk("task:%d wait queue get %d\n", id, v);
regs.fs = SELECTOR_KRNL_DS;
regs.gs = SELECTOR_KRNL_DS;
+ regs.ebx = (unsigned long)name; // 用ebx传递参数
+
int pid = do_fork(®s, FORK_KRNL);
printk("kernel[%s] task pid is %d\n", name, pid);
int cnt = 0;
while (1) {
// sysc_test();
- printl(MPL_ROOT, "root:0 [%08x] weight %d cnt %d", current, root_task.weight, cnt++);
+ // printl(MPL_TASK_0, "root:0 [%08x] weight %d cnt %d", current, root_task.weight, cnt++);
// printk("root:0 [%08x] weight %d cnt %d", current, current->weight, cnt++);
asm("sti;hlt;");
// asm("nop;nop;nop;");
unsigned long iflags;
irq_save(iflags);
- printl(MPL_ROOT, "root:%d [%08x] cnt %u", root_task.pid, &root_task, root_task.cnt);
+ // printl(MPL_ROOT, "root:%d [%08x] cnt %u", root_task.pid, &root_task, root_task.cnt);
float min_ratio = 1.0;
list_for_each_safe(pos, t, &all_tasks) {
p = list_entry(pos, task_union, list);
- printl(MPL_ROOT + p->pid, "task:%d [%08x] state %s cnt %u", p->pid, p, task_state(p->state), p->cnt);
-
if (p->state != TASK_RUNNING) {
continue;
}
if (prev != next) {
// printk("switch to: %s:%d\n", next->name, next->pid);
+
+ list_for_each_safe(pos, t, &all_tasks) {
+ p = list_entry(pos, task_union, list);
+ printl(MPL_TASK_0 + p->pid, "%s%4s:%d [%08x] state %s weight %03d cnt %u", sel == p ? ">" : " ", p->name,
+ p->pid, p, task_state(p->state), p->weight, p->cnt);
+ }
context_switch(prev, next);
}
}