From 2ff03f8f3c86d19866ab6280c3b2f3aac0754063 Mon Sep 17 00:00:00 2001 From: hinus Date: Thu, 17 Jun 2021 18:30:29 +0800 Subject: [PATCH] Title: Move init_task to privilege 3. Issue: https://gitee.com/hinus/linux_kernel_011/issues/I3VOQT Description: Intialize first task and move it to lower privilege. --- include/asm/system.h | 34 ++++++++++++++++++++++++++ include/linux/sched.h | 56 +++++++++++++++++++++++++++++++++++++++++++ kernel/main.c | 3 +++ kernel/sched.c | 15 +++++++++++- 4 files changed, 107 insertions(+), 1 deletion(-) diff --git a/include/asm/system.h b/include/asm/system.h index 001b687..b44e6b6 100644 --- a/include/asm/system.h +++ b/include/asm/system.h @@ -1,6 +1,22 @@ #ifndef _SYSTEM_H #define _SYSTEM_H +#define move_to_user_mode() \ +__asm__("movl %%esp, %%eax\n\t" \ + "pushl $0x17\n\t" \ + "pushl %%eax\n\t" \ + "pushfl\n\t" \ + "pushl $0x0f\n\t" \ + "pushl $1f\n\t" \ + "iret\n\t" \ + "1:\tmovl $0x17, %%eax\n\t" \ + "movw %%ax, %%ds\n\t" \ + "movw %%ax, %%es\n\t" \ + "movw %%ax, %%fs\n\t" \ + "movw %%ax, %%gs\n\t" \ + :::"ax") + + #define sti() __asm__("sti"::) #define cli() __asm__("cli"::) #define nop() __asm__("nop"::) @@ -21,4 +37,22 @@ __asm__("movw %%dx, %%ax\n\t" \ #define set_intr_gate(n, addr) \ _set_gate(&idt[n], 14, 0, addr) +#define set_system_gate(n, addr) \ + _set_gate(&idt[n], 15, 3, addr) + +#define _set_tssldt_desc(n, addr, type) \ +__asm__("movw $104, %1\n\t" \ + "movw %%ax, %2\n\t" \ + "rorl $16, %%eax\n\t" \ + "movb %%al, %3\n\t" \ + "movb $" type ", %4\n\t" \ + "movb $0x00, %5\n\t" \ + "movb %%ah, %6\n\t" \ + "rorl $16, %%eax\n\t" \ + ::"a"(addr), "m"(*(n)), "m"(*(n+2)), "m"(*(n+4)), \ + "m"(*(n+5)), "m"(*(n+6)), "m"(*(n+7)) \ + ) + +#define set_tss_desc(n, addr) _set_tssldt_desc(((char*)(n)), addr, "0x89") +#define set_ldt_desc(n, addr) _set_tssldt_desc(((char*)(n)), addr, "0x82") #endif diff --git a/include/linux/sched.h b/include/linux/sched.h index e7f1a39..dce7118 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -6,4 +6,60 @@ void sched_init(); +struct tss_struct { + long back_link; + long esp0; + long ss0; + long esp1; + long ss1; + long esp2; + long ss2; + long cr3; + long eip; + long eflags; + long eax, ecx, edx, ebx; + long esp; + long ebp; + long esi; + long edi; + long es; + long cs; + long ss; + long ds; + long fs; + long gs; + long ldt; + long trace_bitmap; +}; + +struct task_struct { + struct desc_struct ldt[3]; + struct tss_struct tss; +}; + +#define INIT_TASK \ +{ \ + { \ + {0, 0}, \ + {0x9f, 0xc0fa00}, \ + {0x9f, 0xc0f200}, \ + }, \ + {0, PAGE_SIZE + (long)&init_task, 0x10, 0, 0, 0, 0, (long)&pg_dir, \ + 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, \ + _LDT(0), 0x80000000, \ + }, \ +} + +/* + * In linux is 4, because we add video selector, + * so, it is 5 here. + * */ +#define FIRST_TSS_ENTRY 5 +#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY + 1) +#define _TSS(n) ((((unsigned long)n) << 4) + (FIRST_TSS_ENTRY << 3)) +#define _LDT(n) ((((unsigned long)n) << 4) + (FIRST_LDT_ENTRY << 3)) +#define ltr(n) __asm__("ltr %%ax"::"a"(_TSS(n))) +#define lldt(n) __asm__("lldt %%ax"::"a"(_LDT(n))) + #endif diff --git a/kernel/main.c b/kernel/main.c index 6caab5f..b68535b 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -1,5 +1,7 @@ #define __LIBRARY__ +#include + #include #include #include @@ -41,6 +43,7 @@ void main(void) tty_init(); printk("%d %d\n\r", 12, 34); + move_to_user_mode(); __asm__ __volatile__( "int $0x80\n\r" diff --git a/kernel/sched.c b/kernel/sched.c index 7be08e4..b7a5043 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6,6 +6,13 @@ extern int system_call(); +union task_union { + struct task_struct task; + char stack[PAGE_SIZE]; +}; + +static union task_union init_task = {INIT_TASK, }; + long user_stack[PAGE_SIZE >> 2]; struct @@ -15,6 +22,12 @@ struct } stack_start = {&user_stack[PAGE_SIZE >> 2], 0x10}; void sched_init() { - set_intr_gate(0x80, &system_call); + struct desc_struct* p; + set_tss_desc(gdt + FIRST_TSS_ENTRY, &(init_task.task.tss)); + set_ldt_desc(gdt + FIRST_LDT_ENTRY, &(init_task.task.ldt)); + __asm__("pushfl; andl $0xffffbfff, (%esp); popfl"); + ltr(0); + lldt(0); + set_system_gate(0x80, &system_call); } -- Gitee