From: acevest Date: Wed, 31 Dec 2025 12:28:19 +0000 (+0800) Subject: 继续优化ring3代码 X-Git-Url: http://repos.zhaoyanbai.com/?a=commitdiff_plain;h=2b64fa5fa98cd4b0d6bbe3ddd0210d25c8ee69dd;p=kernel.git 继续优化ring3代码 --- diff --git a/kernel/ring3.S b/kernel/ring3.S index b4dc911..a187fa8 100644 --- a/kernel/ring3.S +++ b/kernel/ring3.S @@ -27,40 +27,62 @@ ring3_entry: nop nop - movl $SYSC_RAND, %eax + pushl $0 # 模拟一个内核不需要的参数1 + pushl $SYSC_RAND # 系统调用号 call ring3_syscall + addl $8, %esp movl %eax, %ecx andl $0x000000FF, %ecx - movl $SYSC_WAIT, %eax + pushl %ecx # 参数1 + pushl $SYSC_WAIT # 系统调用号 call ring3_syscall + addl $8, %esp + + + # 纯消耗CPU时间 + movl $0x0F0F0F0F, %ecx +1: + loop 1b + nop nop jmp ring3_entry -# eax 系统调用号 -# ecx 参数1 +# 传入: 系统调用号, 参数1 ring3_syscall: pushl %ebp + movl %esp, %ebp + + pushl %ebx # 用于保存参数1 + pushl %edi # 用于保存sysexit后返回用户态的地址 + # ebp用于保存sysexit后的用户态栈,不过已经保存了,这里不用再保存 - pushl %ebx - pushl %edi + movl 0x08(%ebp), %eax # 系统调用号 + movl 0x0C(%ebp), %ebx # 参数1 - movl %ecx, %ebx + # 获取call get_eip后的地址 call get_eip get_eip: # 这里popl取得的就是上一个call指令自动压入栈中的地址 # 这个地址就是当前指令的地址 popl %edi - addl $8,%edi - movl %esp, %ebp; + + # 算出sysenter后的地地址 + addl $8, %edi + + # 设置sysexit返回用户态后的栈位置 + movl %esp, %ebp sysenter + # 从栈中恢复保存的易失寄存器 popl %edi popl %ebx + + # popl %ebp ret diff --git a/kernel/sched.c b/kernel/sched.c index 73bfa5a..48dd2c0 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -172,10 +172,10 @@ const char *task_state(unsigned int state) { void debug_print_all_tasks() { task_t *p = 0; list_head_t *pos = 0, *t = 0; - printl(MPL_TASK_TITLE, " NAME STATE TK/PI REASON SCHED KEEP TURN"); + printl(MPL_TASK_TITLE, " NAME STATE TK/PI REASON TICKS SCHED KEEP TURN"); list_for_each_safe(pos, t, &all_tasks) { p = list_entry(pos, task_t, list); - printl(MPL_TASK_0 + p->pid, "%08x %-6s:%u %s %02u/%02u %-10s %-10u %-10u %-10u", p, p->name, p->pid, + printl(MPL_TASK_0 + p->pid, "%08x %-6s:%u %s %02u/%02u %-10s %-9u %-9u %-9u", p, p->name, p->pid, task_state(p->state), p->ticks, p->priority, p->reason, p->sched_cnt, p->sched_keep_cnt, p->turn); } } diff --git a/kernel/task_user.c b/kernel/task_user.c index 231e019..535da79 100644 --- a/kernel/task_user.c +++ b/kernel/task_user.c @@ -28,11 +28,11 @@ void flush_tlb() { } void user_task_entry() { - current->priority = 7; + current->priority = 79; // ring3只占用一个page,页的起始位置放的是代码,页的末尾当栈用 // ring3的地址直接是物理地址 - extern char ring3_page_begin; + extern uint8_t ring3_page_begin; paddr_t ring3_page_addr = (paddr_t)&ring3_page_begin; // 不在内核空间的物理地址 paddr_t ring3_stack_top = ring3_page_addr + PAGE_SIZE; @@ -45,5 +45,15 @@ void user_task_entry() { // 这里减去PAGE_SIZE是因为栈是向下生长的,所以得把栈顶虚拟地址空间的前一页映射到ring3_page page_map((ring3_stack_top_vaddr-PAGE_SIZE), ring3_page_addr, PAGE_P | PAGE_US | PAGE_WR); + + { + // 在ring3_page里非代码的地方插入特征值方便调试 + extern uint8_t ring3_text_end; + uint32_t ring3_text_size = (&ring3_text_end) - (&ring3_page_begin); + for(uint32_t i = ring3_text_size; i