From ad28352c29d2a56a6f2f6233529d01f3e4aa87c0 Mon Sep 17 00:00:00 2001 From: Greg Bowne Date: Tue, 10 Oct 2023 01:12:56 -0700 Subject: [PATCH] Fixing a bunch of broken stuff including the looping bootloader boot.asm --- .clang-format | 3 +- .clang-tidy | 52 +++++++++++--- .gdbinit | 14 +++- CMakeLists.txt | 3 + ask.txt | 15 ++-- src/boot/boot.asm | 147 +++++++++++++++++++++++++------------- src/boot/grub/grub.cfg | 0 src/boot/grub/menu.lst | 0 src/boot/linker.ld | 42 ++++++++--- src/kernel/arch/x86/gdt.c | 16 ++--- src/kernel/arch/x86/idt.h | 4 +- src/kernel/arch/x86/isr.c | 6 +- src/kernel/arch/x86/isr.h | 2 + 13 files changed, 219 insertions(+), 85 deletions(-) delete mode 100644 src/boot/grub/grub.cfg delete mode 100644 src/boot/grub/menu.lst diff --git a/.clang-format b/.clang-format index 56cce94..160f7c1 100644 --- a/.clang-format +++ b/.clang-format @@ -1,5 +1,6 @@ --- -Language: Cpp +Language: C +Standard: C11 (or C17) BasedOnStyle: LLVM IndentWidth: 4 UseTab: Never diff --git a/.clang-tidy b/.clang-tidy index 4ce4d99..a739735 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,12 +1,48 @@ -Checks: "clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,modernize-*,-modernize-use-trailing-return-type" +Checks: "clang-diagnostic-*,clang-analyzer-*,modernize-*,-modernize-use-trailing-return-type" WarningsAsErrors: true HeaderFilterRegex: "" AnalyzeTemporaryDtors: false -FormatStyle: google +FormatStyle: llvm CheckOptions: - - key: cert-dcl16-c.NewSuffixes - value: "L;LL;LU;LLU" - - key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField - value: "0" - - key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors - value: "1" + - key: modernize-use-trailing-return-type.Enabled + value: false + - key: readability-identifier-naming.NamespaceCase + value: CamelCase + - key: readability-identifier-naming.ClassCase + value: CamelCase + - key: readability-identifier-naming.StructCase + value: CamelCase + - key: readability-identifier-naming.FunctionCase + value: CamelCase + - key: readability-identifier-naming.VariableCase + value: camelBack + - key: readability-identifier-naming.ConstantCase + value: UPPER_CASE + - key: readability-identifier-naming.EnumCase + value: CamelCase + - key: readability-identifier-naming.EnumConstantCase + value: UPPER_CASE + - key: readability-identifier-naming.GlobalConstantCase + value: UPPER_CASE + - key: readability-identifier-naming.GlobalVariableCase + value: camelBack + - key: readability-identifier-naming.LocalConstantCase + value: camelBack + - key: readability-identifier-naming.LocalVariableCase + value: camelBack + - key: readability-identifier-naming.MemberConstantCase + value: camelBack + - key: readability-identifier-naming.MemberVariableCase + value: camelBack + - key: readability-identifier-naming.ParameterCase + value: camelBack + - key: readability-identifier-naming.TemplateParameterCase + value: camelBack + - key: readability-identifier-naming.TypedefCase + value: CamelCase + - key: readability-identifier-naming.TypeAliasCase + value: CamelCase + - key: readability-identifier-naming.TypeTemplateParameterCase + value: CamelCase + - key: readability-identifier-naming.VariableTemplateCase + value: camelBack diff --git a/.gdbinit b/.gdbinit index e75f5fa..e85cad3 100644 --- a/.gdbinit +++ b/.gdbinit @@ -4,6 +4,16 @@ set architecture i386 # Set the disassembly flavor set disassembly-flavor intel +set disassemble-next-line + +set pagination enable + +set print address + +set logging enable + +set logging file gdb.log + # Set the prompt set prompt (gdb) @@ -16,10 +26,10 @@ set history size 1000 set solib-search-path . # Set the default directory -cd /path/to/project +d /home/user/Documents/ClassicOS # Set the default target -file kernel +file ClassicOS/build/kernel # Set the symbol file symbol-file kernel diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f11616..7bce36f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,10 @@ set(CMAKE_EXE_LINKER_FLAGS "-g -s") set(CMAKE_LINK_FLAGS "${CMAKE_LINK_FLAGS} -e kernel_main") set(CMAKE_CXX_FLAGS "-g -Wall") set(CMAKE_C_FLAGS "-g -Wall -m32") +set(CMAKE_C_FLAGS_DEBUG "-g") set(CMAKE_BUILD_TYPE Debug) +set(CMAKE_GDB_COMMAND gdb) +set(CMAKE_CXX_FLAGS_DEBUG "-g -O0") set(CMAKE_CXX_COMPILER g++) set(CMAKE_ASM_COMPILER nasm) set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} --32") diff --git a/ask.txt b/ask.txt index c98c80c..f36c54d 100644 --- a/ask.txt +++ b/ask.txt @@ -147,16 +147,23 @@ target_link_libraries(ClassicOS PRIVATE) set(CMAKE_C_COMPILER gcc) set(CMAKE_LINKER ld) -set(CMAKE_EXE_LINKER_FLAGS "-g") +set(CMAKE_EXE_LINKER_FLAGS "-g -s") +set(CMAKE_LINK_FLAGS "${CMAKE_LINK_FLAGS} -e kernel_main") set(CMAKE_CXX_FLAGS "-g -Wall") -set(CMAKE_C_FLAGS "-g -Wall") +set(CMAKE_C_FLAGS "-g -Wall -m32") +set(CMAKE_C_FLAGS_DEBUG "-g") set(CMAKE_BUILD_TYPE Debug) +set(CMAKE_GDB_COMMAND gdb) +set(CMAKE_CXX_FLAGS_DEBUG "-g -O0") set(CMAKE_CXX_COMPILER g++) set(CMAKE_ASM_COMPILER nasm) +set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} --32") set(CMAKE_SYSTEM_PROCESSOR i386) +set(CMAKE_SYSTEM_NAME None) set(CMAKE_ASM_NASM_COMPILER nasm) set(CMAKE_C_STANDARD 17) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) set(CMAKE_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/build) -set_target_properties(ClassicOS PROPERTIES LINK_FLAGS "-T ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld") \ No newline at end of file +set_target_properties(ClassicOS PROPERTIES LINK_FLAGS "-T ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld") + diff --git a/src/boot/boot.asm b/src/boot/boot.asm index 901d3b8..f652fef 100644 --- a/src/boot/boot.asm +++ b/src/boot/boot.asm @@ -1,61 +1,110 @@ ; Set up the segment registers - xor ax, ax - mov ds, ax - mov es, ax +xor ax, ax +mov ds, ax +mov es, ax - ; Set up stack and jump to main - mov ss, ax - mov sp, 0x7c00 - jmp main +; Set up stack and jump to main +mov ss, ax +mov sp, 0x7c00 +jmp main - ; Print 'Booting ClassicOS!' to the screen - print: - mov si, message - mov ah, 0x0e - .loop: - lodsb - test al, al - jz .done - int 0x10 - jmp .loop - .done: - ret +; Print 'Booting ClassicOS!' to the screen +print: + mov si, message + mov ah, 0x0e +.loop: + lodsb + test al, al + jz .done + int 0x10 + jmp .loop +.done: + ret - ; Set the video mode to a 40 column text mode - set_video_mode: - mov ax, 0x0003 ; Set up a 80x25 text mode - int 0x10 +; Set the video mode to a 40 column text mode +set_video_mode: + mov ax, 0x0003 ; Set up a 80x25 text mode + int 0x10 - ; Set the number of columns to 40 - mov ax, 0x1112 - mov bx, 0x0007 - int 0x10 + ; Set the number of columns to 40 + mov ax, 0x1112 + mov bx, 0x0007 + int 0x10 - ret + ret - ; Bootloader entry point - main: - ; Call the set_video_mode function - call set_video_mode +; Detect floppy disk drive +detect_disk: + mov ah, 0x08 + int 0x13 + cmp ah, 0 + jne .error + ret - ; Clear the screen - mov ah, 0x06 - mov al, 0 - xor bx, bx - xor cx, cx - mov dh, 24 - mov dl, 39 - int 0x10 +.error: + ; Handle disk detection error + ; Display error message or take appropriate action + ret - ; Call the print function - call print +; Read sectors from floppy disk +read_sectors: + mov ah, 0x02 + mov al, 1 ; Number of sectors to read + mov ch, 0 ; Cylinder/Track number + mov cl, 2 ; Sector number (starting from 1) + mov dh, 0 ; Head number + mov dl, 0 ; Drive number (0 for floppy disk) - ; Infinite loop - .loop: - jmp .loop + mov bx, buffer ; Destination buffer + mov es, bx + xor bx, bx - ; Message to print - message db 'Booting ClassicOS!', 0 + int 0x13 - times 510-($-$$) db 0 - dw 0xaa55 + jc .error ; Check carry flag for error + ret + +.error: + ; Handle read error + ; Display error message or take appropriate action + ret + +; Bootloader entry point +main: + ; Call the set_video_mode function + call set_video_mode + + ; Clear the screen + mov ah, 0x06 + mov al, 0 + xor bx, bx + xor cx, cx + mov dh, 24 + mov dl, 39 + int 0x10 + + ; Call the print function + call print + + ; Wait for a key press to exit the loop + mov ah, 0x00 + int 0x16 + + ; Call the detect_disk function + call detect_disk + + ; Call the read_sectors function + call read_sectors + + ; Infinite loop +.loop: + jmp .loop + +; Message to print +message db 'Booting ClassicOS!', 0 + +; Buffer to store read sectors +buffer times 512 db 0 + +times 510-($-$$) db 0 +dw 0xaa55 \ No newline at end of file diff --git a/src/boot/grub/grub.cfg b/src/boot/grub/grub.cfg deleted file mode 100644 index e69de29..0000000 diff --git a/src/boot/grub/menu.lst b/src/boot/grub/menu.lst deleted file mode 100644 index e69de29..0000000 diff --git a/src/boot/linker.ld b/src/boot/linker.ld index b01bd5f..fda2a64 100644 --- a/src/boot/linker.ld +++ b/src/boot/linker.ld @@ -1,8 +1,34 @@ -ENTRY(boot) - SECTIONS { - . = 0x7c00; - .text : { - *(.text) - } - /* Add other sections as needed */ - } \ No newline at end of file +ENTRY(start) +SECTIONS { + . = 0x7c00; + + .text : { + *(.text) + } + + .data : { + *(.data) + } + + .bss : { + *(.bss) + } + + /* Define the bootloader signature at the end of the bootloader */ + bootloader_signature : { + *(.bootloader_signature) + } + + /* Define the bootloader magic number at the end of the bootloader */ + bootloader_magic : { + *(.bootloader_magic) + } + + /* Define the bootloader padding to fill up the remaining space */ + bootloader_padding : { + *(.bootloader_padding) + } + + /* Set the bootloader size to 512 bytes */ + = 512; +} \ No newline at end of file diff --git a/src/kernel/arch/x86/gdt.c b/src/kernel/arch/x86/gdt.c index ed5f819..bf04da6 100644 --- a/src/kernel/arch/x86/gdt.c +++ b/src/kernel/arch/x86/gdt.c @@ -80,7 +80,7 @@ void gdt_init() } // Exception handlers -extern void divide_error(); +extern void divide_error(struct idt_regs *regs); extern void page_fault(struct idt_regs *regs); extern void general_protection_fault(); extern void double_fault(); @@ -92,20 +92,20 @@ extern void keyboard(); extern void device(); // Register an ISR -void isr_register(uint8_t num, void (*handler)(struct idt_regs *)) +void isr_register(uint8_t num, void (*handler)(struct isr_regs *)) { isr_table[num] = handler; } +void divide_error(struct idt_regs *regs) +{ + printf("Divide by zero error!\n"); + // Additional actions can be taken as needed +} + // Initialize the ISR void isr_init() { - // Initialize ISR table - for (int i = 0; i < ISR_TABLE_SIZE; i++) - { - isr_table[i] = NULL; - } - // Register exception handlers isr_register(0, divide_error); isr_register(PAGE_FAULT, page_fault); diff --git a/src/kernel/arch/x86/idt.h b/src/kernel/arch/x86/idt.h index 0fa2204..5abc491 100644 --- a/src/kernel/arch/x86/idt.h +++ b/src/kernel/arch/x86/idt.h @@ -2,7 +2,7 @@ #define IDT_H #include - +#include "isr.h" // IDT entry structure struct idt_entry { @@ -21,7 +21,7 @@ struct idt_ptr } __attribute__((packed)); // Exception handlers -void divide_error(); +void divide_error(struct idt_regs *regs); void double_fault(); // Interrupt handlers diff --git a/src/kernel/arch/x86/isr.c b/src/kernel/arch/x86/isr.c index 5d508a6..36ea722 100644 --- a/src/kernel/arch/x86/isr.c +++ b/src/kernel/arch/x86/isr.c @@ -18,7 +18,7 @@ void dummy_isr(struct isr_regs *regs) } // ISR table -extern void (*isr_table[256])(struct isr_regs *regs); +void (*isr_table[256])(struct isr_regs *regs) = {0}; // Register an ISR extern void isr_register(uint8_t num, void (*handler)(struct isr_regs *regs)) @@ -32,7 +32,7 @@ void isr_handler(struct idt_regs *regs) switch (regs->int_no) { case 0x00: - divide_error(); + divide_error(regs); break; case 0x06: invalid_opcode(); @@ -74,7 +74,7 @@ void isr_handler(struct idt_regs *regs) } // Exception handlers -void divide_error() +void divide_error(struct idt_regs *regs) { printf("Divide by zero error!\n"); // Additional actions can be taken as needed diff --git a/src/kernel/arch/x86/isr.h b/src/kernel/arch/x86/isr.h index 989c56b..b6223fa 100644 --- a/src/kernel/arch/x86/isr.h +++ b/src/kernel/arch/x86/isr.h @@ -3,6 +3,8 @@ #include +extern void (*isr_table[256])(struct isr_regs *regs); + struct isr_regs { uint32_t gs, fs, es, ds; // Segment selectors