修复ACPI驱动无法处理电源键问题

This commit is contained in:
XIAOYI12 2024-08-19 17:27:13 +08:00
parent b0e065958d
commit d73f236850
12 changed files with 82 additions and 85 deletions

View File

@ -1,7 +1,7 @@
#ifndef CRASHPOWEROS_STDIO_H
#define CRASHPOWEROS_STDIO_H
void put_char(char c);
void put_char();
void debug_test();
#endif

View File

@ -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;
}

View File

@ -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:

View File

@ -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;

View File

@ -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);
}

View File

@ -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))

View File

@ -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]; // 有自定义处理程序,调用之

View File

@ -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");

View File

@ -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){

View File

@ -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));
}

View File

@ -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);

View File

@ -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++) {