more of bootloader, tiny kernel stub
This commit is contained in:
parent
aeff38fe15
commit
cdc7b2ae53
7 changed files with 313 additions and 51 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
obj/
|
||||
out/
|
|
@ -1,7 +1,9 @@
|
|||
0x0000 - 0x03ff : interrupt vector table
|
||||
0x0400 - 0x04ff : bios data area
|
||||
0x0500 - 0x05ff : structure pointers
|
||||
0x00 dword : fat pointer
|
||||
0x00 : fat
|
||||
0x04 : root directory
|
||||
0x08 : kernel
|
||||
0x0600 - 0x1fff : not assigned
|
||||
0x2000 - 0x3fff : memory map
|
||||
for each word : 1 page
|
||||
|
|
17
makefile
17
makefile
|
@ -1,10 +1,23 @@
|
|||
floppy: out bootloader
|
||||
mkfs.fat -C -f 1 -F 12 -n "PORTLAND OS" -R 2 -S 512 out/floppy.img 1440
|
||||
floppy: out bootloader files
|
||||
mkfs.fat -C -f 1 -F 12 -n "PORTLAND OS" -R 4 -S 512 out/floppy.img 1440
|
||||
mkdir out/floppy_mount
|
||||
mount out/floppy.img out/floppy_mount
|
||||
cp out/fs/* out/floppy_mount/
|
||||
umount out/floppy_mount
|
||||
dd if=obj/bootloader.bin of=out/floppy.img bs=1 seek=62 conv=notrunc
|
||||
|
||||
bootloader: obj
|
||||
nasm src/bootloader.bin -o obj/bootloader.bin
|
||||
|
||||
kernel: obj out
|
||||
gcc -c src/kernel/main.c -o obj/kmain.o -ffreestanding
|
||||
gcc -c src/kernel/vga.c -o obj/kvga.o -ffreestanding
|
||||
ld obj/kmain.o obj/kvga.o -o out/kernel.out -nostdlib --oformat=i386-aout
|
||||
|
||||
files: kernel
|
||||
mkdir out/fs
|
||||
cp out/kernel.out out/fs/kernel.sys
|
||||
|
||||
obj:
|
||||
mkdir -p obj
|
||||
|
||||
|
|
|
@ -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
|
||||
int 0x13
|
||||
|
||||
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
|
||||
|
||||
allocate:
|
||||
;TODO
|
||||
ret
|
||||
|
||||
halt:
|
||||
|
@ -240,7 +361,3 @@ halt:
|
|||
.hlt:
|
||||
hlt
|
||||
jmp .hlt
|
||||
|
||||
bits 32
|
||||
pmode:
|
||||
|
||||
|
|
26
src/kernel/main.c
Normal file
26
src/kernel/main.c
Normal file
|
@ -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");
|
||||
}
|
71
src/kernel/vga.c
Normal file
71
src/kernel/vga.c
Normal file
|
@ -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;
|
||||
}
|
31
src/kernel/vga.h
Normal file
31
src/kernel/vga.h
Normal file
|
@ -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
|
Reference in a new issue