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
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);
}
}
}
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;
// 这里减去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<PAGE_SIZE; i++) {
+ ((uint8_t *)(pa2va(ring3_page_addr)))[i] = 0xCC;
+ }
+ }
+
asm volatile("sysexit;" ::"d"(ring3_page_vaddr), "c"(ring3_stack_top_vaddr));
}
.ring3 :
{
*(.ring3.entry)
+ . = ALIGN(0x100);
+ ring3_text_end = .;
}
. = ALIGN(0x1000);
ring3_page_end = .;