From 84e68f2fbd8f9f521f7c8b39cabb1df218c35d80 Mon Sep 17 00:00:00 2001 From: xiaoyi1212 Date: Thu, 11 Apr 2024 22:53:15 +0800 Subject: [PATCH] =?UTF-8?q?=E2=80=9C=E7=BC=A4=E7=BA=B7=E6=9B=B4=E6=96=B0"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +- boot/boot.asm | 1 - boot/graphics.asm | 0 data/queue.c | 2 +- driver/cmos.c | 2 +- driver/keyboard.c | 3 +- driver/vbe.c | 9 ++++ driver/vga.c | 37 ++++++++++++-- include/common.h | 2 +- include/{vga.h => graphics.h} | 12 +++++ include/multiboot.h | 95 +++++++++++++++++++++++++++++++++++ kernel/common.c | 2 +- kernel/idt.c | 4 +- kernel/kernel.c | 18 ++++--- kernel/page.c | 58 +++++++++++++++++---- kernel/task.c | 2 +- kernel/timer.c | 2 +- sysapp/date.c | 2 +- sysapp/shell.c | 46 ++++++++--------- 19 files changed, 243 insertions(+), 58 deletions(-) create mode 100644 boot/graphics.asm create mode 100644 driver/vbe.c rename include/{vga.h => graphics.h} (90%) create mode 100644 include/multiboot.h diff --git a/.gitignore b/.gitignore index 93faeea..60fc945 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,6 @@ i686_elf_tools/ cmake-build-debug/ -isodir/ \ No newline at end of file +isodir/ + +crashpowerdos-x86-nodesktop-rebuild-0.2.0.iso \ No newline at end of file diff --git a/boot/boot.asm b/boot/boot.asm index 85cda49..ef06bcd 100644 --- a/boot/boot.asm +++ b/boot/boot.asm @@ -21,7 +21,6 @@ stack_top: .global _start .type _start, @function _start: - mov $stack_top, %esp call kernel_main diff --git a/boot/graphics.asm b/boot/graphics.asm new file mode 100644 index 0000000..e69de29 diff --git a/data/queue.c b/data/queue.c index d6a9338..663de6e 100644 --- a/data/queue.c +++ b/data/queue.c @@ -1,6 +1,6 @@ #include "../include/queue.h" #include "../include/memory.h" -#include "../include/vga.h" +#include "../include/graphics.h" #include "../include/io.h" Queue *create_queue() { diff --git a/driver/cmos.c b/driver/cmos.c index 508c04e..e9b2192 100644 --- a/driver/cmos.c +++ b/driver/cmos.c @@ -1,7 +1,7 @@ #include "../include/cmos.h" #include "../include/memory.h" #include "../include/io.h" -#include "../include/vga.h" +#include "../include/graphics.h" #include "../include/common.h" static void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { diff --git a/driver/keyboard.c b/driver/keyboard.c index 42e7dca..61ea383 100644 --- a/driver/keyboard.c +++ b/driver/keyboard.c @@ -1,6 +1,5 @@ #include "../include/keyboard.h" - -#include "../include/vga.h" +#include "../include/graphics.h" #include "../include/memory.h" #include "../include/queue.h" #include "../include/io.h" diff --git a/driver/vbe.c b/driver/vbe.c new file mode 100644 index 0000000..078cf62 --- /dev/null +++ b/driver/vbe.c @@ -0,0 +1,9 @@ +#include "../include/graphics.h" + +void vbe_putchar(char c){ + +} + +void vbe_clear(){ + +} diff --git a/driver/vga.c b/driver/vga.c index 42ae5be..fa06897 100644 --- a/driver/vga.c +++ b/driver/vga.c @@ -1,13 +1,14 @@ -#include "../include/vga.h" +#include "../include/graphics.h" #include "../include/common.h" #include "../include/io.h" - size_t terminal_row; size_t terminal_column; uint8_t terminal_color; uint16_t *terminal_buffer; +int status = 0; + static uint16_t cursor_x = 0, cursor_y = 0; // 光标位置 static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) { @@ -31,9 +32,10 @@ static void scroll() { } void vga_install(void) { + status = 0; terminal_row = 0; terminal_column = 0; - terminal_color = vga_entry_color(VGA_COLOR_DARK_GREY, VGA_COLOR_BLACK); + terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); terminal_buffer = (uint16_t *) 0xB8000; //terminal_buffer = (uint16_t*) 0xA0000; for (size_t y = 0; y < VGA_HEIGHT ; y++) { @@ -45,6 +47,10 @@ void vga_install(void) { } void vga_clear() { + if(status){ + vbe_clear(); + return; + } for (size_t y = 0; y < VGA_HEIGHT; y++) { for (size_t x = 0; x < VGA_WIDTH; x++) { const size_t index = y * VGA_WIDTH + x; @@ -74,8 +80,11 @@ void vga_putentryat(char c, uint8_t color, size_t x, size_t y) { } void vga_putchar(char c) { - uint8_t backColor = 0, foreColor = 15; - uint8_t attributeByte = (backColor << 4) | (foreColor & 0x07); // 黑底白字 + if(status){ + vbe_putchar(c); + return; + } + uint8_t attributeByte = terminal_color; // 黑底白字 uint16_t attribute = attributeByte << 8; uint16_t *location; @@ -92,6 +101,24 @@ void vga_putchar(char c) { } else if (c == '\n') { cursor_x = 0; // 光标回首 cursor_y++; // 下一行 + } else if( c == '\033') { + terminal_color = vga_entry_color(VGA_COLOR_LIGHT_RED, VGA_COLOR_BLACK); + return; + }else if( c == '\034') { + terminal_color = vga_entry_color(VGA_COLOR_LIGHT_BLUE, VGA_COLOR_BLACK); + return; + }else if( c == '\035') { + terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREEN, VGA_COLOR_BLACK); + return; + }else if( c == '\036') { + terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); + return; + }else if( c == '\037') { + terminal_color = vga_entry_color(VGA_COLOR_LIGHT_CYAN, VGA_COLOR_BLACK); + return; + }else if( c == '\032') { + terminal_color = vga_entry_color(VGA_COLOR_DARK_GREY, VGA_COLOR_BLACK); + return; } else if (c >= ' ' && c <= '~') { location = terminal_buffer + (cursor_y * 80 + cursor_x); *location = c | attribute; diff --git a/include/common.h b/include/common.h index 95607f8..3fa19a8 100644 --- a/include/common.h +++ b/include/common.h @@ -2,7 +2,7 @@ #define CRASHPOWEROS_COMMON_H #define OS_NAME "CrashPowerDOS" -#define OS_VERSION "v0.2.1" +#define OS_VERSION "v0.2.2" #include #include diff --git a/include/vga.h b/include/graphics.h similarity index 90% rename from include/vga.h rename to include/graphics.h index 27df08c..6e47f46 100644 --- a/include/vga.h +++ b/include/graphics.h @@ -5,6 +5,15 @@ #include #include +/* + * \032 DARK GRAY + * \033 LIGHT RED + * \034 LIGHT BLUE + * \035 LIGHT GREEN + * \036 LIGHT GRAY + * \037 LIGHT CYAN + */ + #define VGA_WIDTH 80 #define VGA_HEIGHT 25 @@ -66,4 +75,7 @@ void vga_clear(); void move_cursor(); void printf(const char *formet, ...); +void vbe_putchar(char c); +void vbe_clear(); + #endif \ No newline at end of file diff --git a/include/multiboot.h b/include/multiboot.h new file mode 100644 index 0000000..597325c --- /dev/null +++ b/include/multiboot.h @@ -0,0 +1,95 @@ +#ifndef INCLUDE_MULTIBOOT_H_ +#define INCLUDE_MULTIBOOT_H_ + +#include + +/** + * 启动后,在32位内核进入点,机器状态如下: + * 1. CS 指向基地址为 0x00000000,限长为4G – 1的代码段描述符。 + * 2. DS,SS,ES,FS 和 GS 指向基地址为0x00000000,限长为4G – + * 1的数据段描述符。 + * 3. A20 地址线已经打开。 + * 4. 页机制被禁止。 + * 5. 中断被禁止。 + * 6. EAX = 0x2BADB002 + * 7. 系统信息和启动信息块的线性地址保存在 EBX中(相当于一个指针)。 + * 以下即为这个信息块的结构 + */ + +typedef struct multiboot_t { + uint32_t flags; // Multiboot 的版本信息 + /** + * 从 BIOS 获知的可用内存 + * + * mem_lower和mem_upper分别指出了低端和高端内存的大小,单位是K。 + * 低端内存的首地址是0,高端内存的首地址是1M。 + * 低端内存的最大可能值是640K。 + * 高端内存的最大可能值是最大值减去1M。但并不保证是这个值。 + */ + uint32_t mem_lower; + uint32_t mem_upper; + + uint32_t boot_device; // 指出引导程序从哪个BIOS磁盘设备载入的OS映像 + uint32_t cmdline; // 内核命令行 + uint32_t mods_count; // boot 模块列表 + uint32_t mods_addr; + + /** + * ELF 格式内核映像的section头表。 + * 包括每项的大小、一共有几项以及作为名字索引的字符串表。 + */ + uint32_t num; + uint32_t size; + uint32_t addr; + uint32_t shndx; + + /** + * 以下两项指出保存由BIOS提供的内存分布的缓冲区的地址和长度 + * mmap_addr是缓冲区的地址,mmap_length是缓冲区的总大小 + * 缓冲区由一个或者多个下面的大小/结构对 mmap_entry_t 组成 + */ + uint32_t mmap_length; + uint32_t mmap_addr; + + uint32_t drives_length; // 指出第一个驱动器结构的物理地址 + uint32_t drives_addr; // 指出第一个驱动器这个结构的大小 + uint32_t config_table; // ROM 配置表 + uint32_t boot_loader_name; // boot loader 的名字 + uint32_t apm_table; // APM 表 + uint32_t vbe_control_info; + uint32_t vbe_mode_info; + uint16_t vbe_mode; + uint16_t vbe_interface_seg; + uint16_t vbe_interface_off; + uint16_t vbe_interface_len; + + unsigned long long framebuffer_addr; + uint32_t framebuffer_pitch; + uint32_t framebuffer_width; + uint32_t framebuffer_height; + char framebuffer_bpp; +} __attribute__((packed)) multiboot_t; + +/** + * size是相关结构的大小,单位是字节,它可能大于最小值20 + * base_addr_low是启动地址的低32位,base_addr_high是高32位,启动地址总共有64位 + * length_low是内存区域大小的低32位,length_high是内存区域大小的高32位,总共是64位 + * type是相应地址区间的类型,1代表可用RAM,所有其它的值代表保留区域 + */ +typedef struct mmap_entry_t { + uint32_t size; // 留意 size 是不含 size 自身变量的大小 + uint32_t base_addr_low; + uint32_t base_addr_high; + uint32_t length_low; + uint32_t length_high; + uint32_t type; +} __attribute__((packed)) mmap_entry_t; + +// 声明全局的 multiboot_t * 指针 +// 内核未建立分页机制前暂存的指针 +extern multiboot_t *mboot_ptr_tmp; + +// 内核页表建立后的指针 +extern multiboot_t *glb_mboot_ptr; + +#endif // INCLUDE_MULTIBOOT_H_ diff --git a/kernel/common.c b/kernel/common.c index 84b6ea4..fc1fb0c 100644 --- a/kernel/common.c +++ b/kernel/common.c @@ -1,5 +1,5 @@ #include "../include/common.h" -#include "../include/vga.h" +#include "../include/graphics.h" #include "../include/memory.h" #include "../include/io.h" diff --git a/kernel/idt.c b/kernel/idt.c index f9351e9..c9693df 100644 --- a/kernel/idt.c +++ b/kernel/idt.c @@ -1,8 +1,7 @@ #include "../include/description_table.h" #include "../include/memory.h" #include "../include/io.h" -#include "../include/isr.h" -#include "../include/vga.h" +#include "../include/graphics.h" static isr_t interrupt_handlers[256]; idt_entry_t idt_entries[256]; // IDT有256个描述符 @@ -49,6 +48,7 @@ void idt_install() { memset(&idt_entries, 0, sizeof(idt_entry_t) * 256); + // 初始化PIC outb(0x20, 0x11); outb(0xA0, 0x11); outb(0x21, 0x20); diff --git a/kernel/kernel.c b/kernel/kernel.c index 03fdada..94465cb 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -1,5 +1,6 @@ +#include "../include/multiboot.h" #include "../include/common.h" -#include "../include/vga.h" +#include "../include/graphics.h" #include "../include/description_table.h" #include "../include/io.h" #include "../include/memory.h" @@ -11,22 +12,23 @@ #include "../include/date.h" extern uint32_t end; +extern int status; uint32_t placement_address = (uint32_t) & end; -void kernel_main() { +void kernel_main(multiboot_t *multiboot) { io_cli(); vga_install(); - printf("[kernel]: VGA driver load success!\n"); + printf("[\035kernel\036]: VGA driver load success!\n"); gdt_install(); idt_install(); - printf("[kernel]: description table config success!\n"); + printf("[\035kernel\036]: description table config success!\n"); init_timer(10); init_page(); - printf("[kernel]: page set success!\n"); + printf("[\035kernel\036]: page set success!\n"); init_sched(); - printf("[kernel]: PCB load success!\n"); + printf("[\035kernel\036]: PCB load success!\n"); init_keyboard(); - printf("[kernel]: Keyboard driver load success!\n"); + printf("[\035kernel\036]: Keyboard driver load success!\n"); print_cpu_id(); io_sti(); @@ -34,7 +36,7 @@ void kernel_main() { clock_sleep(25); kernel_thread(setup_shell,NULL,"CPOS-Shell"); - kernel_thread(setup_date,NULL,"CPOS-Date"); + if(!status) kernel_thread(setup_date,NULL,"CPOS-Date"); for (;;){ io_hlt(); diff --git a/kernel/page.c b/kernel/page.c index e6269d9..357512b 100644 --- a/kernel/page.c +++ b/kernel/page.c @@ -1,6 +1,7 @@ #include "../include/memory.h" -#include "../include/vga.h" +#include "../include/graphics.h" #include "../include/io.h" +#include "../include/task.h" page_directory_t *kernel_directory = 0; // 内核用页目录 page_directory_t *current_directory = 0; // 当前页目录 @@ -8,6 +9,8 @@ page_directory_t *current_directory = 0; // 当前页目录 uint32_t *frames; uint32_t nframes; +extern struct task_struct *current; + extern uint32_t placement_address; extern void *program_break, *program_break_end; @@ -106,19 +109,56 @@ void page_fault(registers_t *regs) { int id = regs->err_code & 0x10; // 由取指引起 printf("[ERROR]: Page fault |"); - if (present) + if (present) { printf("Type: present;\n\taddress: %x ", faulting_address); - else if (rw) + 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 (rw) { printf("Type: read-only;\n\taddress: %x", faulting_address); - else if (us) + 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); - else if (reserved) + 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); - else if (id) + 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", faulting_address); - - - for (;;) io_hlt(); + 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); + } + } } void init_page() { diff --git a/kernel/task.c b/kernel/task.c index f6122e1..4d7bdba 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -1,6 +1,6 @@ #include "../include/task.h" #include "../include/common.h" -#include "../include/vga.h" +#include "../include/graphics.h" struct task_struct *running_proc_head = NULL; struct task_struct *wait_proc_head = NULL; diff --git a/kernel/timer.c b/kernel/timer.c index bee4d43..fb41819 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1,6 +1,6 @@ #include "../include/timer.h" #include "../include/io.h" -#include "../include/vga.h" +#include "../include/graphics.h" #include "../include/isr.h" #include "../include/task.h" diff --git a/sysapp/date.c b/sysapp/date.c index c722013..93b56fe 100644 --- a/sysapp/date.c +++ b/sysapp/date.c @@ -1,6 +1,6 @@ #include "../include/date.h" #include "../include/cmos.h" -#include "../include/vga.h" +#include "../include/graphics.h" #include "../include/timer.h" extern uint16_t *terminal_buffer; diff --git a/sysapp/shell.c b/sysapp/shell.c index 72410ca..695c1e9 100644 --- a/sysapp/shell.c +++ b/sysapp/shell.c @@ -1,6 +1,6 @@ #include "../include/shell.h" #include "../include/queue.h" -#include "../include/vga.h" +#include "../include/graphics.h" #include "../include/common.h" #include "../include/task.h" #include "../include/cmos.h" @@ -96,12 +96,12 @@ void cmd_ls() { void cmd_cat(int argc, char **argv) { if (argc <= 2) { - printf("[Shell-CAT]: If there are too few parameters, please specify the filename and data."); + printf("\033[Shell-CAT]: If there are too few parameters, please specify the filename and data.\036\n"); return; } struct File *file = open_file(argv[1]); if (file == NULL) { - printf("[Shell-CAT]: Not found [%s] \n", argv[1]); + printf("\033[Shell-CAT]: Not found [%s]\036 \n", argv[1]); return; } @@ -119,13 +119,13 @@ void cmd_cat(int argc, char **argv) { void cmd_read(int argc, char **argv) { if (argc == 1) { - printf("[Shell-READ]: If there are too few parameters, please specify the filename"); + printf("\033[Shell-READ]: If there are too few parameters, please specify the filename.\036\n"); return; } struct File *file = open_file(argv[1]); char *buffer = (char *) kmalloc(sizeof(char) * 4096); if (file == NULL) { - printf("[Shell-READ]: Not found [%s] \n", argv[1]); + printf("\033[Shell-READ]: Not found [%s]\036 \n", argv[1]); return; } @@ -137,13 +137,13 @@ void cmd_read(int argc, char **argv) { void cmd_mkdir(int argc, char **argv) { if (argc == 1) { - printf("[Shell-MKDIR]: If there are too few parameters, please specify the directory name"); + printf("\033[Shell-MKDIR]: If there are too few parameters, please specify the directory name.\036\n"); return; } printf("Create directory: %s\n",argv[1]); struct File *dir = create_dir(argv[1]); if (dir == NULL) { - printf("[Shell-MKDIR]: Cannot create directory '%s'.", argv[1]); + printf("\033[Shell-MKDIR]: Cannot create directory '%s'.\036\n", argv[1]); return; } kfree(dir); @@ -151,12 +151,12 @@ void cmd_mkdir(int argc, char **argv) { void cmd_del(int argc, char **argv) { if (argc == 1) { - vga_writestring("[Shell-DEL]: If there are too few parameters, please specify the folder name.\n"); + vga_writestring("\033[Shell-DEL]: If there are too few parameters, please specify the folder name.\036\n"); return; } struct File *info = open_file(argv[1]); if (info == NULL) { - printf("[Shell-DEL]: Not found [%s] \n", argv[1]); + printf("\033[Shell-DEL]: Not found [%s]\036 \n", argv[1]); return; } delete_file(info); @@ -172,14 +172,14 @@ void cmd_reset(){ void setup_shell(){ vga_clear(); printf("%s for x86 [Version %s] \n",OS_NAME, OS_VERSION); - printf("Copyright 2024 XIAOYI12 (Build by GCC i686-elf-tools)\n"); + printf("\032Copyright 2024 XIAOYI12 (Build by GCC i686-elf-tools)\036\n"); char com[MAX_COMMAND_LEN]; char *argv[MAX_ARG_NR]; int argc = -1; while (1) { - printf("CPOS/> "); + printf("\035CPOS/>\036 "); if (gets(com, MAX_COMMAND_LEN) <= 0) continue; argc = cmd_parse(com, argv, ' '); @@ -211,18 +211,18 @@ void setup_shell(){ else if (!strcmp("reset", argv[0])) cmd_reset(); else if (!strcmp("help", argv[0]) || !strcmp("?", argv[0]) || !strcmp("h", argv[0])) { - vga_writestring("-=[CrashPowerShell Helper]=-\n"); - vga_writestring("help ? h Print shell help info.\n"); - vga_writestring("version Print os version.\n"); - vga_writestring("echo Print message.\n"); - vga_writestring("ls List all files.\n"); - vga_writestring("cat Edit a file\n"); - vga_writestring("read Read a file\n"); - vga_writestring("mkdir Make a directory\n"); - vga_writestring("del rm Delete a file\n"); - vga_writestring("sysinfo Print system info.\n"); - vga_writestring("proc Lists all running processes.\n"); - vga_writestring("reset Reset OS.\n"); + vga_writestring("-=[\037CrashPowerShell Helper\036]=-\n"); + vga_writestring("help ? h \032Print shell help info.\036\n"); + vga_writestring("version \032Print os version.\036\n"); + vga_writestring("echo \032Print message.\036\n"); + vga_writestring("ls \032List all files.\036\n"); + vga_writestring("cat \032Edit a file.\036\n"); + vga_writestring("read \032Read a file.\036\n"); + vga_writestring("mkdir \032Make a directory.\036\n"); + vga_writestring("del rm \032Delete a file.\036\n"); + vga_writestring("sysinfo \032Print system info.\036\n"); + vga_writestring("proc \032Lists all running processes.\036\n"); + vga_writestring("reset \032Reset OS.\036\n"); } else printf("[Shell]: Unknown command '%s'.\n", argv[0]); } }