mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 11:16:47 +00:00
进入用户模式(系统调用存在page fault的bug)
This commit is contained in:
parent
c09c6d4e66
commit
dacc29310f
@ -22,7 +22,7 @@ enum CMOSTimeSelector
|
|||||||
int rtc_get_cmos_time(struct rtc_time_t *t)
|
int rtc_get_cmos_time(struct rtc_time_t *t)
|
||||||
{
|
{
|
||||||
// 为防止中断请求打断该过程,需要先关中断
|
// 为防止中断请求打断该过程,需要先关中断
|
||||||
cli();
|
//cli();
|
||||||
|
|
||||||
uint8_t status_register_B = read_cmos(0x0B); // 读取状态寄存器B
|
uint8_t status_register_B = read_cmos(0x0B); // 读取状态寄存器B
|
||||||
bool is_24h = ((status_register_B & 0x02) ? true : false); // 判断是否启用24小时模式
|
bool is_24h = ((status_register_B & 0x02) ? true : false); // 判断是否启用24小时模式
|
||||||
@ -53,6 +53,6 @@ int rtc_get_cmos_time(struct rtc_time_t *t)
|
|||||||
|
|
||||||
if ((!is_24h) && t->hour & 0x80) // 将十二小时制转为24小时
|
if ((!is_24h) && t->hour & 0x80) // 将十二小时制转为24小时
|
||||||
t->hour = ((t->hour & 0x7f) + 12) % 24;
|
t->hour = ((t->hour & 0x7f) + 12) % 24;
|
||||||
sti();
|
//sti();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -104,13 +104,15 @@ Err_Code:
|
|||||||
// 系统调用入口
|
// 系统调用入口
|
||||||
// 保存寄存器
|
// 保存寄存器
|
||||||
ENTRY(system_call)
|
ENTRY(system_call)
|
||||||
|
|
||||||
// 由于sysenter指令会禁用中断,因此要在这里手动开启中断
|
// 由于sysenter指令会禁用中断,因此要在这里手动开启中断
|
||||||
sti;
|
sti;
|
||||||
hlt
|
|
||||||
|
|
||||||
subq $0x38, %rsp
|
subq $0x38, %rsp
|
||||||
|
|
||||||
cld;
|
cld;
|
||||||
|
|
||||||
pushq %rax
|
pushq %rax
|
||||||
movq %es, %rax
|
movq %es, %rax
|
||||||
pushq %rax
|
pushq %rax
|
||||||
@ -137,6 +139,7 @@ ENTRY(system_call)
|
|||||||
// 将rsp作为参数传递给system_call_function
|
// 将rsp作为参数传递给system_call_function
|
||||||
movq %rsp, %rdi
|
movq %rsp, %rdi
|
||||||
|
|
||||||
|
|
||||||
callq system_call_function
|
callq system_call_function
|
||||||
|
|
||||||
|
|
||||||
@ -145,33 +148,29 @@ ENTRY(system_call)
|
|||||||
ENTRY(ret_from_system_call)
|
ENTRY(ret_from_system_call)
|
||||||
movq %rax, 0x80(%rsp) // 将当前rax的值先存到栈中rax的位置
|
movq %rax, 0x80(%rsp) // 将当前rax的值先存到栈中rax的位置
|
||||||
|
|
||||||
popq %r15
|
|
||||||
popq %r14
|
popq %r15
|
||||||
popq %r13
|
popq %r14
|
||||||
popq %r12
|
popq %r13
|
||||||
popq %r11
|
popq %r12
|
||||||
popq %r10
|
popq %r11
|
||||||
popq %r9
|
popq %r10
|
||||||
popq %r8
|
popq %r9
|
||||||
popq %rbx
|
popq %r8
|
||||||
popq %rcx
|
popq %rbx
|
||||||
popq %rdx
|
popq %rcx
|
||||||
popq %rsi
|
popq %rdx
|
||||||
popq %rdi
|
popq %rsi
|
||||||
popq %rbp
|
popq %rdi
|
||||||
|
popq %rbp
|
||||||
popq %rax // 不允许直接pop到ds
|
popq %rax
|
||||||
movq %rax, %ds
|
movq %rax, %ds
|
||||||
|
popq %rax
|
||||||
popq %rax
|
movq %rax, %es
|
||||||
movq %rax, %es
|
popq %rax
|
||||||
|
addq $0x38, %rsp
|
||||||
popq %rax
|
.byte 0x48
|
||||||
|
sysexit
|
||||||
addq $0x38, %rsp
|
|
||||||
|
|
||||||
.byte 0x48
|
|
||||||
sysexit
|
|
||||||
|
|
||||||
|
|
||||||
// 0 #DE 除法错误
|
// 0 #DE 除法错误
|
||||||
|
@ -168,7 +168,7 @@ void do_stack_segment_fault(struct pt_regs *regs, unsigned long error_code)
|
|||||||
// 13 #GP 通用保护性异常
|
// 13 #GP 通用保护性异常
|
||||||
void do_general_protection(struct pt_regs *regs, unsigned long error_code)
|
void do_general_protection(struct pt_regs *regs, unsigned long error_code)
|
||||||
{
|
{
|
||||||
hlt();
|
|
||||||
kerror("do_general_protection(13),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\n", error_code, regs->rsp, regs->rip);
|
kerror("do_general_protection(13),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\n", error_code, regs->rsp, regs->rip);
|
||||||
if (error_code & 0x01)
|
if (error_code & 0x01)
|
||||||
printk_color(RED, BLACK, "The exception occurred during delivery of an event external to the program,such as an interrupt or an earlier exception.\n");
|
printk_color(RED, BLACK, "The exception occurred during delivery of an event external to the program,such as an interrupt or an earlier exception.\n");
|
||||||
@ -192,7 +192,7 @@ void do_general_protection(struct pt_regs *regs, unsigned long error_code)
|
|||||||
// 14 #PF 页故障
|
// 14 #PF 页故障
|
||||||
void do_page_fault(struct pt_regs *regs, unsigned long error_code)
|
void do_page_fault(struct pt_regs *regs, unsigned long error_code)
|
||||||
{
|
{
|
||||||
hlt();
|
|
||||||
unsigned long cr2 = 0;
|
unsigned long cr2 = 0;
|
||||||
|
|
||||||
__asm__ __volatile__("movq %%cr2, %0":"=r"(cr2)::"memory");
|
__asm__ __volatile__("movq %%cr2, %0":"=r"(cr2)::"memory");
|
||||||
|
@ -164,7 +164,7 @@ void mm_init()
|
|||||||
if (z->zone_addr_start >= 0x100000000 && (!ZONE_UNMAPPED_INDEX))
|
if (z->zone_addr_start >= 0x100000000 && (!ZONE_UNMAPPED_INDEX))
|
||||||
ZONE_UNMAPPED_INDEX = i;
|
ZONE_UNMAPPED_INDEX = i;
|
||||||
}
|
}
|
||||||
kdebug("ZONE_DMA_INDEX=%d\tZONE_NORMAL_INDEX=%d\tZONE_UNMAPPED_INDEX=%d", ZONE_DMA_INDEX, ZONE_NORMAL_INDEX, ZONE_UNMAPPED_INDEX);
|
//kdebug("ZONE_DMA_INDEX=%d\tZONE_NORMAL_INDEX=%d\tZONE_UNMAPPED_INDEX=%d", ZONE_DMA_INDEX, ZONE_NORMAL_INDEX, ZONE_UNMAPPED_INDEX);
|
||||||
// 设置内存页管理结构的地址,预留了一段空间,防止内存越界。
|
// 设置内存页管理结构的地址,预留了一段空间,防止内存越界。
|
||||||
memory_management_struct.end_of_struct = (ul)((ul)memory_management_struct.zones_struct + memory_management_struct.zones_struct_len + sizeof(long) * 32) & (~(sizeof(long) - 1));
|
memory_management_struct.end_of_struct = (ul)((ul)memory_management_struct.zones_struct + memory_management_struct.zones_struct_len + sizeof(long) * 32) & (~(sizeof(long) - 1));
|
||||||
|
|
||||||
@ -174,7 +174,7 @@ void mm_init()
|
|||||||
// 初始化内存管理单元结构所占的物理页的结构体
|
// 初始化内存管理单元结构所占的物理页的结构体
|
||||||
|
|
||||||
ul mms_max_page = (virt_2_phys(memory_management_struct.end_of_struct) >> PAGE_2M_SHIFT); // 内存管理单元所占据的序号最大的物理页
|
ul mms_max_page = (virt_2_phys(memory_management_struct.end_of_struct) >> PAGE_2M_SHIFT); // 内存管理单元所占据的序号最大的物理页
|
||||||
kdebug("mms_max_page=%ld", mms_max_page);
|
//kdebug("mms_max_page=%ld", mms_max_page);
|
||||||
|
|
||||||
struct Page *tmp_page = NULL;
|
struct Page *tmp_page = NULL;
|
||||||
ul page_num;
|
ul page_num;
|
||||||
@ -191,11 +191,11 @@ void mm_init()
|
|||||||
|
|
||||||
global_CR3 = get_CR3();
|
global_CR3 = get_CR3();
|
||||||
// root_page_table_phys_addr = global_CR3;
|
// root_page_table_phys_addr = global_CR3;
|
||||||
kdebug("global_CR3\t:%#018lx", global_CR3);
|
//kdebug("global_CR3\t:%#018lx", global_CR3);
|
||||||
kdebug("*global_CR3\t:%#018lx", *phys_2_virt(global_CR3) & (~0xff));
|
//kdebug("*global_CR3\t:%#018lx", *phys_2_virt(global_CR3) & (~0xff));
|
||||||
kdebug("**global_CR3\t:%#018lx", *phys_2_virt(*phys_2_virt(global_CR3) & (~0xff)) & (~0xff));
|
//kdebug("**global_CR3\t:%#018lx", *phys_2_virt(*phys_2_virt(global_CR3) & (~0xff)) & (~0xff));
|
||||||
|
|
||||||
kdebug("1.memory_management_struct.bmp:%#018lx\tzone->count_pages_using:%d\tzone_struct->count_pages_free:%d", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free);
|
//kdebug("1.memory_management_struct.bmp:%#018lx\tzone->count_pages_using:%d\tzone_struct->count_pages_free:%d", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free);
|
||||||
//kinfo("Cleaning page table remapping at 0x0000");
|
//kinfo("Cleaning page table remapping at 0x0000");
|
||||||
|
|
||||||
kinfo("Memory management unit initialize complete!");
|
kinfo("Memory management unit initialize complete!");
|
||||||
|
@ -374,7 +374,7 @@ ul slab_init()
|
|||||||
page_init(page, PAGE_KERNEL_INIT | PAGE_KERNEL | PAGE_PGT_MAPPED);
|
page_init(page, PAGE_KERNEL_INIT | PAGE_KERNEL | PAGE_PGT_MAPPED);
|
||||||
}
|
}
|
||||||
|
|
||||||
kdebug("2.memory_management_struct.bmp:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free);
|
//kdebug("2.memory_management_struct.bmp:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free);
|
||||||
|
|
||||||
// 为slab内存池对象分配内存空间
|
// 为slab内存池对象分配内存空间
|
||||||
ul *virt = NULL;
|
ul *virt = NULL;
|
||||||
@ -395,7 +395,7 @@ ul slab_init()
|
|||||||
|
|
||||||
kmalloc_cache_group[i].cache_pool_entry->vaddr = virt;
|
kmalloc_cache_group[i].cache_pool_entry->vaddr = virt;
|
||||||
}
|
}
|
||||||
kdebug("3.memory_management_struct.bmp:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free);
|
//kdebug("3.memory_management_struct.bmp:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free);
|
||||||
|
|
||||||
kinfo("SLAB initialized successfully!");
|
kinfo("SLAB initialized successfully!");
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <mm/slab.h>
|
#include <mm/slab.h>
|
||||||
#include <sched/sched.h>
|
#include <sched/sched.h>
|
||||||
|
|
||||||
|
extern void system_call(void);
|
||||||
/**
|
/**
|
||||||
* @brief 切换进程
|
* @brief 切换进程
|
||||||
*
|
*
|
||||||
@ -20,24 +21,20 @@
|
|||||||
void __switch_to(struct process_control_block *prev, struct process_control_block *next)
|
void __switch_to(struct process_control_block *prev, struct process_control_block *next)
|
||||||
{
|
{
|
||||||
initial_tss[0].rsp0 = next->thread->rbp;
|
initial_tss[0].rsp0 = next->thread->rbp;
|
||||||
kdebug("phys_2_virt(TSS64_Table)=%#018lx", phys_2_virt(TSS64_Table));
|
|
||||||
set_tss64((uint *)phys_2_virt(TSS64_Table), initial_tss[0].rsp0, initial_tss[0].rsp1, initial_tss[0].rsp2, initial_tss[0].ist1,
|
set_tss64((uint *)phys_2_virt(TSS64_Table), initial_tss[0].rsp0, initial_tss[0].rsp1, initial_tss[0].rsp2, initial_tss[0].ist1,
|
||||||
initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5, initial_tss[0].ist6, initial_tss[0].ist7);
|
initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5, initial_tss[0].ist6, initial_tss[0].ist7);
|
||||||
|
|
||||||
kdebug("prev->thread=%#018lx", prev->thread);
|
|
||||||
kdebug("next->thread=%#018lx", next->thread);
|
|
||||||
|
|
||||||
__asm__ __volatile__("movq %%fs, %0 \n\t"
|
__asm__ __volatile__("movq %%fs, %0 \n\t"
|
||||||
: "=a"(prev->thread->fs)::"memory");
|
: "=a"(prev->thread->fs)::"memory");
|
||||||
__asm__ __volatile__("movq %%gs, %0 \n\t"
|
__asm__ __volatile__("movq %%gs, %0 \n\t"
|
||||||
: "=a"(prev->thread->gs)::"memory");
|
: "=a"(prev->thread->gs)::"memory");
|
||||||
kdebug("&next->thread->fs=%#018lx", &(next->thread->fs));
|
|
||||||
|
|
||||||
__asm__ __volatile__("movq %0, %%fs \n\t" ::"a"(next->thread->fs)
|
__asm__ __volatile__("movq %0, %%fs \n\t" ::"a"(next->thread->fs)
|
||||||
: "memory");
|
: "memory");
|
||||||
|
|
||||||
__asm__ __volatile__("movq %0, %%gs \n\t" ::"a"(next->thread->gs)
|
__asm__ __volatile__("movq %0, %%gs \n\t" ::"a"(next->thread->gs)
|
||||||
: "memory");
|
: "memory");
|
||||||
|
wrmsr(0x175, next->thread->rbp);
|
||||||
kdebug("prev->thread->rsp0:%#018lx\n", prev->thread->rbp);
|
kdebug("prev->thread->rsp0:%#018lx\n", prev->thread->rbp);
|
||||||
kdebug("next->thread->rsp0:%#018lx\n", next->thread->rbp);
|
kdebug("next->thread->rsp0:%#018lx\n", next->thread->rbp);
|
||||||
}
|
}
|
||||||
@ -51,18 +48,21 @@ void user_level_function()
|
|||||||
// kinfo("Program (user_level_function) is runing...");
|
// kinfo("Program (user_level_function) is runing...");
|
||||||
// kinfo("Try to enter syscall id 15...");
|
// kinfo("Try to enter syscall id 15...");
|
||||||
// enter_syscall(15, 0, 0, 0, 0, 0, 0, 0, 0);
|
// enter_syscall(15, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
//enter_syscall(SYS_PRINTF, (ul) "test_sys_printf\n", 0, 0, 0, 0, 0, 0, 0);
|
|
||||||
long ret = 0;
|
|
||||||
// color_printk(RED,BLACK,"user_level_function task is running\n");
|
|
||||||
char string[]="Hello World!\n";
|
|
||||||
|
|
||||||
__asm__ __volatile__ ( "leaq sysexit_return_address(%%rip), %%rdx \n\t"
|
// enter_syscall(SYS_PRINTF, (ul) "test_sys_printf\n", 0, 0, 0, 0, 0, 0, 0);
|
||||||
"movq %%rsp, %%rcx \n\t"
|
long ret = 0;
|
||||||
"sysenter \n\t"
|
// color_printk(RED,BLACK,"user_level_function task is running\n");
|
||||||
"sysexit_return_address: \n\t"
|
|
||||||
:"=a"(ret):"0"(1),"D"(string):"memory");
|
char string[] = "Hello World!\n";
|
||||||
//kinfo("Return from syscall id 15...");
|
|
||||||
|
__asm__ __volatile__("leaq sysexit_return_address(%%rip), %%rdx \n\t"
|
||||||
|
"movq %%rsp, %%rcx \n\t"
|
||||||
|
"sysenter \n\t"
|
||||||
|
"sysexit_return_address: \n\t"
|
||||||
|
: "=a"(ret)
|
||||||
|
: "0"(1), "D"(string)
|
||||||
|
: "memory", "rcx", "rdx", "r14");
|
||||||
|
// kinfo("Return from syscall id 15...");
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
;
|
;
|
||||||
@ -89,10 +89,10 @@ ul do_execve(struct pt_regs *regs)
|
|||||||
// mm_map_proc_page_table(get_CR3(), true, 0x800000, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true);
|
// mm_map_proc_page_table(get_CR3(), true, 0x800000, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true);
|
||||||
|
|
||||||
uint64_t addr = 0x800000UL;
|
uint64_t addr = 0x800000UL;
|
||||||
|
|
||||||
unsigned long * tmp = phys_2_virt((unsigned long *)((unsigned long)get_CR3() & (~0xfffUL)) + (( addr>> PAGE_GDT_SHIFT) & 0x1ff));
|
unsigned long *tmp = phys_2_virt((unsigned long *)((unsigned long)get_CR3() & (~0xfffUL)) + ((addr >> PAGE_GDT_SHIFT) & 0x1ff));
|
||||||
|
|
||||||
unsigned long * virtual = kmalloc(PAGE_4K_SIZE, 0);
|
unsigned long *virtual = kmalloc(PAGE_4K_SIZE, 0);
|
||||||
set_pml4t(tmp, mk_pml4t(virt_2_phys(virtual), PAGE_USER_PGT));
|
set_pml4t(tmp, mk_pml4t(virt_2_phys(virtual), PAGE_USER_PGT));
|
||||||
|
|
||||||
tmp = phys_2_virt((unsigned long *)(*tmp & (~0xfffUL)) + ((addr >> PAGE_1G_SHIFT) & 0x1ff));
|
tmp = phys_2_virt((unsigned long *)(*tmp & (~0xfffUL)) + ((addr >> PAGE_1G_SHIFT) & 0x1ff));
|
||||||
@ -105,9 +105,10 @@ ul do_execve(struct pt_regs *regs)
|
|||||||
|
|
||||||
flush_tlb();
|
flush_tlb();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
mm_map_phys_addr_user(addr, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE);
|
mm_map_phys_addr_user(addr, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE);
|
||||||
*/ if (!(current_pcb->flags & PF_KTHREAD))
|
*/
|
||||||
|
if (!(current_pcb->flags & PF_KTHREAD))
|
||||||
current_pcb->addr_limit = KERNEL_BASE_LINEAR_ADDR;
|
current_pcb->addr_limit = KERNEL_BASE_LINEAR_ADDR;
|
||||||
// 将程序代码拷贝到对应的内存中
|
// 将程序代码拷贝到对应的内存中
|
||||||
memcpy((void *)0x800000, user_level_function, 1024);
|
memcpy((void *)0x800000, user_level_function, 1024);
|
||||||
@ -247,29 +248,36 @@ void process_init()
|
|||||||
initial_mm.brk_start = 0;
|
initial_mm.brk_start = 0;
|
||||||
initial_mm.brk_end = memory_management_struct.kernel_end;
|
initial_mm.brk_end = memory_management_struct.kernel_end;
|
||||||
|
|
||||||
|
|
||||||
initial_mm.stack_start = *(ul *)phys_2_virt(&_stack_start);
|
initial_mm.stack_start = *(ul *)phys_2_virt(&_stack_start);
|
||||||
|
|
||||||
|
// 向MSR寄存器组中的 IA32_SYSENTER_CS寄存器写入内核的代码段的地址
|
||||||
|
wrmsr(0x174, KERNEL_CS);
|
||||||
|
// 向MSR寄存器组中的 IA32_SYSENTER_ESP寄存器写入内核进程的rbp(在syscall入口中会将rsp减去相应的数值)
|
||||||
|
wrmsr(0x175, current_pcb->thread->rbp);
|
||||||
|
|
||||||
|
// 向MSR寄存器组中的 IA32_SYSENTER_EIP寄存器写入系统调用入口的地址。
|
||||||
|
wrmsr(0x176, (ul)system_call);
|
||||||
// 初始化进程和tss
|
// 初始化进程和tss
|
||||||
set_tss64((uint *)phys_2_virt(TSS64_Table), initial_thread.rbp, initial_tss[0].rsp1, initial_tss[0].rsp2, initial_tss[0].ist1, initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5, initial_tss[0].ist6, initial_tss[0].ist7);
|
set_tss64((uint *)phys_2_virt(TSS64_Table), initial_thread.rbp, initial_tss[0].rsp1, initial_tss[0].rsp2, initial_tss[0].ist1, initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5, initial_tss[0].ist6, initial_tss[0].ist7);
|
||||||
|
|
||||||
initial_tss[0].rsp0 = initial_thread.rbp;
|
initial_tss[0].rsp0 = initial_thread.rbp;
|
||||||
|
/*
|
||||||
kdebug("initial_thread.rbp=%#018lx", initial_thread.rbp);
|
kdebug("initial_thread.rbp=%#018lx", initial_thread.rbp);
|
||||||
kdebug("initial_tss[0].rsp1=%#018lx", initial_tss[0].rsp1);
|
kdebug("initial_tss[0].rsp1=%#018lx", initial_tss[0].rsp1);
|
||||||
kdebug("initial_tss[0].ist1=%#018lx", initial_tss[0].ist1);
|
kdebug("initial_tss[0].ist1=%#018lx", initial_tss[0].ist1);
|
||||||
|
*/
|
||||||
// 初始化进程的循环链表
|
// 初始化进程的循环链表
|
||||||
list_init(&initial_proc_union.pcb.list);
|
list_init(&initial_proc_union.pcb.list);
|
||||||
|
current_pcb->flags=0;
|
||||||
kernel_thread(initial_kernel_thread, 10, CLONE_FS | CLONE_FILES | CLONE_SIGNAL); // 初始化内核进程
|
kernel_thread(initial_kernel_thread, 10, CLONE_FS | CLONE_FILES | CLONE_SIGNAL); // 初始化内核进程
|
||||||
initial_proc_union.pcb.state = PROC_RUNNING;
|
initial_proc_union.pcb.state = PROC_RUNNING;
|
||||||
|
|
||||||
// 获取新的进程的pcb
|
// 获取新的进程的pcb
|
||||||
struct process_control_block *p = container_of(list_next(¤t_pcb->list), struct process_control_block, list);
|
// struct process_control_block *p = container_of(list_next(¤t_pcb->list), struct process_control_block, list);
|
||||||
|
|
||||||
kdebug("Ready to switch...");
|
kdebug("Ready to switch...");
|
||||||
// 切换到新的内核线程
|
// 切换到新的内核线程
|
||||||
switch_proc(current_pcb, p);
|
// switch_proc(current_pcb, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -296,6 +304,8 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
|||||||
// 将当前进程的pcb复制到新的pcb内
|
// 将当前进程的pcb复制到新的pcb内
|
||||||
*tsk = *current_pcb;
|
*tsk = *current_pcb;
|
||||||
|
|
||||||
|
kdebug("current_pcb->flags=%#010lx", current_pcb->flags);
|
||||||
|
|
||||||
// 将进程加入循环链表
|
// 将进程加入循环链表
|
||||||
list_init(&tsk->list);
|
list_init(&tsk->list);
|
||||||
|
|
||||||
@ -306,6 +316,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
|||||||
|
|
||||||
// 将线程结构体放置在pcb的后面
|
// 将线程结构体放置在pcb的后面
|
||||||
struct thread_struct *thd = (struct thread_struct *)(tsk + 1);
|
struct thread_struct *thd = (struct thread_struct *)(tsk + 1);
|
||||||
|
memset(thd, 0, sizeof(struct thread_struct));
|
||||||
tsk->thread = thd;
|
tsk->thread = thd;
|
||||||
|
|
||||||
// 将寄存器信息存储到进程的内核栈空间的顶部
|
// 将寄存器信息存储到进程的内核栈空间的顶部
|
||||||
@ -321,6 +332,10 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
|||||||
// 若进程不是内核层的进程,则跳转到ret from system call
|
// 若进程不是内核层的进程,则跳转到ret from system call
|
||||||
if (!(tsk->flags & PF_KTHREAD))
|
if (!(tsk->flags & PF_KTHREAD))
|
||||||
thd->rip = regs->rip = (ul)ret_from_system_call;
|
thd->rip = regs->rip = (ul)ret_from_system_call;
|
||||||
|
else
|
||||||
|
kdebug("is kernel proc.");
|
||||||
|
|
||||||
|
kdebug("ret_from_system_call=%#018lx", (ul)ret_from_system_call);
|
||||||
|
|
||||||
tsk->state = PROC_RUNNING;
|
tsk->state = PROC_RUNNING;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ void smp_init()
|
|||||||
|
|
||||||
apic_get_ics(ACPI_ICS_TYPE_PROCESSOR_LOCAL_APIC, tmp_vaddr, &total_processor_num);
|
apic_get_ics(ACPI_ICS_TYPE_PROCESSOR_LOCAL_APIC, tmp_vaddr, &total_processor_num);
|
||||||
|
|
||||||
kdebug("processor num=%d", total_processor_num);
|
//kdebug("processor num=%d", total_processor_num);
|
||||||
for (int i = 0; i < total_processor_num; ++i)
|
for (int i = 0; i < total_processor_num; ++i)
|
||||||
proc_local_apic_structs[i] = (struct acpi_Processor_Local_APIC_Structure_t *)(tmp_vaddr[i]);
|
proc_local_apic_structs[i] = (struct acpi_Processor_Local_APIC_Structure_t *)(tmp_vaddr[i]);
|
||||||
|
|
||||||
@ -56,10 +56,10 @@ void smp_init()
|
|||||||
set_tss_descriptor(10 + (i * 2), (void *)virt_2_phys(cpu_core_info[i].tss_vaddr));
|
set_tss_descriptor(10 + (i * 2), (void *)virt_2_phys(cpu_core_info[i].tss_vaddr));
|
||||||
|
|
||||||
set_tss64((uint *)cpu_core_info[i].tss_vaddr, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start);
|
set_tss64((uint *)cpu_core_info[i].tss_vaddr, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start);
|
||||||
kdebug("phys_2_virt(GDT_Table)=%#018lx",phys_2_virt(GDT_Table));
|
//kdebug("phys_2_virt(GDT_Table)=%#018lx",phys_2_virt(GDT_Table));
|
||||||
kdebug("GDT Table %#018lx, \t %#018lx", *(ul *)(phys_2_virt(GDT_Table) + 10 + i * 2), *(ul *)(phys_2_virt(GDT_Table) + 10 + i * 2 + 1));
|
//kdebug("GDT Table %#018lx, \t %#018lx", *(ul *)(phys_2_virt(GDT_Table) + 10 + i * 2), *(ul *)(phys_2_virt(GDT_Table) + 10 + i * 2 + 1));
|
||||||
// kdebug("(cpu_core_info[i].tss_vaddr)=%#018lx", (cpu_core_info[i].tss_vaddr));
|
// kdebug("(cpu_core_info[i].tss_vaddr)=%#018lx", (cpu_core_info[i].tss_vaddr));
|
||||||
kdebug("(cpu_core_info[i].stack_start)=%#018lx", (cpu_core_info[i].stack_start));
|
//kdebug("(cpu_core_info[i].stack_start)=%#018lx", (cpu_core_info[i].stack_start));
|
||||||
// 连续发送两次start-up IPI
|
// 连续发送两次start-up IPI
|
||||||
ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand, true, proc_local_apic_structs[i]->ACPI_ID);
|
ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand, true, proc_local_apic_structs[i]->ACPI_ID);
|
||||||
ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand, true, proc_local_apic_structs[i]->ACPI_ID);
|
ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand, true, proc_local_apic_structs[i]->ACPI_ID);
|
||||||
@ -111,7 +111,7 @@ void smp_ap_start()
|
|||||||
load_TR(10 + current_starting_cpu * 2);
|
load_TR(10 + current_starting_cpu * 2);
|
||||||
|
|
||||||
sti();
|
sti();
|
||||||
kdebug("IDT_addr = %#018lx", phys_2_virt(IDT_Table));
|
//kdebug("IDT_addr = %#018lx", phys_2_virt(IDT_Table));
|
||||||
memset(current_pcb, 0, sizeof(struct process_control_block));
|
memset(current_pcb, 0, sizeof(struct process_control_block));
|
||||||
spin_unlock(&multi_core_starting_lock);
|
spin_unlock(&multi_core_starting_lock);
|
||||||
while (1) // 这里要循环hlt,原因是当收到中断后,核心会被唤醒,处理完中断之后不会自动hlt
|
while (1) // 这里要循环hlt,原因是当收到中断后,核心会被唤醒,处理完中断之后不会自动hlt
|
||||||
|
@ -26,9 +26,11 @@ void syscall_init()
|
|||||||
wrmsr(0x174, KERNEL_CS);
|
wrmsr(0x174, KERNEL_CS);
|
||||||
// 向MSR寄存器组中的 IA32_SYSENTER_ESP寄存器写入内核进程的rbp(在syscall入口中会将rsp减去相应的数值)
|
// 向MSR寄存器组中的 IA32_SYSENTER_ESP寄存器写入内核进程的rbp(在syscall入口中会将rsp减去相应的数值)
|
||||||
wrmsr(0x175, current_pcb->thread->rbp);
|
wrmsr(0x175, current_pcb->thread->rbp);
|
||||||
|
|
||||||
|
|
||||||
// 向MSR寄存器组中的 IA32_SYSENTER_EIP寄存器写入系统调用入口的地址。
|
// 向MSR寄存器组中的 IA32_SYSENTER_EIP寄存器写入系统调用入口的地址。
|
||||||
wrmsr(0x176, (ul)system_call);
|
wrmsr(0x176, (ul)system_call);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long enter_syscall(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7)
|
long enter_syscall(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7)
|
||||||
@ -65,10 +67,11 @@ long enter_syscall(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, u
|
|||||||
*/
|
*/
|
||||||
ul sys_printf(struct pt_regs *regs)
|
ul sys_printf(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
while(1);
|
|
||||||
if(regs->r9 == 0 &®s->r10 == 0)
|
//if(regs->r9 == 0 &®s->r10 == 0)
|
||||||
printk((char*)regs->r8);
|
// printk((char*)regs->r8);
|
||||||
else printk_color(regs->r9, regs->r10, (char*)regs->r8);
|
//else printk_color(regs->r9, regs->r10, (char*)regs->r8);
|
||||||
|
printk_color(BLACK,WHITE,(char *)regs->rdi);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user