修复ACPI驱动无法处理电源键问题
This commit is contained in:
parent
b0e065958d
commit
d73f236850
@ -1,7 +1,7 @@
|
|||||||
#ifndef CRASHPOWEROS_STDIO_H
|
#ifndef CRASHPOWEROS_STDIO_H
|
||||||
#define CRASHPOWEROS_STDIO_H
|
#define CRASHPOWEROS_STDIO_H
|
||||||
|
|
||||||
void put_char(char c);
|
void put_char();
|
||||||
void debug_test();
|
void debug_test();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,8 +4,19 @@ void hlt(){
|
|||||||
while (1);
|
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(){
|
int main(){
|
||||||
|
//putc('A');
|
||||||
|
put_char();
|
||||||
hlt();
|
hlt();
|
||||||
//put_char('A');
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -2,14 +2,10 @@ global put_char
|
|||||||
global debug_test
|
global debug_test
|
||||||
|
|
||||||
put_char:
|
put_char:
|
||||||
ret
|
|
||||||
push edx
|
|
||||||
push eax
|
push eax
|
||||||
mov edx,[ss:esp+12]
|
|
||||||
mov eax,0x01
|
mov eax,0x01
|
||||||
int 31h
|
int 31h
|
||||||
pop eax
|
pop eax
|
||||||
pop edx
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
debug_test:
|
debug_test:
|
||||||
|
@ -16,6 +16,8 @@ uint32_t *PM1b_CNT;
|
|||||||
uint8_t PM1_CNT_LEN;
|
uint8_t PM1_CNT_LEN;
|
||||||
uint16_t SLP_EN;
|
uint16_t SLP_EN;
|
||||||
uint16_t SCI_EN;
|
uint16_t SCI_EN;
|
||||||
|
uint32_t PM1a_EVT_BLK;
|
||||||
|
uint32_t PM1b_EVT_BLK;
|
||||||
|
|
||||||
acpi_rsdt_t *rsdt; // root system descript table
|
acpi_rsdt_t *rsdt; // root system descript table
|
||||||
acpi_facp_t *facp; // fixed ACPI table
|
acpi_facp_t *facp; // fixed ACPI table
|
||||||
@ -144,24 +146,37 @@ void power_off() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int AcpiPowerHandler(registers_t *irq) {
|
static int AcpiPowerHandler(registers_t *irq) {
|
||||||
uint16_t status = io_in16((uint32_t) facp->PM1a_EVT_BLK);
|
io_cli();
|
||||||
// check if power button press
|
uint16_t status = io_in16((uint32_t) PM1a_EVT_BLK);
|
||||||
if (status & (1 << 8)) {
|
|
||||||
io_out16((uint32_t) facp->PM1a_EVT_BLK, status &= ~(1 << 8)); // clear bits
|
// 不检查电源键, 按下就关机
|
||||||
|
|
||||||
|
io_out16((uint32_t) PM1a_EVT_BLK, status &= ~(1 << 8)); // clear bits
|
||||||
printf("Shutdown OS...");
|
printf("Shutdown OS...");
|
||||||
shutdown_kernel();
|
shutdown_kernel();
|
||||||
|
|
||||||
|
// check if power button press
|
||||||
|
if (status & (1 << 8)) {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!facp->PM1b_EVT_BLK)
|
if (!PM1b_EVT_BLK){
|
||||||
|
printf("PowerDown fault\n");
|
||||||
|
io_sti();
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("DEBUG IV\n");
|
||||||
// check if power button press
|
// 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)) {
|
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...");
|
printf("Shutdown OS...");
|
||||||
shutdown_kernel();
|
shutdown_kernel();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
io_sti();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,7 +196,7 @@ static void AcpiPowerInit() {
|
|||||||
PM1b_ENABLE_REG, (uint8_t)(1 << 8));
|
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) {
|
int AcpiCheckHeader(void *ptr, uint8_t *sign) {
|
||||||
@ -213,8 +228,7 @@ uint8_t *AcpiCheckRSDPtr(void *ptr) {
|
|||||||
bptr++;
|
bptr++;
|
||||||
}
|
}
|
||||||
if (!check) {
|
if (!check) {
|
||||||
return (uint8_t * )
|
return (uint8_t * ) rsdp->rsdt;
|
||||||
rsdp->rsdt;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -263,6 +277,9 @@ static int AcpiSysInit() {
|
|||||||
|
|
||||||
PM1_CNT_LEN = facp->PM1_CNT_LEN;
|
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;
|
SLP_EN = 1 << 13;
|
||||||
SCI_EN = 1;
|
SCI_EN = 1;
|
||||||
|
|
||||||
|
@ -190,5 +190,5 @@ void initVBE(multiboot_t *info) {
|
|||||||
vbe_clear();
|
vbe_clear();
|
||||||
|
|
||||||
Bmp *bmp = (Bmp*) &logo_bmp;
|
Bmp *bmp = (Bmp*) &logo_bmp;
|
||||||
display(bmp,0,0,false);
|
//display(bmp,0,0,false);
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
#define UINT32_MAX 0xffffffff
|
#define UINT32_MAX 0xffffffff
|
||||||
#define INT32_MAX 0x7fffffff
|
#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) \
|
#define swap32(x) \
|
||||||
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
|
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
|
||||||
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
|
(((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) {
|
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]) {
|
if (interrupt_handlers[regs.int_no]) {
|
||||||
isr_t handler = 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);
|
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("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");
|
int pid = kernel_thread(setup_shell,NULL,"CPOS-Shell");
|
||||||
klogf(pid != -1,"Launch kernel shell.\n");
|
klogf(pid != -1,"Launch kernel shell.\n");
|
||||||
|
@ -20,6 +20,7 @@ extern uint32_t c_height;
|
|||||||
Bmp *panic_bmp;
|
Bmp *panic_bmp;
|
||||||
|
|
||||||
static GP_13(registers_t *reg){
|
static GP_13(registers_t *reg){
|
||||||
|
io_cli();
|
||||||
printf("throw #GP 13 error.\n");
|
printf("throw #GP 13 error.\n");
|
||||||
if(current->pid == 0){
|
if(current->pid == 0){
|
||||||
printf("Kernel PANIC(#GP), Please restart your CPOS Kernel.\n");
|
printf("Kernel PANIC(#GP), Please restart your CPOS Kernel.\n");
|
||||||
@ -27,6 +28,7 @@ static GP_13(registers_t *reg){
|
|||||||
}else {
|
}else {
|
||||||
task_kill(current->pid);
|
task_kill(current->pid);
|
||||||
}
|
}
|
||||||
|
io_sti();
|
||||||
}
|
}
|
||||||
|
|
||||||
static UD_6(registers_t *reg){
|
static UD_6(registers_t *reg){
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
void syscall_handler(registers_t regs){
|
void syscall_handler(registers_t regs){
|
||||||
io_cli();
|
io_cli();
|
||||||
printf("Syscall is enable.\n");
|
printf("Syscall is enable. EAX: %08x\n",regs.eax);
|
||||||
if(regs.eax == 0x01){
|
if(regs.eax == 0x01){
|
||||||
putchar((regs.edx));
|
putchar((regs.edx));
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,10 @@ struct task_struct *get_current() {
|
|||||||
return 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) {
|
void print_proc_t(int *i, struct task_struct *base, struct task_struct *cur, int is_print) {
|
||||||
if (cur->pid == base->pid) {
|
if (cur->pid == base->pid) {
|
||||||
if (is_print) {
|
if (is_print) {
|
||||||
@ -218,19 +222,15 @@ int32_t user_process(char *path, char *name){ // 用户进程创建
|
|||||||
|
|
||||||
page_switch(page);
|
page_switch(page);
|
||||||
|
|
||||||
printf("TASK I\n");
|
for (int i = USER_START; i < USER_END + 0x1000;i++) { //用户堆以及用户栈映射
|
||||||
|
|
||||||
for (int i = USER_START; i < USER_END;i++) {
|
|
||||||
page_t *pg = get_page(i,1,page, false);
|
page_t *pg = get_page(i,1,page, false);
|
||||||
alloc_frame(pg,0,1);
|
alloc_frame(pg,0,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* buffer = user_alloc(new_task,size);
|
char* buffer = user_alloc(new_task,size);
|
||||||
|
|
||||||
printf("TASK II\n");
|
|
||||||
|
|
||||||
memset(buffer,0,size);
|
memset(buffer,0,size);
|
||||||
vfs_readfile(path,buffer); //能加载, 但是执行一会就不知道跳哪里去了,给自己爆了
|
vfs_readfile(path,buffer);
|
||||||
|
|
||||||
Elf32_Ehdr *ehdr = buffer;
|
Elf32_Ehdr *ehdr = buffer;
|
||||||
if(!elf32Validate(ehdr)){
|
if(!elf32Validate(ehdr)){
|
||||||
@ -238,8 +238,15 @@ int32_t user_process(char *path, char *name){ // 用户进程创建
|
|||||||
return -1;
|
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);
|
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);
|
uint32_t *stack_top = (uint32_t * )((uint32_t) new_task + STACK_SIZE);
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include "../include/common.h"
|
#include "../include/common.h"
|
||||||
#include "../include/printf.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) {
|
static uint32_t div_round_up(uint32_t num, uint32_t size) {
|
||||||
return (num + size - 1) / size;
|
return (num + size - 1) / size;
|
||||||
@ -14,79 +14,40 @@ bool elf32Validate(Elf32_Ehdr *hdr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t elf32_get_max_vaddr(Elf32_Ehdr *hdr) {
|
uint32_t elf32_get_max_vaddr(Elf32_Ehdr *hdr) {
|
||||||
Elf32_Phdr *phdr = (Elf32_Phdr *) ((uint32_t) hdr + hdr->e_phoff);
|
Elf32_Phdr *phdr = (Elf32_Phdr *)((uint32_t)hdr + hdr->e_phoff);
|
||||||
uint32_t max = 0;
|
uint32_t max = 0;
|
||||||
for (int i = 0; i < hdr->e_phnum; i++) {
|
for (int i = 0; i < hdr->e_phnum; i++) {
|
||||||
uint32_t size = MAX(
|
// 如果memsz大于filesz 说明这是bss段,我们以最大的为准
|
||||||
phdr->p_filesz,
|
uint32_t size = max(phdr->p_filesz, phdr->p_memsz);
|
||||||
phdr->p_memsz); // 如果memsz大于filesz 说明这是bss段,我们以最大的为准
|
max = max(max, phdr->p_vaddr + size);
|
||||||
max = MAX(max, phdr->p_vaddr + size);
|
|
||||||
phdr++;
|
phdr++;
|
||||||
}
|
}
|
||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_segment(Elf32_Phdr *phdr, page_directory_t *pdt, void *elf) {
|
void load_segment(Elf32_Phdr *phdr,page_directory_t *dir, void *elf) {
|
||||||
unsigned int p = div_round_up(phdr->p_memsz, 0x1000);
|
size_t hi = PADDING_UP(phdr->p_paddr + phdr->p_memsz, 0x1000);
|
||||||
|
size_t lo = PADDING_DOWN(phdr->p_paddr, 0x1000);
|
||||||
int d = phdr->p_paddr;
|
for (size_t i = lo; i < hi; i += 0x1000) {
|
||||||
if (d & 0x00000fff) {
|
alloc_frame(get_page(i,1,dir,false),0,1);
|
||||||
unsigned e = d + phdr->p_memsz;
|
|
||||||
d = d & 0xfffff000;
|
|
||||||
e &= 0xfffff000;
|
|
||||||
p = (e - d) / 0x1000 + 1;
|
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < p; i++) {
|
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);
|
||||||
alloc_frame(get_page(d + i * 0x1000, 1, pdt, false), 0, 1);
|
memcpy((void *)phdr->p_vaddr, elf + phdr->p_offset, phdr->p_filesz);
|
||||||
}
|
|
||||||
memcpy(phdr->p_vaddr, elf + phdr->p_offset, phdr->p_filesz);
|
|
||||||
|
|
||||||
if (phdr->p_memsz > phdr->p_filesz) { // 这个是bss段
|
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) {
|
uint32_t load_elf(Elf32_Ehdr *hdr,page_directory_t *dir) {
|
||||||
Elf32_Ehdr *elf_hdr = (Elf32_Ehdr *) file_buffer;
|
Elf32_Phdr *phdr = (Elf32_Phdr *)((uint32_t)hdr + hdr->e_phoff);
|
||||||
//检测文件类型
|
|
||||||
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);
|
|
||||||
for (int i = 0; i < hdr->e_phnum; i++) {
|
for (int i = 0; i < hdr->e_phnum; i++) {
|
||||||
if (phdr->p_type != PT_LOAD) {
|
load_segment(phdr, (void *)hdr,dir);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
load_segment(phdr, pdt, (void *) hdr);
|
|
||||||
phdr++;
|
phdr++;
|
||||||
}
|
}
|
||||||
return hdr->e_entry;
|
return hdr->e_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void elf32LoadData(Elf32_Ehdr *elfhdr, uint8_t *ptr) {
|
void elf32LoadData(Elf32_Ehdr *elfhdr, uint8_t *ptr) {
|
||||||
uint8_t *p = (uint8_t *) elfhdr;
|
uint8_t *p = (uint8_t *) elfhdr;
|
||||||
for (int i = 0; i < elfhdr->e_shnum; i++) {
|
for (int i = 0; i < elfhdr->e_shnum; i++) {
|
||||||
|
Loading…
Reference in New Issue
Block a user