From e5890fd8f723a948fffb28cc73990c6749f36260 Mon Sep 17 00:00:00 2001 From: Elizabeth Alexander Hunt Date: Wed, 7 Oct 2026 09:17:15 -0700 Subject: VBE attempt 1 --- src/boot.asm | 25 ++++++++-- src/kernel.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 147 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/boot.asm b/src/boot.asm index cbf57d6..c88f08c 100644 --- a/src/boot.asm +++ b/src/boot.asm @@ -1,20 +1,37 @@ ;> The Multiboot header must be contained completely within the first 8192 bytes of the OS ;> image, and must be longword (32-bit) aligned. MULTIBOOT_ALIGN_TO_PAGE: equ 1 << 0 -MULTIBOOT_MEMORY_DESCRIBE: equ 1 << 2 +MULTIBOOT_MEMORY_DESCRIBE: equ 1 << 1 +MULTIBOOT_VIDEO_MODE: equ 1 << 2 MULTIBOOT_MAGIC: equ 0x1BADB002 -MULTIBOOT_FLAGS: equ (MULTIBOOT_ALIGN_TO_PAGE | MULTIBOOT_MEMORY_DESCRIBE) +MULTIBOOT_FLAGS: equ (MULTIBOOT_ALIGN_TO_PAGE | MULTIBOOT_MEMORY_DESCRIBE | MULTIBOOT_VIDEO_MODE) MULTIBOOT_CHECKSUM: equ -(MULTIBOOT_MAGIC + MULTIBOOT_FLAGS) -section .multiboot_header +MULTIBOOT_VIDEO_TYPE: equ 0 +MULTIBOOT_GODS_WIDTH: equ 640 +MULTIBOOT_GODS_HEIGHT: equ 480 +MULTIBOOT_VIDEO_BPP: equ 16 + +; We don't set flags[16] because we assemble to ELF32 so header_addr, etc is useless to us +; (at least at the moment). +UNUSED_BYTES_COUNT: equ 5*4 +section .multiboot_header: +; I guess multiboot 2 requires a length field and we might migrate to that in the future. +multiboot_header_start: align 4 dd MULTIBOOT_MAGIC dd MULTIBOOT_FLAGS dd MULTIBOOT_CHECKSUM + times UNUSED_BYTES_COUNT db 0 + dd MULTIBOOT_VIDEO_TYPE + dd MULTIBOOT_GODS_WIDTH + dd MULTIBOOT_GODS_HEIGHT + dd MULTIBOOT_VIDEO_BPP +multiboot_header_end: STACK_SIZE: equ (1 << 14) section .bss align 16 -stack_bottom: +stack_bottom: ; ("haha bottom" somewhere in there??) resb STACK_SIZE stack_top: diff --git a/src/kernel.c b/src/kernel.c index 1459f73..917c07e 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1,36 +1,134 @@ #include #include +#include -#define WIDTH 80 -#define HEIGHT 25 - -#define BLACK 0 -#define BLUE 1 -#define GREEN 2 -#define RED 4 -#define MAGENTA 13 -#define WHITE 15 - -int strlen(char* s) { - int n = 0; - char* s_ptr = s; - while (*(s_ptr++)) { - n++; - } - return n; +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long long u64; + +#ifndef asm +#define asm __asm__ volatile +#endif + +struct __attribute__((packed)) multiboot_info +{ + /* Multiboot info version number */ + u32 flags; + + /* Available memory from BIOS */ + u32 mem_lower; + u32 mem_upper; + + /* "root" partition */ + u32 boot_device; + + /* Kernel command line */ + u32 cmdline; + + /* Boot-Module list */ + u32 mods_count; + u32 mods_addr; + +// union +// { +// multiboot_aout_symbol_table_t aout_sym; +// multiboot_elf_section_header_table_t elf_sec; +// } u; + u32 unused_1; + u32 unused_2; + u32 unused_3; + u32 unused_4; + + /* Memory Mapping buffer */ + u32 mmap_length; + u32 mmap_addr; + + /* Drive Info buffer */ + u32 drives_length; + u32 drives_addr; + + /* ROM configuration table */ + u32 config_table; + + /* Boot Loader Name */ + u32 boot_loader_name; + + /* APM table */ + u32 apm_table; + + /* Video */ + u32 vbe_control_info; + u32 vbe_mode_info; + u16 vbe_mode; + u16 vbe_interface_seg; + u16 vbe_interface_off; + u16 vbe_interface_len; + + u64 framebuffer_addr; + u32 framebuffer_pitch; + u32 framebuffer_width; + u32 framebuffer_height; + u8 framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + u8 framebuffer_type; + union + { + struct + { + u32 framebuffer_palette_addr; + u16 framebuffer_palette_num_colors; + }; + struct + { + u8 framebuffer_red_field_position; + u8 framebuffer_red_mask_size; + u8 framebuffer_green_field_position; + u8 framebuffer_green_mask_size; + u8 framebuffer_blue_field_position; + u8 framebuffer_blue_mask_size; + }; + }; +}; +typedef struct multiboot_info multiboot_info_t; + +u8 inportb(u16 port) { + u8 r; + asm("inb %1, %0" : "=a" (r) : "dN" (port)); + return r; +} + +void outportb(u16 port, u8 data) { + asm("outb %1, %0" : : "dN" (port), "a" (data)); +} + +// TODO: Why won't this work? void macaroni_panic(char* msg) { +void macaroni_panic() { + // we'll do something with msg later. + while(true){ asm("nop\n\t"); } +} + +void macaroni_assert(bool condition) { + if (condition) { + return; + } + macaroni_panic(); } void cmain(void) { - uint16_t* vgamem = (uint16_t*) 0xB8000; - uint16_t vgacolors[6] = {WHITE | RED << 4, WHITE | GREEN << 4, WHITE | BLUE << 4, BLACK | RED << 4, BLACK | GREEN << 4, BLACK | BLUE << 4}; - char* s = "Hello world!"; - int i,j,k; - for (k = 0; k >= 0; ++k) { - k = (k % 5); - j = 0; - while (j < 100000000) { j++; } // Since we don't have an interrupt descriptor table we can't use the PIC; this emulates "sleeping" - for (i = 0; i < WIDTH*HEIGHT; i++) { - vgamem[i] = s[i % strlen(s)] | vgacolors[(i+k) % 6] << 8; + u32 magic_response = 0x1; + multiboot_info_t* p_multiboot_info; + asm("\t movl %%eax,%0" : "=r"(magic_response)); + asm("\t movl %%ebx,%0" : "=r"(p_multiboot_info)); + + void *fb = (void *) (unsigned long) p_multiboot_info->framebuffer_addr; + u8* pixel = fb; + for (int i = 0; i < 10000; i++) { + *(pixel + i) = i * 2; } - } + + macaroni_assert(magic_response == 0x2BADB002); + //asm("int $0x13"); } \ No newline at end of file -- cgit v1.3