From d73f2368506b3c0bd6eb834bfb803b0a8daa9625 Mon Sep 17 00:00:00 2001 From: xiaoyi1212 Date: Mon, 19 Aug 2024 17:27:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DACPI=E9=A9=B1=E5=8A=A8?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E5=A4=84=E7=90=86=E7=94=B5=E6=BA=90=E9=94=AE?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/include/stdio.h | 2 +- apps/init/init.c | 13 +++++++- apps/libs/syscall.asm | 4 --- src/driver/acpi.c | 37 +++++++++++++++------ src/driver/vbe.c | 2 +- src/include/common.h | 3 ++ src/kernel/idt.c | 2 +- src/kernel/kernel.c | 4 +-- src/kernel/panic.c | 2 ++ src/kernel/syscall.c | 2 +- src/kernel/task.c | 21 ++++++++---- src/util/elf.c | 75 +++++++++++-------------------------------- 12 files changed, 82 insertions(+), 85 deletions(-) diff --git a/apps/include/stdio.h b/apps/include/stdio.h index 4d260ae..6363ef7 100644 --- a/apps/include/stdio.h +++ b/apps/include/stdio.h @@ -1,7 +1,7 @@ #ifndef CRASHPOWEROS_STDIO_H #define CRASHPOWEROS_STDIO_H -void put_char(char c); +void put_char(); void debug_test(); #endif diff --git a/apps/init/init.c b/apps/init/init.c index 30be55c..e08217d 100644 --- a/apps/init/init.c +++ b/apps/init/init.c @@ -4,8 +4,19 @@ void hlt(){ while (1); } +void putc(char c){ + asm ("push %%eax\n" + "push %%edx\n" + "mov %0,%%edx\n" + "mov $0x1,%%eax\n" + "int $31\n" + "pop %%edx\n" + "pop %%eax\n"::"m"(c)); +} + int main(){ + //putc('A'); + put_char(); hlt(); - //put_char('A'); return 0; } \ No newline at end of file diff --git a/apps/libs/syscall.asm b/apps/libs/syscall.asm index bc55bec..6c359f2 100644 --- a/apps/libs/syscall.asm +++ b/apps/libs/syscall.asm @@ -2,14 +2,10 @@ global put_char global debug_test put_char: - ret - push edx push eax - mov edx,[ss:esp+12] mov eax,0x01 int 31h pop eax - pop edx ret debug_test: diff --git a/src/driver/acpi.c b/src/driver/acpi.c index 9d064d3..44a3e51 100644 --- a/src/driver/acpi.c +++ b/src/driver/acpi.c @@ -16,6 +16,8 @@ uint32_t *PM1b_CNT; uint8_t PM1_CNT_LEN; uint16_t SLP_EN; uint16_t SCI_EN; +uint32_t PM1a_EVT_BLK; +uint32_t PM1b_EVT_BLK; acpi_rsdt_t *rsdt; // root system descript table acpi_facp_t *facp; // fixed ACPI table @@ -144,24 +146,37 @@ void power_off() { } static int AcpiPowerHandler(registers_t *irq) { - uint16_t status = io_in16((uint32_t) facp->PM1a_EVT_BLK); + io_cli(); + uint16_t status = io_in16((uint32_t) PM1a_EVT_BLK); + + // 不检查电源键, 按下就关机 + + io_out16((uint32_t) PM1a_EVT_BLK, status &= ~(1 << 8)); // clear bits + printf("Shutdown OS..."); + shutdown_kernel(); + // check if power button press if (status & (1 << 8)) { - io_out16((uint32_t) facp->PM1a_EVT_BLK, status &= ~(1 << 8)); // clear bits - printf("Shutdown OS..."); - shutdown_kernel(); + return 0; } - if (!facp->PM1b_EVT_BLK) + if (!PM1b_EVT_BLK){ + printf("PowerDown fault\n"); + io_sti(); return -1; + } + + printf("DEBUG IV\n"); // check if power button press - status = io_in16((uint32_t) facp->PM1b_EVT_BLK); + status = io_in16((uint32_t) PM1b_EVT_BLK); + printf("DEBUG V\n"); if (status & (1 << 8)) { - io_out16((uint32_t) facp->PM1b_EVT_BLK, status &= ~(1 << 8)); + io_out16((uint32_t) PM1b_EVT_BLK, status &= ~(1 << 8)); printf("Shutdown OS..."); shutdown_kernel(); return 0; } + io_sti(); return -1; } @@ -181,7 +196,7 @@ static void AcpiPowerInit() { PM1b_ENABLE_REG, (uint8_t)(1 << 8)); } - register_interrupt_handler(facp->SCI_INT, AcpiPowerHandler); + register_interrupt_handler(facp->SCI_INT + 0x20, AcpiPowerHandler); } int AcpiCheckHeader(void *ptr, uint8_t *sign) { @@ -213,8 +228,7 @@ uint8_t *AcpiCheckRSDPtr(void *ptr) { bptr++; } if (!check) { - return (uint8_t * ) - rsdp->rsdt; + return (uint8_t * ) rsdp->rsdt; } } return NULL; @@ -263,6 +277,9 @@ static int AcpiSysInit() { PM1_CNT_LEN = facp->PM1_CNT_LEN; + PM1a_EVT_BLK = facp->PM1b_EVT_BLK; + PM1b_EVT_BLK = facp->PM1b_EVT_BLK; + SLP_EN = 1 << 13; SCI_EN = 1; diff --git a/src/driver/vbe.c b/src/driver/vbe.c index 7942a1a..3f3e18e 100644 --- a/src/driver/vbe.c +++ b/src/driver/vbe.c @@ -190,5 +190,5 @@ void initVBE(multiboot_t *info) { vbe_clear(); Bmp *bmp = (Bmp*) &logo_bmp; - display(bmp,0,0,false); + //display(bmp,0,0,false); } diff --git a/src/include/common.h b/src/include/common.h index 114baa5..68b5bdb 100644 --- a/src/include/common.h +++ b/src/include/common.h @@ -14,6 +14,9 @@ #define UINT32_MAX 0xffffffff #define INT32_MAX 0x7fffffff +#define PADDING_DOWN(size, to) ((size_t)(size) / (size_t)(to) * (size_t)(to)) +#define PADDING_UP(size, to) PADDING_DOWN((size_t)(size) + (size_t)(to) - (size_t)1, to) + #define swap32(x) \ ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) diff --git a/src/kernel/idt.c b/src/kernel/idt.c index e0b0491..1e71b3b 100644 --- a/src/kernel/idt.c +++ b/src/kernel/idt.c @@ -29,7 +29,7 @@ void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) { } void isr_handler(registers_t regs) { - printf("\n[Kernel]: received interrupt: %d\n",regs.int_no); + //printf("\n[Kernel]: received interrupt: %d\n",regs.int_no); if (interrupt_handlers[regs.int_no]) { isr_t handler = interrupt_handlers[regs.int_no]; // 有自定义处理程序,调用之 diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 6235e55..9448a89 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -135,9 +135,9 @@ void kernel_main(multiboot_t *multiboot) { clock_sleep(25); - vfs_change_path("apps"); + // vfs_change_path("apps"); //klogf(user_process("service.bin","Service") != -1,"Service base process init.\n"); - klogf(user_process("init.bin","Init") != -1,"Init base process init.\n"); + //klogf(user_process("init.bin","Init") != -1,"Init base process init.\n"); int pid = kernel_thread(setup_shell,NULL,"CPOS-Shell"); klogf(pid != -1,"Launch kernel shell.\n"); diff --git a/src/kernel/panic.c b/src/kernel/panic.c index ed7508e..15c7e08 100644 --- a/src/kernel/panic.c +++ b/src/kernel/panic.c @@ -20,6 +20,7 @@ extern uint32_t c_height; Bmp *panic_bmp; static GP_13(registers_t *reg){ + io_cli(); printf("throw #GP 13 error.\n"); if(current->pid == 0){ printf("Kernel PANIC(#GP), Please restart your CPOS Kernel.\n"); @@ -27,6 +28,7 @@ static GP_13(registers_t *reg){ }else { task_kill(current->pid); } + io_sti(); } static UD_6(registers_t *reg){ diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index 651e10e..64a46df 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -7,7 +7,7 @@ void syscall_handler(registers_t regs){ io_cli(); - printf("Syscall is enable.\n"); + printf("Syscall is enable. EAX: %08x\n",regs.eax); if(regs.eax == 0x01){ putchar((regs.edx)); } diff --git a/src/kernel/task.c b/src/kernel/task.c index 759381e..93a4709 100644 --- a/src/kernel/task.c +++ b/src/kernel/task.c @@ -30,6 +30,10 @@ struct task_struct *get_current() { return current; } +static uint32_t padding_up(uint32_t num, uint32_t size) { + return (num + size - 1) / size; +} + void print_proc_t(int *i, struct task_struct *base, struct task_struct *cur, int is_print) { if (cur->pid == base->pid) { if (is_print) { @@ -218,19 +222,15 @@ int32_t user_process(char *path, char *name){ // 用户进程创建 page_switch(page); - printf("TASK I\n"); - - for (int i = USER_START; i < USER_END;i++) { + for (int i = USER_START; i < USER_END + 0x1000;i++) { //用户堆以及用户栈映射 page_t *pg = get_page(i,1,page, false); alloc_frame(pg,0,1); } char* buffer = user_alloc(new_task,size); - printf("TASK II\n"); - memset(buffer,0,size); - vfs_readfile(path,buffer); //能加载, 但是执行一会就不知道跳哪里去了,给自己爆了 + vfs_readfile(path,buffer); Elf32_Ehdr *ehdr = buffer; if(!elf32Validate(ehdr)){ @@ -238,8 +238,15 @@ int32_t user_process(char *path, char *name){ // 用户进程创建 return -1; } + /* + uint32_t alloc_addr = (elf32_get_max_vaddr((Elf32_Ehdr *)ehdr) & 0xfffff000) + 0x1000; + uint32_t pg = padding_up( 0xf00000, 0x1000); + for (int i = 0; i < pg + 128; i++) { + alloc_frame(get_page(alloc_addr + i * 0x1000,1,page),0,1); + } + */ + uint32_t main = load_elf(ehdr,page); - printf("Task [PID: %d] start_function: %08x\n",new_task->pid,main); uint32_t *stack_top = (uint32_t * )((uint32_t) new_task + STACK_SIZE); diff --git a/src/util/elf.c b/src/util/elf.c index 38e9564..2954468 100644 --- a/src/util/elf.c +++ b/src/util/elf.c @@ -2,7 +2,7 @@ #include "../include/common.h" #include "../include/printf.h" -#define MAX(a, b) a > b ? a : b +#define max(a, b) a > b ? a : b static uint32_t div_round_up(uint32_t num, uint32_t size) { return (num + size - 1) / size; @@ -14,79 +14,40 @@ bool elf32Validate(Elf32_Ehdr *hdr) { } uint32_t elf32_get_max_vaddr(Elf32_Ehdr *hdr) { - Elf32_Phdr *phdr = (Elf32_Phdr *) ((uint32_t) hdr + hdr->e_phoff); - uint32_t max = 0; + Elf32_Phdr *phdr = (Elf32_Phdr *)((uint32_t)hdr + hdr->e_phoff); + uint32_t max = 0; for (int i = 0; i < hdr->e_phnum; i++) { - uint32_t size = MAX( - phdr->p_filesz, - phdr->p_memsz); // 如果memsz大于filesz 说明这是bss段,我们以最大的为准 - max = MAX(max, phdr->p_vaddr + size); + // 如果memsz大于filesz 说明这是bss段,我们以最大的为准 + uint32_t size = max(phdr->p_filesz, phdr->p_memsz); + max = max(max, phdr->p_vaddr + size); phdr++; } return max; } -void load_segment(Elf32_Phdr *phdr, page_directory_t *pdt, void *elf) { - unsigned int p = div_round_up(phdr->p_memsz, 0x1000); - - int d = phdr->p_paddr; - if (d & 0x00000fff) { - unsigned e = d + phdr->p_memsz; - d = d & 0xfffff000; - e &= 0xfffff000; - p = (e - d) / 0x1000 + 1; +void load_segment(Elf32_Phdr *phdr,page_directory_t *dir, void *elf) { + size_t hi = PADDING_UP(phdr->p_paddr + phdr->p_memsz, 0x1000); + size_t lo = PADDING_DOWN(phdr->p_paddr, 0x1000); + for (size_t i = lo; i < hi; i += 0x1000) { + alloc_frame(get_page(i,1,dir,false),0,1); } - for (unsigned i = 0; i < p; i++) { - alloc_frame(get_page(d + i * 0x1000, 1, pdt, false), 0, 1); - } - memcpy(phdr->p_vaddr, elf + phdr->p_offset, phdr->p_filesz); - + printf("VDDR: %08x elf: %08x offset: %08x filesz: %08x elf+offset: %08x\n",phdr->p_vaddr, elf , phdr->p_offset, phdr->p_filesz, elf + phdr->p_offset); + memcpy((void *)phdr->p_vaddr, elf + phdr->p_offset, phdr->p_filesz); if (phdr->p_memsz > phdr->p_filesz) { // 这个是bss段 - memset(phdr->p_vaddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); + memset((void *)(phdr->p_vaddr + phdr->p_filesz), 0, phdr->p_memsz - phdr->p_filesz); } } -static uint32_t reload_elf_file(uint8_t *file_buffer) { - Elf32_Ehdr *elf_hdr = (Elf32_Ehdr *) file_buffer; - //检测文件类型 - if ((elf_hdr->e_ident[0] != 0x7f) || (elf_hdr->e_ident[1] != 'E') || - (elf_hdr->e_ident[2] != 'L') || (elf_hdr->e_ident[3] != 'F')) { - return 0; - } - for (int i = 0; i < elf_hdr->e_phnum; i++) { - Elf32_Phdr *phdr = (Elf32_Phdr *) (file_buffer + elf_hdr->e_phoff) + i; - if (phdr->p_type != PT_LOAD) { - continue; - } - //获取源文件地址以及需要加载的位置 - uint8_t *src = file_buffer + phdr->p_offset; - //printf("POFFSET: %08x\n",phdr->p_offset); - uint8_t *dest = (uint8_t *) phdr->p_paddr; - for (int j = 0; j < phdr->p_filesz; j++) { - *dest++ = *src++; - } - //计算结束地址, 对bss区域进行清零 - dest = (uint8_t *) phdr->p_paddr + phdr->p_filesz; - for (int j = 0; j < phdr->p_memsz - phdr->p_filesz; j++) { - *dest++ = 0; - } - } - //返回进入的地址 - return elf_hdr->e_entry; -} - -uint32_t load_elf(Elf32_Ehdr *hdr, page_directory_t *pdt) { - Elf32_Phdr *phdr = (Elf32_Phdr *) ((uint32_t) hdr + hdr->e_phoff); +uint32_t load_elf(Elf32_Ehdr *hdr,page_directory_t *dir) { + Elf32_Phdr *phdr = (Elf32_Phdr *)((uint32_t)hdr + hdr->e_phoff); for (int i = 0; i < hdr->e_phnum; i++) { - if (phdr->p_type != PT_LOAD) { - continue; - } - load_segment(phdr, pdt, (void *) hdr); + load_segment(phdr, (void *)hdr,dir); phdr++; } return hdr->e_entry; } + void elf32LoadData(Elf32_Ehdr *elfhdr, uint8_t *ptr) { uint8_t *p = (uint8_t *) elfhdr; for (int i = 0; i < elfhdr->e_shnum; i++) {