From d6476d0509588471e60bfa0ffaf549b1c1752cc9 Mon Sep 17 00:00:00 2001 From: xiaoyi1212 Date: Sun, 19 May 2024 18:05:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=BF=9B=E7=A8=8B=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- boot/boot.asm | 14 +++++---- build.py | 2 +- driver/acpi.c | 74 +++++++++++++++++++++++++++++++++++++++++++--- driver/vbe.c | 57 +++++++++++++++++++++++++++++++++-- fs/fat.c | 3 +- include/acpi.h | 61 ++++++++++++++++++++++++++++++++++++++ include/graphics.h | 35 ++++++++++++++++++++++ kernel/idt.c | 2 +- kernel/kernel.c | 23 +++++++++++--- kernel/page.c | 46 +++++++--------------------- kernel/task.c | 42 ++++++++------------------ kernel/timer.c | 2 ++ sysapp/shell.c | 7 +++++ 13 files changed, 283 insertions(+), 85 deletions(-) diff --git a/boot/boot.asm b/boot/boot.asm index ef06bcd..3f71f5e 100644 --- a/boot/boot.asm +++ b/boot/boot.asm @@ -1,15 +1,17 @@ -.set ALIGN, 1<<0 -.set MEMINFO, 1<<1 -.set FLAGS, ALIGN | MEMINFO -.set MAGIC, 0x1BADB002 -.set CHECKSUM, -(MAGIC + FLAGS) +.set ALIGN, 1<<0 +.set MEMINFO, 1<<1 +.set FLAGS, ALIGN | MEMINFO +.set MAGIC, 0x1BADB002 +.set CHECKSUM, -(MAGIC + FLAGS) .section .multiboot -.align 4 .long MAGIC .long FLAGS .long CHECKSUM +.long 0, 0, 0, 0, 0 +.long 0 +.long 1024, 768, 32 .section .bss .align 16 diff --git a/build.py b/build.py index 3bb32f7..d7d6deb 100644 --- a/build.py +++ b/build.py @@ -130,4 +130,4 @@ if len(sys.argv) == 0 or sys.argv[1] == 'vga': os.system("qemu-system-i386 -net nic,model=pcnet -net user -kernel isodir\\sys\\kernel.elf -hda diskx.img") elif sys.argv[1] == 'vbe': print("Graphics MODE [VBE]") - os.system("qemu-system-i386 -vga std -net nic,model=pcnet -net user -kernel isodir\\sys\\kernel.elf -hda diskx.img") \ No newline at end of file + os.system("qemu-system-i386 -vga vmware -net nic,model=pcnet -net user -kernel isodir\\sys\\kernel.elf -hda diskx.img") \ No newline at end of file diff --git a/driver/acpi.c b/driver/acpi.c index 119d402..c217028 100644 --- a/driver/acpi.c +++ b/driver/acpi.c @@ -20,6 +20,7 @@ uint16_t SCI_EN; acpi_rsdt_t *rsdt; // root system descript table acpi_facp_t *facp; // fixed ACPI table + int acpi_enable_flag; uint8_t *rsdp_address; @@ -170,23 +171,25 @@ static int AcpiPowerHandler(registers_t *irq) { } static void AcpiPowerInit() { - if(!facp) return; + if (!facp) return; uint8_t len = facp->PM1_EVT_LEN / 2; uint32_t *PM1a_ENABLE_REG = facp->PM1a_EVT_BLK + len; uint32_t *PM1b_ENABLE_REG = facp->PM1b_EVT_BLK + len; - if(PM1b_ENABLE_REG == len) + if (PM1b_ENABLE_REG == len) PM1b_ENABLE_REG = 0; printf("[acpi]: Setting Power event listener...\n"); io_out16(PM1a_ENABLE_REG, (1 << 8)); if (PM1b_ENABLE_REG) { - io_out16((uint16_t)PM1b_ENABLE_REG, (uint8_t)(1 << 8)); + io_out16((uint16_t) + PM1b_ENABLE_REG, (uint8_t)(1 << 8)); } - printf("ACPI : SCI_INT %08x\n",(uint8_t)facp->SCI_INT); + printf("ACPI : SCI_INT %08x\n", (uint8_t) + facp->SCI_INT); register_interrupt_handler(facp->SCI_INT, AcpiPowerHandler); } @@ -323,5 +326,68 @@ void acpi_install() { AcpiSysInit(); acpi_enable_flag = !acpi_enable(); // power init + hpet_initialize(); AcpiPowerInit(); +} + +static HpetInfo *hpetInfo = NULL; +static uint32_t hpetPeriod = 0; + +uint32_t nanoTime() { + uint32_t mcv = hpetInfo->mainCounterValue; + + while (1)asm("hlt"); + + return mcv * hpetPeriod; +} + +void usleep(uint32_t nano) { + uint32_t targetTime = nanoTime(); + uint32_t after = 0; + while (1) { + uint64_t n = nanoTime(); + if (n < targetTime) { + after += 0xffffffff - targetTime + n; + targetTime = n; + } else { + after += n - targetTime; + targetTime = n; + } + if (after >= nano) { + return; + } + } +} + +unsigned int acpi_find_table(char *Signature) { + uint8_t * ptr, *ptr2; + uint32_t len; + uint8_t * rsdt_t = (uint8_t * ) + rsdt; + // iterate on ACPI table pointers + for (len = *((uint32_t * )(rsdt_t + 4)), ptr2 = rsdt_t + 36; ptr2 < rsdt_t + len; + ptr2 += (char *) rsdt_t[0] == 'X' ? 8 : 4) { + ptr = (uint8_t * )(uintptr_t)(rsdt_t[0] == 'X' ? *((uint64_t *) ptr2) + : *((uint32_t *) ptr2)); + if (!memcmp(ptr, Signature, 4)) { + return (unsigned) ptr; + } + } + // printk("not found.\n"); + return 0; +} + +void hpet_initialize() { + HPET *hpet = acpi_find_table("HPET"); + if (!hpet) { + printf("can not found acpi hpet table\n"); + } + hpetInfo = (HpetInfo *) hpet->hpetAddress.address; + + uint32_t counterClockPeriod = hpetInfo->generalCapabilities >> 32; + hpetPeriod = counterClockPeriod / 1000000; + + hpetInfo->generalConfiguration |= 1; // 启用hpet + + printf("[acpi]: hpet successfully enabled.\n"); } \ No newline at end of file diff --git a/driver/vbe.c b/driver/vbe.c index c019f07..8fa06dd 100644 --- a/driver/vbe.c +++ b/driver/vbe.c @@ -1,6 +1,49 @@ #include "../include/graphics.h" +#include "../include/memory.h" #include "../include/io.h" +extern page_directory_t *kernel_directory; +uint32_t video_base, video_size; + +svga_mode_info_t* svga_mode_get_info(multiboot_t *sys_multiboot_info,uint16_t mode) { + return (svga_mode_info_t *) sys_multiboot_info->vbe_mode_info; +} +/* +uint32_t svga_map_fb(uint32_t real_addr, uint32_t fb_length) { + int i = 0; + uint32_t fb_addr; + + // Align framebuffer length to page boundaries + fb_length += 0x1000; + fb_length &= 0x0FFFF000; + + // Map enough framebuffer + for(i = 0xD0000000; i < 0xD0000000 + fb_length; i += 0x1000) { + page_t* page = paging_get_page(i, true, kernel_directory); + + fb_addr = (i & 0x0FFFF000) + real_addr; + + page->present = 1; + page->rw = 1; + page->user = 1; + page->frame = fb_addr >> 12; + } + + // Convert the kernel directory addresses to physical if needed + for(i = 0x340; i < 0x340 + (fb_length / 0x400000); i++) { + uint32_t physAddr = kernel_directory->tablesPhysical[i]; + + if((physAddr & 0xC0000000) == 0xC0000000) { + physAddr &= 0x0FFFFFFF; // get rid of high nybble + + kernel_directory->tablesPhysical[i] = physAddr; + } + } + + return 0xD0000000; +} + */ + int isVBEDisplayMode(uint16_t vbe_mode_info) { if (vbe_mode_info & (1 << 12)) { return 1; @@ -10,8 +53,16 @@ int isVBEDisplayMode(uint16_t vbe_mode_info) { } void initVBE(multiboot_t *mboot) { + svga_mode_info_t *vbe_info = svga_mode_get_info(mboot,SVGA_DEFAULT_MODE); + if(vbe_info->bpp == 32 || vbe_info->bpp == 16){ + printf("VBE LOAD SUCCESS!"); + } - if(isVBEDisplayMode(mboot->vbe_mode_info)){ - printf("[\035kernel\036]: Graphics mode: \037VBE\036\n"); - } else printf("[\035kernel\036]: Graphics mode: \037VGA\036\n"); + printf("[VBE]: Bass: %08x | PITCH: %d | HEIGHT: %d\n",vbe_info->physbase, + vbe_info->pitch, + vbe_info->screen_height); + + //video_base = svga_map_fb(svga_mode_info->physbase, svga_mode_info->pitch * svga_mode_info->screen_height); + + while (1) io_hlt(); } diff --git a/fs/fat.c b/fs/fat.c index db17f9b..c400947 100644 --- a/fs/fat.c +++ b/fs/fat.c @@ -1003,7 +1003,6 @@ void fat_InitFS(struct vfs_t *vfs, uint8_t disk_number) { get_dm(vfs).SectorBytes; get_dm(vfs).ADR_DISKIMG = (unsigned int)kmalloc(get_dm(vfs).RootDictAddress + get_dm(vfs).RootMaxFiles * 32); - printf("DISK NUMBER :%x %d\n",disk_number,sec); Disk_Read(0, sec, (void *)get_dm(vfs).ADR_DISKIMG, disk_number); @@ -1196,7 +1195,7 @@ bool Fat_Check(uint8_t disk_number) { uint8_t *boot_sec = kmalloc(512); Disk_Read(0, 1, boot_sec, disk_number); // logk("disk number = %02x\n", disk_number); - for(int i = 0;i<0x200;i++) printf("%02x ",boot_sec[i]); + //for(int i = 0;i<0x200;i++) printf("%02x ",boot_sec[i]); if (memcmp(boot_sec + BS_FileSysType, "FAT12 ", 8) == 0 || memcmp(boot_sec + BS_FileSysType, "FAT16 ", 8) == 0 || memcmp(boot_sec + BS_FileSysType + BPB_Fat32ExtByts, "FAT32 ", 8) == diff --git a/include/acpi.h b/include/acpi.h index 5d044fe..fe171f8 100644 --- a/include/acpi.h +++ b/include/acpi.h @@ -205,6 +205,64 @@ typedef struct } madt_processor_localAPIC_t; #pragma pack(pop) +typedef struct { + char sign[4]; + uint32_t len; + char revision; + char checksum; + char oemid[6]; + uint64_t oem_table_id; + uint32_t oem_revision; + uint32_t creator_id; + uint32_t creator_revision; +} __attribute__((packed)) MADT; +typedef struct { + uint64_t configurationAndCapability; + uint64_t comparatorValue; + uint64_t fsbInterruptRoute; + uint64_t unused; +} __attribute__((packed)) HpetTimer; + +typedef struct { + uint64_t generalCapabilities; + uint64_t reserved0; + uint64_t generalConfiguration; + uint64_t reserved1; + uint64_t generalIntrruptStatus; + uint8_t reserved3[0xc8]; + uint64_t mainCounterValue; + uint64_t reserved4; + HpetTimer timers[0]; +} __attribute__((packed)) HpetInfo; +typedef struct { + uint8_t addressSpaceID; + uint8_t registerBitWidth; + uint8_t registerBitOffset; + uint8_t accessWidth; // acpi 3.0 + uintptr_t address; +} __attribute__((packed)) AcpiAddress; +typedef struct { + uint32_t signature; + uint32_t length; + uint8_t revision; + uint8_t checksum; + uint8_t oem[6]; + uint8_t oemTableID[8]; + uint32_t oemVersion; + uint32_t creatorID; + uint32_t creatorVersion; + uint8_t hardwareRevision; + uint8_t comparatorCount : 5; + uint8_t counterSize : 1; + uint8_t reserved : 1; + uint8_t legacyReplacement : 1; + uint16_t pciVendorId; + AcpiAddress hpetAddress; + uint8_t hpetNumber; + uint16_t minimumTick; + uint8_t pageProtection; +} __attribute__((packed)) HPET; + uint8_t *AcpiGetRSDPtr(); int AcpiCheckHeader(void *ptr, uint8_t *sign); uint8_t *AcpiCheckRSDPtr(void *ptr); @@ -214,5 +272,8 @@ void power_reset(); int acpi_enable(); int acpi_disable(); void acpi_install(); +void hpet_initialize(); +uint32_t nanoTime(); +void usleep(uint32_t nano); #endif //CRASHPOWEROS_ACPI_H diff --git a/include/graphics.h b/include/graphics.h index ab8f08b..f609716 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -43,6 +43,10 @@ #define BUF_SIZE 4096 +#define SVGA_DEFAULT_MODE 0x117 +// RRRRR GGGGGG BBBBB +#define SVGA_24TO16BPP(x) ((x & 0xF80000) >> 8) | ((x & 0xFC00) >> 5) | ((x & 0xF8) >> 3) + enum vga_color { VGA_COLOR_BLACK = 0, VGA_COLOR_BLUE = 1, @@ -69,6 +73,35 @@ struct color_rgba { uint8_t a; }; +typedef struct svga_mode_info { + uint16_t attributes; + uint8_t windowA, windowB; + uint16_t granularity; + uint16_t windowSize; + uint16_t segmentA, segmentB; + uint32_t winFuncPtr; // ptr to INT 0x10 Function 0x4F05 + uint16_t pitch; // bytes per scan line + + uint16_t screen_width, screen_height; // resolution + uint8_t wChar, yChar, planes, bpp, banks; // number of banks + uint8_t memoryModel, bankSize, imagePages; + uint8_t reserved0; + + // color masks + uint8_t readMask, redPosition; + uint8_t greenMask, greenPosition; + uint8_t blueMask, bluePosition; + uint8_t reservedMask, reservedPosition; + uint8_t directColorAttributes; + + uint32_t physbase; //pointer to LFB in LFB modes + uint32_t offScreenMemOff; + uint16_t offScreenMemSize; + uint8_t reserved1[206]; +} __attribute__((packed)) svga_mode_info_t; + +svga_mode_info_t* svga_mode_get_info(multiboot_t *sys_multiboot_info,uint16_t mode); + typedef struct color_rgba color_rgba; uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg); @@ -93,4 +126,6 @@ void vga_clear(); void move_cursor(); +void initVBE(multiboot_t *mboot); + #endif \ No newline at end of file diff --git a/kernel/idt.c b/kernel/idt.c index 5e94247..8225298 100644 --- a/kernel/idt.c +++ b/kernel/idt.c @@ -20,7 +20,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",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/kernel/kernel.c b/kernel/kernel.c index 8037ddb..abdb567 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -44,6 +44,20 @@ uint32_t memory_all(){ return (multiboot_all->mem_upper + multiboot_all->mem_lower); } +int check_task(int *pid){ + struct task_struct *shell = found_task_pid(*pid); + while (1){ + if(shell->state == TASK_DEATH){ + printf("\033\n[Task-Check]: Task was throw exception.\036\n"); + printf("Enter any key to restart kernel.> "); + getc(); + printf("\n"); + reset_kernel(); + } + } + return 0; +} + void kernel_main(multiboot_t *multiboot) { io_cli(); vga_install(); @@ -52,13 +66,13 @@ void kernel_main(multiboot_t *multiboot) { (multiboot->mem_upper + multiboot->mem_lower) / 1024 + 1); while (1) io_hlt(); } - initVBE(multiboot); + //initVBE(multiboot); printf("[\035kernel\036]: VGA driver load success!\n"); gdt_install(); idt_install(); printf("[\035kernel\036]: description table config success!\n"); - init_timer(10); + init_timer(1); acpi_install(); printf("[\035kernel\036]: ACPI enable success!\n"); init_page(); @@ -80,7 +94,7 @@ void kernel_main(multiboot_t *multiboot) { vfs_mount_disk('A','A'); if(vfs_change_disk('A')) - printf("[FileSystem]: Chang disk win!"); + printf("[FileSystem]: Change disk win!\n"); else { for(;;); } @@ -94,7 +108,8 @@ void kernel_main(multiboot_t *multiboot) { clock_sleep(25); - kernel_thread(setup_shell, NULL, "CPOS-Shell"); + int pid = kernel_thread(setup_shell, NULL, "CPOS-Shell"); + kernel_thread(check_task,&pid,"CPOS-SHELL-CHECK"); launch_date(); for (;;) { diff --git a/kernel/page.c b/kernel/page.c index 563f2c5..53136c3 100644 --- a/kernel/page.c +++ b/kernel/page.c @@ -2,6 +2,7 @@ #include "../include/graphics.h" #include "../include/io.h" #include "../include/task.h" +#include "../include/timer.h" page_directory_t *kernel_directory = 0; // 内核用页目录 page_directory_t *current_directory = 0; // 当前页目录 @@ -111,50 +112,25 @@ void page_fault(registers_t *regs) { printf("[ERROR]: Page fault |"); if (present) { printf("Type: present;\n\taddress: %x \n", faulting_address); - if (current->pid == 0) { - printf(" ======= Kernel Error ======= \n"); - while (1) io_hlt(); - } else { - current->state = TASK_ZOMBIE; - printf("Taskkill process PID:%d Name:%s\n", current->pid, current->name); - } } else if (rw) { printf("Type: read-only;\n\taddress: %x", faulting_address); - if (current->pid == 0) { - printf(" ======= Kernel Error ======= "); - while (1) io_hlt(); - } else { - current->state = TASK_ZOMBIE; - printf("Taskkill process PID:%d Name:%s", current->pid, current->name); - } } else if (us) { printf("Type: user-mode;\n\taddres: %x", faulting_address); - if (current->pid == 0) { - printf(" ======= Kernel Error ======= "); - while (1) io_hlt(); - } else { - current->state = TASK_ZOMBIE; - printf("Taskkill process PID:%d Name:%s", current->pid, current->name); - } } else if (reserved) { printf("Type: reserved;\n\taddress: %x", faulting_address); - if (current->pid == 0) { - printf(" ======= Kernel Error ======= "); - while (1) io_hlt(); - } else { - current->state = TASK_ZOMBIE; - printf("Taskkill process PID:%d Name:%s", current->pid, current->name); - } } else if (id) { printf("Type: decode address;\n\taddress: %x\n", faulting_address); - if (current->pid == 0) { - printf(" ======= Kernel Error ======= \n"); - while (1) io_hlt(); - } else { - current->state = TASK_ZOMBIE; - printf("Taskkill process PID:%d Name:%s\n", current->pid, current->name); - } } + + if (current->pid == 0) { + printf(" ======= Kernel Error ======= \n"); + while (1) io_hlt(); + } else { + task_kill(current->pid); + } + + io_sti(); + sleep(1); } static page_table_t *clone_table(page_table_t *src, uint32_t *physAddr) { diff --git a/kernel/task.c b/kernel/task.c index f6a419c..17bcbad 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -22,19 +22,19 @@ void print_proc_t(int *i,struct task_struct *base,struct task_struct *cur,int is if(is_print){ switch (cur->state) { case TASK_RUNNABLE: - printf("%s %d %s\n",cur->name,cur->pid,"Running"); + printf("%-17s %-2d %s\n",cur->name,cur->pid,"Running"); break; case TASK_SLEEPING: - printf("%s %d %s\n",cur->name,cur->pid,"Sleeping"); + printf("%-17s %-2d %s\n",cur->name,cur->pid,"Sleeping"); break; case TASK_UNINIT: - printf("%s %d %s\n",cur->name,cur->pid,"Init"); + printf("%-17s %-2d %s\n",cur->name,cur->pid,"Init"); break; case TASK_ZOMBIE: - printf("%s %d %s\n",cur->name,cur->pid,"Zombie"); + printf("%-17s %-2d %s\n",cur->name,cur->pid,"Zombie"); break; case TASK_DEATH: - printf("%s %d %s\n",cur->name,cur->pid,"Death"); + printf("%-17s %-2d %s\n",cur->name,cur->pid,"Death"); break; } } @@ -43,19 +43,19 @@ void print_proc_t(int *i,struct task_struct *base,struct task_struct *cur,int is if(is_print){ switch (cur->state) { case TASK_RUNNABLE: - printf("%s %d %s\n",cur->name,cur->pid,"Running"); + printf("%-17s %-2d %s\n",cur->name,cur->pid,"Running"); break; case TASK_SLEEPING: - printf("%s %d %s\n",cur->name,cur->pid,"Sleeping"); + printf("%-17s %-2d %s\n",cur->name,cur->pid,"Sleeping"); break; case TASK_UNINIT: - printf("%s %d %s\n",cur->name,cur->pid,"Init"); + printf("%-17s %-2d %s\n",cur->name,cur->pid,"Init"); break; case TASK_ZOMBIE: - printf("%s %d %s\n",cur->name,cur->pid,"Zombie"); + printf("%-17s %-2d %s\n",cur->name,cur->pid,"Zombie"); break; case TASK_DEATH: - printf("%s %d %s\n",cur->name,cur->pid,"Death"); + printf("%-17s %-2d %s\n",cur->name,cur->pid,"Death"); break; } } @@ -65,10 +65,10 @@ void print_proc_t(int *i,struct task_struct *base,struct task_struct *cur,int is } void print_proc(){ - printf("====--------[Processes]---------===\n"); int index = 0; print_proc_t(&index,current,current->next,1); - printf("Name Pid Status [All Proc: %d]\n\n",index); + printf("====---------------[Processes]----------------====\n"); + printf("Name Pid Status [All Proc: %d]\n\n",index); } static void found_task(int pid,struct task_struct *head,struct task_struct *base,struct task_struct **argv,int first){ @@ -119,23 +119,7 @@ void task_kill(int pid){ return; } argv->state = TASK_DEATH; - switch (argv->state) { - case TASK_RUNNABLE: - printf("%s %d %s\n",argv->name,argv->pid,"Running"); - break; - case TASK_SLEEPING: - printf("%s %d %s\n",argv->name,argv->pid,"Sleeping"); - break; - case TASK_UNINIT: - printf("%s %d %s\n",argv->name,argv->pid,"Init"); - break; - case TASK_ZOMBIE: - printf("%s %d %s\n",argv->name,argv->pid,"Zombie"); - break; - case TASK_DEATH: - printf("%s %d %s\n",argv->name,argv->pid,"Death"); - break; - } + printf("Taskkill process PID:%d Name:%s\n", current->pid, current->name); printf("Task [%s] exit code: -130.\n",argv->name); io_sti(); kfree(argv); diff --git a/kernel/timer.c b/kernel/timer.c index a4316f7..48d483f 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -2,6 +2,7 @@ #include "../include/io.h" #include "../include/graphics.h" #include "../include/cmos.h" +#include "../include/acpi.h" uint32_t tick = 0; extern struct task_struct *current; @@ -24,6 +25,7 @@ static void timer_handle(registers_t *regs) { void sleep(uint32_t timer){ clock_sleep(timer); + //usleep(timer*1000000); } void clock_sleep(uint32_t timer){ diff --git a/sysapp/shell.c b/sysapp/shell.c index d7f37e8..f2140ac 100644 --- a/sysapp/shell.c +++ b/sysapp/shell.c @@ -175,6 +175,13 @@ void cmd_shutdown() { void cmd_debug() { vga_clear(); + + /* + extern multiboot_t *multiboot_all; + svga_mode_info_t *vbe_info = multiboot_all->vbe_mode_info; + printf("%08x\n",vbe_info->screen_height); + */ + printf("%s for x86 [Version %s] \n", OS_NAME, OS_VERSION); printf("\032Copyright 2024 XIAOYI12 (Build by GCC i686-elf-tools)\036\n"); extern int acpi_enable_flag;