diff options
-rw-r--r-- | src/kernel/main.c | 180 | ||||
-rw-r--r-- | src/kernel/vga.c | 45 | ||||
-rw-r--r-- | src/kernel/vga.h | 5 |
3 files changed, 195 insertions, 35 deletions
diff --git a/src/kernel/main.c b/src/kernel/main.c index 2c4a24f..6993233 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -24,27 +24,27 @@ OF THIS SOFTWARE. #include <stdbool.h> enum tag_type { - BOOT_COMMAND = 1, - LOADER_NAME = 2, - BOOT_MODULES = 3, - MEMORY_INFO = 4, - BOOT_DEVICE = 5, - MEMORY_MAP = 6, - VBE_INFO = 7, - FBUF_INFO = 8, - ELF_SYMBOLS = 9, - APM_TABLE = 10, - EFI_I386_TABLE = 11, - EFI_AMD64_TABLE = 12, - SMBIOS_TABLE = 13, - RSDP_ACPI1 = 14, - RSDP_ACPI2 = 15, - NETWORK_INFO = 16, - EFI_MEMORY_MAP = 17, - EFI_SERVICES = 18, - EFI_I386_HANDLE = 19, - EFI_AMD64_HANDLE = 20, - IMAGE_BASE_ADDR = 21 + BOOT_COMMAND = 0x00000001, + LOADER_NAME = 0x00000002, + BOOT_MODULES = 0x00000003, + MEMORY_INFO = 0x00000004, + BOOT_DEVICE = 0x00000005, + MEMORY_MAP = 0x00000006, + VBE_INFO = 0x00000007, + FBUF_INFO = 0x00000008, + ELF_SYMBOLS = 0x00000009, + APM_TABLE = 0x0000000a, + EFI_I386_TABLE = 0x0000000b, + EFI_AMD64_TABLE = 0x0000000c, + SMBIOS_TABLE = 0x0000000d, + RSDP_ACPI1 = 0x0000000e, + RSDP_ACPI2 = 0x0000000f, + NETWORK_INFO = 0x00000010, + EFI_MEMORY_MAP = 0x00000011, + EFI_SERVICES = 0x00000012, + EFI_I386_HANDLE = 0x00000013, + EFI_AMD64_HANDLE = 0x00000014, + IMAGE_BASE_ADDR = 0x00000015 }; struct tag_start { @@ -72,6 +72,47 @@ struct mmap_tag_entry { uint32_t type; } __attribute__ ((__packed__)); +struct vbe_tag { + uint16_t mode; + uint16_t v2_segment; + uint16_t v2_offset; + uint16_t v2_length; + uint8_t control_info[512]; + uint8_t mode_info[256]; +} __attribute__ ((__packed__)); + +enum color_types { + PALETTE = 0x00, + RGB = 0x01, + TEXT = 0x02 +}; + +struct fbuf_tag { + uint32_t address_low; + uint32_t address_high; + uint32_t pitch; + uint32_t width; + uint32_t height; + uint8_t bpp; + uint8_t color_type; + uint8_t padding; +} __attribute__ ((__packed__)); + +struct fbuf_palette_entry { + uint8_t red; + uint8_t green; + uint8_t blue; +} __attribute__ ((__packed__)); + +struct fbuf_rgb_info { + uint8_t red_pos; + uint8_t red_mask; + uint8_t green_pos; + uint8_t green_mask; + uint8_t blue_pos; + uint8_t blue_mask; +} __attribute__ ((__packed__)); + struct boot_device_tag boot_device; bool have_boot_device = false; bool have_mmap = false; @@ -88,14 +129,26 @@ enum error_codes { struct tag_start *tag_pointer; uint32_t main(void) { - put_sz("Multiboot info:\n"); + put_sz("Multiboot info:"); while (tag_pointer->type) { - put_sz(" Tag type 0x"); + put_sz("\n Tag type 0x"); put_32_hex(tag_pointer->type); put_sz(" with size 0x"); put_32_hex(tag_pointer->size); switch (tag_pointer->type) { + case LOADER_NAME: + put_sz(": bootloader name\n "); + put_sz((uint8_t *)(tag_pointer + 1)); + break; + + case MEMORY_INFO: + put_sz(": memory size\n Lower memory: 0x"); + put_32_hex((tag_pointer + 1)->type); + put_sz("\n Upper memory: 0x"); + put_32_hex((tag_pointer + 1)->size); + break; + case BOOT_DEVICE: boot_device = *(struct boot_device_tag *)(tag_pointer + 1); have_boot_device = true; @@ -107,17 +160,15 @@ uint32_t main(void) { if (boot_device.subpartition != 0xffffffff) { put_sz("\n Subpartition number: "); put_32_hex(boot_device.subpartition); - put_char('\n'); } else - put_sz("\n No subpartition\n"); + put_sz("\n No subpartition"); } else - put_sz("\n No partition\n"); + put_sz("\n No partition"); break; - case MEMORY_MAP: - { + case MEMORY_MAP: { uint32_t size = *(uint32_t *)(tag_pointer + 1); struct mmap_tag_entry *tag = (struct mmap_tag_entry *)(tag_pointer + 2); struct mmap_tag_entry *end = (struct mmap_tag_entry *)((uint32_t)tag_pointer + tag_pointer->size); @@ -177,7 +228,6 @@ uint32_t main(void) { put_sz(" Total usable memory: 0x"); put_32_hex(usable); - put_char('\n'); bool dirty; do { @@ -202,8 +252,70 @@ uint32_t main(void) { have_mmap = true; break; } + + case VBE_INFO: { + struct vbe_tag *vbe_info = (struct vbe_tag *)(tag_pointer + 1); + put_sz(": VBE information"); + if (vbe_info->v2_length) { + put_sz("\n v2: 0x"); + put_16_hex(vbe_info->v2_segment); + put_sz(":0x"); + put_16_hex(vbe_info->v2_offset); + put_sz(" + 0x"); + put_16_hex(vbe_info->v2_length); + } + put_sz("\n v3 mode: 0x"); + put_16_hex(vbe_info->mode); + break; + } + + case FBUF_INFO: { + struct fbuf_tag *fbuf_info = (struct fbuf_tag *)(tag_pointer + 1); + put_sz(": framebuffer information\n Address: 0x"); + put_32_hex(fbuf_info->address_high); + put_char(':'); + put_32_hex(fbuf_info->address_low); + put_sz("\n Pitch: "); + put_32_dec(fbuf_info->pitch); + put_sz("B\n Size: "); + put_32_dec(fbuf_info->width); + put_sz(" x "); + put_32_dec(fbuf_info->height); + put_sz(" x "); + put_8_dec(fbuf_info->bpp); + switch (fbuf_info->color_type) { + case PALETTE: + put_sz("b\n Palette:"); + uint32_t l = *(uint32_t *)(fbuf_info + 1); + struct fbuf_palette_entry *palette = (struct fbuf_palette_entry *)((uint32_t *)(fbuf_info + 1) + 1); + for (uint32_t i = 0; i < l; ++i) { + put_sz("\n #"); + put_8_hex(palette[i].red); + put_8_hex(palette[i].green); + put_8_hex(palette[i].blue); + } + break; + case RGB: + put_sz("b\n RGB:"); + //TODO + break; + case TEXT: + put_sz("b\n Text mode"); + break; + default: + put_sz("b\n Unknown mode 0x"); + put_8_hex(fbuf_info->color_type); + } + break; + } + + case IMAGE_BASE_ADDR: + put_sz(": image address\n 0x"); + put_32_hex(*(uint32_t *)(tag_pointer + 1)); + break; + default: - put_sz(": ignoring\n"); + put_sz(": ignoring"); } tag_pointer = (struct tag_start *)(((uint32_t)tag_pointer + tag_pointer->size - 1 & 0xfffffff8) + 8); @@ -214,13 +326,17 @@ uint32_t main(void) { if (!have_mmap) return NO_MMAP; - put_sz("\nReady!\n Memory map size: 0x"); + put_sz("\n\nReady!\n Memory map size: 0x"); put_32_hex(sizeof(struct mmap_entry) * MMAP_SIZE); put_sz("\n Process table size: 0x"); put_32_hex(sizeof(struct proc_info) * 65536); put_sz("\n File table size: 0x"); put_32_hex(sizeof(struct file_info) * 65536); - put_char('\n'); + put_sz("\n\n"); + + put_sz("No file support yet. Halting."); + while (1) + asm ("hlt"); uint8_t rc_buffer[4096]; diff --git a/src/kernel/vga.c b/src/kernel/vga.c index 5fd8a46..cf95bc2 100644 --- a/src/kernel/vga.c +++ b/src/kernel/vga.c @@ -21,10 +21,11 @@ OF THIS SOFTWARE. #include "serial.h" #include <stdbool.h> -uint16_t cursor_pos = 0; -uint8_t color = 0x70; +#define VGA_BUFFER ((uint8_t *)0x000b8000) #define cols 80 #define rows 25 +uint16_t cursor_pos = 0; +uint8_t color = 0x70; void clear(void) { uint32_t fill = 0x00200020 | (color << 24) | (color << 8); @@ -82,6 +83,46 @@ void put_32_hex(uint32_t n) { } } +void put_16_hex(uint16_t n) { + for (uint8_t i = 0; i < 4; ++i) { + put_char("0123456789abcdef"[n >> 12]); + n <<= 4; + } +} + +void put_8_hex(uint8_t n) { + put_char("0123456789abcdef"[n >> 4]); + put_char("0123456789abcdef"[n & 0x0f]); +} + +void put_32_dec(uint32_t n) { + if (n) { + bool sig = false; + for (uint32_t m = 1000000000; m; m /= 10) { + if (((n / m) % 10) || sig) { + sig = true; + put_char((uint8_t)'0' + (n / m) % 10); + } + } + } + else + put_char('0'); +} + +void put_8_dec(uint8_t n) { + if (n) { + bool sig = false; + for (uint8_t m = 100; m; m /= 10) { + if (((n / m) % 10) || sig) { + sig = true; + put_char((uint8_t)'0' + (n / m) % 10); + } + } + } + else + put_char('0'); +} + void move_cursor(uint8_t col, uint8_t row) { cursor_pos = (col + row * cols) * 2; } diff --git a/src/kernel/vga.h b/src/kernel/vga.h index 2504128..cb2c2e3 100644 --- a/src/kernel/vga.h +++ b/src/kernel/vga.h @@ -22,11 +22,14 @@ OF THIS SOFTWARE. #ifndef VGA_H #define VGA_H -#define VGA_BUFFER ((uint8_t *)0x000b8000) void clear(void); void put_char(uint8_t ch); void put_sz(uint8_t *s); void put_32_hex(uint32_t n); +void put_16_hex(uint16_t n); +void put_8_hex(uint8_t n); +void put_32_dec(uint32_t n); +void put_8_dec(uint8_t n); void move_cursor(uint8_t col, uint8_t row); void set_color(uint8_t c); |