diff --git a/kernel/Makefile b/kernel/Makefile index fa54fb9f..90b5cf04 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -7,10 +7,10 @@ DIR_LIB=lib lib_patterns := *.a LIB_FILES := $(foreach DIR,$(DIR_LIB),$(addprefix $(DIR)/,$(lib_patterns))) -DEBUG=1 +DEBUG=DEBUG CFLAGS := -mcmodel=large -fno-builtin -m64 -O0 -I . -fno-stack-protector -ifeq ($(DEBUG), 1) +ifeq ($(DEBUG), DEBUG) CFLAGS += -g endif @@ -35,6 +35,10 @@ entry.o: exception/entry.S gcc -E exception/entry.S > exception/entry.s as $(ASFLAGS) -o exception/entry.o exception/entry.s +procs.o: process/proc.S + gcc -E process/proc.S > process/proc.s + as $(ASFLAGS) -o process/procs.o process/proc.s + main.o: main.c @@ -151,8 +155,8 @@ all: kernel objcopy -I elf64-x86-64 -O elf64-x86-64 -R ".comment" -R ".eh_frame" kernel ../bin/kernel/kernel.elf # -kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o sched.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o apu_boot.o rtc.o HPET.o softirq.o timer.o fat32.o MBR.o VFS.o $(OBJ_LIST) - ld -b elf64-x86-64 -z muldefs -o kernel head.o exception/entry.o main.o common/printk.o exception/trap.o exception/irq.o mm/mm.o mm/slab.o process/process.o syscall/syscall.o driver/multiboot2/multiboot2.o \ +kernel: head.o entry.o procs.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o sched.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o apu_boot.o rtc.o HPET.o softirq.o timer.o fat32.o MBR.o VFS.o $(OBJ_LIST) + ld -b elf64-x86-64 -z muldefs -o kernel head.o exception/entry.o process/procs.o main.o common/printk.o exception/trap.o exception/irq.o mm/mm.o mm/slab.o process/process.o syscall/syscall.o driver/multiboot2/multiboot2.o \ common/cpu.o smp/smp.o smp/apu_boot.o exception/softirq.o sched/sched.o filesystem/fat32/fat32.o filesystem/MBR.o filesystem/VFS/VFS.o \ driver/acpi/acpi.o driver/interrupt/pic.o driver/keyboard/ps2_keyboard.o driver/mouse/ps2_mouse.o driver/disk/ata.o driver/pci/pci.o driver/disk/ahci/ahci.o driver/timers/rtc/rtc.o driver/timers/HPET/HPET.o driver/timers/timer.o \ $(LD_LIST) \ diff --git a/kernel/common/printk.c b/kernel/common/printk.c index 9cb9f931..1c2ea359 100644 --- a/kernel/common/printk.c +++ b/kernel/common/printk.c @@ -635,9 +635,9 @@ static void putchar(uint *fb, int Xsize, int x, int y, unsigned int FRcolor, uns * @param font 字符的bitmap */ -#ifdef DEBUG +//#if DEBUG uart_send(COM1, font); -#endif +//#endif unsigned char *font_ptr = font_ascii[font]; unsigned int *addr; diff --git a/kernel/driver/interrupt/apic/apic.c b/kernel/driver/interrupt/apic/apic.c index d72700d5..589e7e9a 100644 --- a/kernel/driver/interrupt/apic/apic.c +++ b/kernel/driver/interrupt/apic/apic.c @@ -459,7 +459,6 @@ void do_IRQ(struct pt_regs *rsp, ul number) irq->handler(number, irq->parameter, rsp); else kwarn("Intr vector [%d] does not have a handler!"); - // 向中断控制器发送应答消息 if (irq->controller != NULL && irq->controller->ack != NULL) irq->controller->ack(number); @@ -485,10 +484,10 @@ void do_IRQ(struct pt_regs *rsp, ul number) { // printk_color(RED, BLACK, "SMP IPI [ %d ]\n", number); apic_local_apic_edge_ack(number); - + { - irq_desc_t * irq = &SMP_IPI_desc[number-200]; - if(irq->handler!=NULL) + irq_desc_t *irq = &SMP_IPI_desc[number - 200]; + if (irq->handler != NULL) irq->handler(number, irq->parameter, rsp); } } @@ -498,9 +497,11 @@ void do_IRQ(struct pt_regs *rsp, ul number) kwarn("do IRQ receive: %d", number); } + kdebug("before softirq"); // 检测是否有未处理的软中断 if (softirq_status != 0) do_softirq(); + kdebug("after softirq"); // 检测当前进程是否持有自旋锁,若持有自旋锁,则不进行抢占式的进程调度 if (current_pcb->preempt_count > 0) return; @@ -510,6 +511,7 @@ void do_IRQ(struct pt_regs *rsp, ul number) // 检测当前进程是否可被调度 if (current_pcb->flags & PROC_NEED_SCHED) { + kdebug("to sched"); sched_cfs(); } } diff --git a/kernel/driver/timers/HPET/HPET.c b/kernel/driver/timers/HPET/HPET.c index 49c0a75a..4786bfcc 100644 --- a/kernel/driver/timers/HPET/HPET.c +++ b/kernel/driver/timers/HPET/HPET.c @@ -51,7 +51,7 @@ hardware_intr_controller HPET_intr_controller = void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs) { - // printk("(HPET)"); + printk("(HPET)"); switch (param) { case 0: // 定时器0中断 diff --git a/kernel/filesystem/fat32/fat32.c b/kernel/filesystem/fat32/fat32.c index 24588038..b0755166 100644 --- a/kernel/filesystem/fat32/fat32.c +++ b/kernel/filesystem/fat32/fat32.c @@ -699,7 +699,9 @@ struct vfs_filesystem_type_t fat32_fs_type = }; void fat32_init() { - kinfo("Initializing FAT32..."); + + // kinfo("Initializing FAT32..."); + // 在VFS中注册fat32文件系统 vfs_register_filesystem(&fat32_fs_type); diff --git a/kernel/main.c b/kernel/main.c index 0bf8f110..cd677695 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -86,9 +86,9 @@ void system_initialize() // 初始化printk printk_init(8, 16); -#ifdef DEBUG +//#ifdef DEBUG uart_init(COM1, 115200); -#endif +//#endif kinfo("Kernel Starting..."); // 重新加载gdt和idt @@ -156,7 +156,8 @@ void system_initialize() process_init(); HPET_init(); - fat32_init(); + //fat32_init(); + } diff --git a/kernel/process/proc.S b/kernel/process/proc.S new file mode 100644 index 00000000..63c4aff3 --- /dev/null +++ b/kernel/process/proc.S @@ -0,0 +1,27 @@ +#include"../common/asm.h" + +ENTRY(kernel_thread_func) + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %r11 + popq %r10 + popq %r9 + popq %r8 + popq %rbx + popq %rcx + popq %rdx + popq %rsi + popq %rdi + popq %rbp + popq %rax + movq %rax, %ds + popq %rax + movq %rax, %es + popq %rax + addq $0x38, %rsp + movq %rdx, %rdi + callq *%rbx + movq %rax, %rdi + callq process_thread_do_exit \ No newline at end of file diff --git a/kernel/process/process.c b/kernel/process/process.c index 9669c494..653cac03 100644 --- a/kernel/process/process.c +++ b/kernel/process/process.c @@ -41,6 +41,7 @@ struct tss_struct initial_tss[MAX_CPU_NUM] = {[0 ... MAX_CPU_NUM - 1] = INITIAL_ void __switch_to(struct process_control_block *prev, struct process_control_block *next) { initial_tss[proc_current_cpu_id].rsp0 = next->thread->rbp; + kdebug("next_rsp = %#018lx ", next->thread->rsp); // 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); @@ -52,7 +53,6 @@ void __switch_to(struct process_control_block *prev, struct process_control_bloc __asm__ __volatile__("movq %0, %%fs \n\t" ::"a"(next->thread->fs)); __asm__ __volatile__("movq %0, %%gs \n\t" ::"a"(next->thread->gs)); // wrmsr(0x175, next->thread->rbp); - } /** @@ -80,7 +80,7 @@ void user_level_function() : "0"(1), "D"(string) : "memory"); */ - long err_code=1; + long err_code = 1; ul addr = (ul)string; __asm__ __volatile__( "movq %2, %%r8 \n\t" @@ -88,16 +88,16 @@ void user_level_function() : "=a"(err_code) : "a"(SYS_PUT_STRING), "m"(addr) : "memory", "r8"); - if(err_code ==0) + if (err_code == 0) { - char str[] ="errno is 0"; + char str[] = "errno is 0"; addr = (ul)str; - __asm__ __volatile__( - "movq %2, %%r8 \n\t" - "int $0x80 \n\t" - : "=a"(err_code) - : "a"(SYS_PUT_STRING), "m"(addr) - : "memory", "r8"); + __asm__ __volatile__( + "movq %2, %%r8 \n\t" + "int $0x80 \n\t" + : "=a"(err_code) + : "a"(SYS_PUT_STRING), "m"(addr) + : "memory", "r8"); } // enter_syscall_int(SYS_PRINTF, (ul) "test_sys_printf\n", 0, 0, 0, 0, 0, 0, 0); // kinfo("Return from syscall id 15..."); @@ -166,7 +166,7 @@ ul do_execve(struct pt_regs *regs) ul initial_kernel_thread(ul arg) { // kinfo("initial proc running...\targ:%#018lx", arg); - + kdebug("6666"); struct pt_regs *regs; current_pcb->thread->rip = (ul)ret_from_system_call; @@ -180,7 +180,7 @@ ul initial_kernel_thread(ul arg) // 将返回用户层的代码压入堆栈,向rdx传入regs的地址,然后jmp到do_execve这个系统调用api的处理函数 这里的设计思路和switch_proc类似 __asm__ __volatile__("movq %1, %%rsp \n\t" "pushq %2 \n\t" - "jmp do_execve \n\t" ::"D"(regs), + "jmp do_execve \n\t" ::"D"(current_pcb->thread->rsp), "m"(current_pcb->thread->rsp), "m"(current_pcb->thread->rip) : "memory"); @@ -206,8 +206,42 @@ ul process_thread_do_exit(ul code) * 执行到这里时,rsp位于栈顶,然后弹出寄存器值 * 弹出之后还要向上移动7个unsigned long的大小,从而弹出额外的信息(详见pt_regs) */ +/* +void kernel_thread_func(void) +{ + __asm__ volatile( + //"kernel_thread_func: \n\t" + " popq %r15 \n\t" + " popq %r14 \n\t" + " popq %r13 \n\t" + " popq %r12 \n\t" + " popq %r11 \n\t" + " popq %r10 \n\t" + " popq %r9 \n\t" + " popq %r8 \n\t" + " popq %rbx \n\t" + " popq %rcx \n\t" + " popq %rdx \n\t" + " popq %rsi \n\t" + " popq %rdi \n\t" + " popq %rbp \n\t" + " popq %rax \n\t" + " movq %rax, %ds \n\t" + " popq %rax \n\t" + " movq %rax, %es \n\t" + " popq %rax \n\t" + " addq $0x38, %rsp \n\t" + ///////////////////////////////// + " movq %rdx, %rdi \n\t" + " callq *%rbx \n\t" + " movq %rax, %rdi \n\t" + " callq process_thread_do_exit \n\t"); +} + +*/ extern void kernel_thread_func(void); +/* __asm__( "kernel_thread_func: \n\t" " popq %r15 \n\t" @@ -235,7 +269,7 @@ __asm__( " callq *%rbx \n\t" " movq %rax, %rdi \n\t" " callq process_thread_do_exit \n\t"); - +*/ /** * @brief 初始化内核进程 * @@ -265,9 +299,9 @@ int kernel_thread(unsigned long (*fn)(unsigned long), unsigned long arg, unsigne // rip寄存器指向内核线程的引导程序 regs.rip = (ul)kernel_thread_func; - // kdebug("kernel_thread_func=%#018lx", kernel_thread_func); - // kdebug("&kernel_thread_func=%#018lx", &kernel_thread_func); - + kdebug("kernel_thread_func=%#018lx", kernel_thread_func); + kdebug("&kernel_thread_func=%#018lx", &kernel_thread_func); + kdebug("1111\tregs.rip = %#018lx", regs.rip); return do_fork(®s, flags, 0, 0); } @@ -338,7 +372,7 @@ void process_init() unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned long stack_start, unsigned long stack_size) { struct process_control_block *tsk = NULL; - + kdebug("222\tregs.rip = %#018lx", regs->rip); // 获取一个物理页并在这个物理页内初始化pcb struct Page *pp = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED | PAGE_KERNEL); @@ -367,9 +401,11 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned struct thread_struct *thd = (struct thread_struct *)(tsk + 1); memset(thd, 0, sizeof(struct thread_struct)); tsk->thread = thd; + kdebug("333\tregs.rip = %#018lx", regs->rip); // 将寄存器信息存储到进程的内核栈空间的顶部 memcpy((void *)((ul)tsk + STACK_SIZE - sizeof(struct pt_regs)), regs, sizeof(struct pt_regs)); + kdebug("regs.rip = %#018lx", regs->rip); // 设置进程的内核栈 thd->rbp = (ul)tsk + STACK_SIZE; thd->rip = regs->rip; diff --git a/kernel/process/process.h b/kernel/process/process.h index 0c7192a5..4d7ab9e5 100644 --- a/kernel/process/process.h +++ b/kernel/process/process.h @@ -216,11 +216,11 @@ struct process_control_block *get_current_pcb() "pushq %%rax \n\t" \ "movq %%rsp, %0 \n\t" \ "movq %2, %%rsp \n\t" \ - "leaq 1f(%%rip), %%rax \n\t" \ + "leaq switch_proc_ret_addr(%%rip), %%rax \n\t" \ "movq %%rax, %1 \n\t" \ "pushq %3 \n\t" \ "jmp __switch_to \n\t" \ - "1: \n\t" \ + "switch_proc_ret_addr: \n\t" \ "popq %%rax \n\t" \ "popq %%rbp \n\t" \ "sti \n\t" \ diff --git a/kernel/sched/sched.c b/kernel/sched/sched.c index e1f8e2c0..85b71c65 100644 --- a/kernel/sched/sched.c +++ b/kernel/sched/sched.c @@ -74,6 +74,7 @@ void sched_cfs() break; } } + kdebug("before switch, next.rip = %#018lx\tnext->gs=%#018lx", proc->thread->rip, proc->thread->gs); switch_proc(current_pcb, proc); } else // 不进行切换 diff --git a/tools/Dockerfile b/tools/Dockerfile new file mode 100644 index 00000000..f2e4860d --- /dev/null +++ b/tools/Dockerfile @@ -0,0 +1,6 @@ +FROM debian:bullseye +RUN apt update \ + && apt install -y git xorriso build-essential +VOLUME ["/user_data"] + +CMD tail -f /dev/null \ No newline at end of file