修复ACPI驱动无法处理电源键问题
This commit is contained in:
parent
b0e065958d
commit
d73f236850
@ -1,7 +1,7 @@
|
||||
#ifndef CRASHPOWEROS_STDIO_H
|
||||
#define CRASHPOWEROS_STDIO_H
|
||||
|
||||
void put_char(char c);
|
||||
void put_char();
|
||||
void debug_test();
|
||||
|
||||
#endif
|
||||
|
@ -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;
|
||||
}
|
@ -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:
|
||||
|
@ -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);
|
||||
// check if power button press
|
||||
if (status & (1 << 8)) {
|
||||
io_out16((uint32_t) facp->PM1a_EVT_BLK, status &= ~(1 << 8)); // clear bits
|
||||
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)) {
|
||||
|
||||
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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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]; // 有自定义处理程序,调用之
|
||||
|
@ -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");
|
||||
|
@ -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){
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
@ -17,76 +17,37 @@ uint32_t elf32_get_max_vaddr(Elf32_Ehdr *hdr) {
|
||||
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) {
|
||||
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++) {
|
||||
|
Loading…
Reference in New Issue
Block a user