diff options
author | Benji Dial <benji3.141@gmail.com> | 2019-12-14 18:31:34 -0500 |
---|---|---|
committer | Benji Dial <benji3.141@gmail.com> | 2019-12-14 18:31:34 -0500 |
commit | cdc7b2ae532fd3a93e13784812f7501f2fd5c07a (patch) | |
tree | 9ea27c32a7f3dc0acc62b421b139d3e8a1dd1cb6 /src | |
parent | aeff38fe153addba50b40600166acd42e7885e99 (diff) | |
download | portland-os-cdc7b2ae532fd3a93e13784812f7501f2fd5c07a.tar.gz |
more of bootloader, tiny kernel stub
Diffstat (limited to 'src')
-rw-r--r-- | src/bootloader.asm | 213 | ||||
-rw-r--r-- | src/kernel/main.c | 26 | ||||
-rw-r--r-- | src/kernel/vga.c | 71 | ||||
-rw-r--r-- | src/kernel/vga.h | 31 |
4 files changed, 293 insertions, 48 deletions
diff --git a/src/bootloader.asm b/src/bootloader.asm index e8ab91b..08d1daf 100644 --- a/src/bootloader.asm +++ b/src/bootloader.asm @@ -17,20 +17,22 @@ pointers: .fat equ 0x0500 +.root_dir equ 0x0504 +.kernel equ 0x0508 fat_header: .oem_name equ 0x7c03;mkfs.fat - ignored .bytes_per_sector equ 0x7c0b;0x0200 - assumed .sectors_per_cluster equ 0x7c0d;0x01 - assumed -.reserved_sectors equ 0x7c0e;0x0002 - other values handled +.reserved_sectors equ 0x7c0e;0x0004 - other values handled .n_fats equ 0x7c10;0x01 - assumed -.directory_entries equ 0x7c11; - +.root_dir_entries equ 0x7c11; - .n_sectors equ 0x7c13;0x0b40 - .media_type equ 0x7c15; - .sectors_per_fat equ 0x7c16; - handled .sectors_per_track equ 0x7c18;0x0012 - .sides equ 0x7c1a;0x0002 - -.hidden_sectors equ 0x7c1c;0x0000_0000 - assumed +.hidden_sectors equ 0x7c1c;0x0000_0000 - assumed, top half used as scratch for sector number of cluster 0 .long_sectors equ 0x7c20;0x0000_0000 - assumed .drive_number equ 0x7c24; - ignored, used as scratch .flags equ 0x7c25; - ignored @@ -148,13 +150,165 @@ memory: jne halt mov ax, word [fat_header.sectors_per_fat] + xor ecx, ecx + mov cx, word [fat_header.reserved_sectors] + + call allocate_and_load + + mov dword [pointers.fat], ebx + + mov ax, word [fat_header.root_dir_entries] + dec ax + shr ax, 4 + inc ax + + xor ecx, ecx + mov cx, word [fat_header.reserved_sectors] + add cx, word [fat_header.sectors_per_fat] + jnc .no_carry + or ecx, 0x0001_0000 +.no_carry: + + call allocate_and_load + + mov dword [pointers.root_dir], ebx + + xor edx, edx + mov dx, word [fat_header.root_dir_entries] + shl edx, 5 + add edx, ebx + +find_kernel: + mov eax, 0x6e_72_65_6b;kern + mov ecx, 0x20_20_6c_65;el + mov ebx, dword [pointers.root_dir] + +.loop: + test dword [ebx], eax + jne .next + test dword [ebx + 4], ecx + jne .next + test word [ebx + 8], 0x79_73;sy + jne .next + test byte [ebx + 10], 0x73;s + je .found + +.next: + add ebx, 32 + test ebx, edx + jne .loop + jmp halt + +.found: + mov byte [allocate_and_load.load], 0xc3;ret + + mov eax, dword [ebx + 0x1c] + dec eax + shr eax, 9 + inc eax + + test eax, 0xffff_0000 + jnz halt + + push word [ebx + 0x1a] + + call allocate_and_load + + mov dword [pointers.kernel], ebx + + mov ax, word [fat_header.root_dir_entries] + dec ax + shr ax, 4 + dec ax + add ax, word [fat_header.reserved_sectors] + jc halt + add ax, word [fat_header.sectors_per_fat] + jc halt + mov word [fat_header.hidden_sectors + 2], ax + +load_kernel: + mov word [dap.length], 0x0001 + mov word [dap.offset], bx + xor bx, bx + shr ebx, 4 + test ebx, 0xffff_0000 + jnz halt + mov word [dap.segment], bx + + xor edx, edx + pop dx + mov word [dap.start + 2], 0x0000 + mov ah, 0x42 + mov si, dap +.loop: + mov cx, dx + add cx, word [fat_header.hidden_sectors + 2] + jc halt + + mov word [dap.start], cx + + int 0x13 + + mov ebx, dword [pointers.fat] + add ebx, edx + add ebx, edx + add ebx, edx + + xor edx, edx + mov dx, word [ebx + 1] + shl edx, 8 + mov dl, byte [ebx] + + add word [dap.segment], 0x0020 + jc halt + + mov ecx, edx + and ecx, 0x0ff8 + test ecx, 0x0ff8 + jne .loop + + mov ebx, dword [pointers.kernel] + + ;Parse kernel executable header, + ;Go through relocation tables, + ;Get kernel_start. + + cli + + lgdt [gdt] + mov eax, cr0 + or al, 0x01 + mov cr0, eax + jmp 0x08:kernel_start;get start from file header + +gdt: +dw 0x28 +dd gdt + 6 +dq 0x0000_0000_0000_0000 +dq 0x0040_9a00_0000_7fff;0x000000 - 0x007fff +dq 0x0040_9200_0000_7fff +dq 0x00c0_9a00_8000_0ff7;0x008000 - 0xffffff +dq 0x00c0_9200_8000_0ff7 + +dap: +dw 0x0010 +.length dw 0x0003 +.offset dw 0x7e00 +.segment dw 0x0000 +.start dd 0x0000_0001 +.start_h dd 0x0000_0000 + +;ecx = sector +;ax = sector count +;bx out = address of start +allocate_and_load: mov word [dap.length], ax + mov dword [dap.start], ecx dec ax shr ax, 3 inc ax -fat_allocate: mov bx, 0x200e xor cx, cx mov dx, 0x2200 @@ -189,50 +343,17 @@ fat_allocate: and ebx, 0x0000_dfff shl ebx, 12 - mov dword [pointers.fat], ebx - - mov dl, byte [fat_header.drive_number] - mov ax, word [fat_header.reserved_sectors] - mov word [dap.start], ax - mov word [dap.offset], bx - shr ebx, 16 - and bx, 0xf000 - mov word [dap.segment], bx +.load: + mov eax, ebx + mov word [dap.offset], ax + shr eax, 4 + and ax, 0xf000 + mov word [dap.segment], ax mov ah, 0x42 mov si, dap - int 0x15 - - mov ebx, dword [pointers.fat] - - ;fat loaded - load kernel - - cli - - lgdt [gdt] - mov eax, cr0 - or al, 0x01 - mov cr0, eax - jmp 0x08:pmode - -gdt: -dw 0x28 -dd gdt + 6 -dq 0x0000_0000_0000_0000 -dq 0x0040_9a00_0000_7fff;0x000000 - 0x007fff -dq 0x0040_9200_0000_7fff -dq 0x00c0_9a00_8000_0ff7;0x008000 - 0xffffff -dq 0x00c0_9200_8000_0ff7 - -dap: -dw 0x0010 -.length dw 0x0001 -.offset dw 0x7e00 -.segment dw 0x0000 -.start dq 1 + int 0x13 -allocate: - ;TODO ret halt: @@ -240,7 +361,3 @@ halt: .hlt: hlt jmp .hlt - -bits 32 -pmode: - diff --git a/src/kernel/main.c b/src/kernel/main.c new file mode 100644 index 0000000..079779c --- /dev/null +++ b/src/kernel/main.c @@ -0,0 +1,26 @@ +/* +Copyright 2019 Benji Dial + +Permission to use, copy, modify, and/or distribute this +software for any purpose with or without fee is hereby +granted, provided that the above copyright notice and this +permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS +ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +OF THIS SOFTWARE. +*/ + +#include "vga.h" + +void main(void) { + put_sz("Welcome to Portland version 0.0.8!\n"); + while (1) + put_sz("|\b/\b-\b\\\b"); +} diff --git a/src/kernel/vga.c b/src/kernel/vga.c new file mode 100644 index 0000000..046dda7 --- /dev/null +++ b/src/kernel/vga.c @@ -0,0 +1,71 @@ +/* +Copyright 2019 Benji Dial + +Permission to use, copy, modify, and/or distribute this +software for any purpose with or without fee is hereby +granted, provided that the above copyright notice and this +permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS +ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +OF THIS SOFTWARE. +*/ + +#include "vga.h" + +uint16_t cursor_pos = 0; +uint8_t color = 0xf0; +#define cols 80 +#define rows 25 + +void scroll(void) { + cursor_pos -= cols * 2; + uint32_t *limit = (uint32_t *)(VGA_BUFFER + cols * (rows - 1)); + for (uint32_t *i = (uint32_t *)VGA_BUFFER; i < limit; ++i) + *i = *(i + cols / 2); + limit += cols / 2; + uint32_t fill = (color * 0x0100 + (uint8_t)' ') * 0x00010001; + for (uint32_t *i = limit - cols / 2; i < limit; ++i) + *i = fill; +} + +void put_char(uint8_t ch) { + switch (ch) { + case '\b': + if (cursor_pos) + VGA_BUFFER[cursor_pos -= 2] = (uint8_t)' '; + break; + case '\t': + while ((cursor_pos % (cols * 2)) % 20) + put_char(' '); + break; + case '\n': + if ((cursor_pos = (cursor_pos / (cols * 2) + 1) * (cols * 2)) >= cols * rows * 2) + scroll(); + break; + default: + VGA_BUFFER[cursor_pos++] = ch; + VGA_BUFFER[cursor_pos++] = color; + if (cursor_pos == (cols * rows * 2)) + scroll(); + } +} + +void put_sz(uint8_t *sz) { + while (*sz) + put_char(*(sz++)); +} + +void move_cursor(uint8_t col, uint8_t row) { + cursor_pos = (col + row * cols) * 2; +} + +void set_color(uint8_t c) { + color = c; +} diff --git a/src/kernel/vga.h b/src/kernel/vga.h new file mode 100644 index 0000000..74a5d04 --- /dev/null +++ b/src/kernel/vga.h @@ -0,0 +1,31 @@ +/* +Copyright 2019 Benji Dial + +Permission to use, copy, modify, and/or distribute this +software for any purpose with or without fee is hereby +granted, provided that the above copyright notice and this +permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS +ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +OF THIS SOFTWARE. +*/ + +#include <stdint.h> + +#ifndef VGA_H +#define VGA_H + +#define VGA_BUFFER ((uint8_t *)0x000b8000) +void put_char(uint8_t ch); +void put_sz(uint8_t *s); +void move_cursor(uint8_t col, uint8_t row); +void set_color(uint8_t c); + +#endif
\ No newline at end of file |