forked from PoliEcho-holding-org/kern
MAJOR REWRITE
- Kernel got pretty much deleted, will be rewriting in following days - Bootloader got rewritten, stage1 works, stage2 will be written in following days - Libc is still the same - User will contains userspace stuff - Rewrote makefiles again - Got rid of backup (see previous commits for that) - Image has 1 MBR partition for FAT32 which contains 'kern.bin' file - Remade info files to be more "big project" style (all caps plain text) - Added some dumb docs
This commit is contained in:
-133
@@ -1,133 +0,0 @@
|
||||
; KBOOT - Kern Bootloader
|
||||
; Most of the code is taken from Limine (https://github.com/limine-bootloader/limine)
|
||||
; I tried to add more documentation than the Limine code had, but it's not everything
|
||||
; Any of my code is pretty bad, so i recommend using an existing bootloader
|
||||
|
||||
[org 0x7c00]
|
||||
[bits 16]
|
||||
|
||||
start:
|
||||
jmp .bpb_end
|
||||
|
||||
; Some BIOSes will override the FAT BPB area,
|
||||
; so we just fill it out to avoid pottentially
|
||||
; overriding bootloader code.
|
||||
; Source: https://github.com/limine-bootloader/limine/blob/trunk/stage1/hdd/bootsect.asm
|
||||
.bpb:
|
||||
times 3-($-$$) db 0
|
||||
.bpb_oem_id: db "KBOOT "
|
||||
.bpb_sector_size dw 512
|
||||
.bpb_sects_per_clust: db 0
|
||||
.bpb_reserved_sects: dw 0
|
||||
.bpb_fat_count: db 0
|
||||
.bpb_root_dir_entries: dw 0
|
||||
.bpb_sector_count: dw 0
|
||||
.bpb_media_type: db 0
|
||||
.bpb_sects_per_fat: dw 0
|
||||
.bpb_sects_per_track: dw 18
|
||||
.bpb_heads_count: dw 2
|
||||
.bpb_hidden_sects: dd 0
|
||||
.bpb_sect_count_big: dd 0
|
||||
.bpb_drive_num: db 0
|
||||
.bpb_reserved: db 0
|
||||
.bpb_signature: db 0
|
||||
.bpb_volume_id: dd 0
|
||||
.bpb_volume_label: db "KBOOT "
|
||||
.bpb_filesystem_type: times 8 db 0
|
||||
.bpb_end:
|
||||
cli
|
||||
cld
|
||||
jmp 0x0000:.init_codeseg ; Long jump to set CS = 0
|
||||
|
||||
; Zero out segment regs (Because segmentation is shit)
|
||||
.init_codeseg:
|
||||
xor si, si ; We cannot change segment regs directly
|
||||
mov ds, si ; Data Segment
|
||||
mov es, si ; Extra Segment
|
||||
mov ss, si ; Stack Segment
|
||||
mov sp, 0x7c00 ; Set Stack Pointer
|
||||
sti
|
||||
|
||||
; We probably won't be booting from a floppy, so
|
||||
; ignore if boot drive is < 0x80 and assume an error
|
||||
cmp dl, 0x80
|
||||
jl err.0
|
||||
; Also anything above 0x8f is "dubious" so we also
|
||||
; just assume an error
|
||||
cmp dl, 0x8f
|
||||
jg err.1
|
||||
|
||||
; Check that int 13h extensions are supported
|
||||
.int13chk:
|
||||
mov ah, 0x41
|
||||
mov bx, 0x55aa ; Expects bx to be this magic value
|
||||
int 0x13 ; Will se CF if unsupported
|
||||
jc err.2
|
||||
cmp bx, 0xaa55 ; Also sets bx to this magic
|
||||
jne err.3
|
||||
|
||||
; Load the stage 2 bootloader code to 0x70000
|
||||
.load_stage2:
|
||||
push 0x7000
|
||||
pop es ; ES = 0x7000
|
||||
xor bx, bx ; ES:BX = 0x70000
|
||||
mov eax, 512
|
||||
xor ebp, ebp
|
||||
mov ecx, 512
|
||||
call read_sectors
|
||||
jc err.4 ; CF was set -> failed to read from disk
|
||||
|
||||
.enable_protected:
|
||||
; Load GDT Pointer
|
||||
lgdt [gdtp]
|
||||
|
||||
; Set PE (Protected mode Enable) flag
|
||||
cli
|
||||
mov eax, cr0
|
||||
or eax, 1 ; Bit 1 - PE
|
||||
mov cr0, eax
|
||||
|
||||
; Far jump to protected mode
|
||||
jmp code_seg:vector
|
||||
|
||||
%include "boot/disk.s" ; Disk I/O helper functions
|
||||
%include "boot/gdt.s" ; Global Descriptor Table
|
||||
|
||||
; Handles an error
|
||||
err:
|
||||
; Error codes
|
||||
.4: inc si ; Failed to read stage2 from disk
|
||||
.3: inc si ; Int 13h extensions unsupported (BX wasn't magic)
|
||||
.2: inc si ; Int 13h extensions unsupported (CF was set)
|
||||
.1: inc si ; Invalid boot drive number (> 0x8f)
|
||||
.0: ; Invalid boot drive number (< 0x80)
|
||||
; Common error handler
|
||||
add si, '0' | (0x4f << 8) ; Store error code number char in SI, white on red
|
||||
push 0xb800 ; VGA Text mode video memory
|
||||
pop es ; ES = 0xb800
|
||||
mov word [es:0], si ; Write character
|
||||
|
||||
; Hang
|
||||
sti
|
||||
.h: hlt
|
||||
jmp .h
|
||||
|
||||
[bits 32]
|
||||
; Protected mode entry vector
|
||||
vector:
|
||||
mov eax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
|
||||
and edx, 0xff
|
||||
|
||||
; Call stage 2 bootloader
|
||||
call 0x70000
|
||||
|
||||
; Padding and boot signature
|
||||
times 510-($-$$) db 0
|
||||
dw 0xaa55
|
||||
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
; Reads sectors from disk
|
||||
; Args:
|
||||
; eax - LBA low 32 bits
|
||||
; ebp - LBA high 32 bits
|
||||
; dl - Drive number
|
||||
; es - Destination segment
|
||||
; bx - Destination offset
|
||||
; ecx - Byte count
|
||||
; Rets:
|
||||
; CF - Set on error
|
||||
read_sectors:
|
||||
pusha
|
||||
|
||||
; Fill out Disk Address Packet
|
||||
mov si, .da_packet
|
||||
mov word [si], 0x10 ; Packet Size and Unused
|
||||
mov word [si+2], 1 ; Sector count
|
||||
mov word [si+4], bx ; Dest. offset
|
||||
mov word [si+6], es ; Dest. segment
|
||||
|
||||
; Store some regs for later
|
||||
push dx
|
||||
push si
|
||||
push eax
|
||||
push ebp
|
||||
|
||||
; Get bytes per sector
|
||||
mov ah, 0x48 ; Extended read drive parameters
|
||||
mov si, .drive_params ; DS:SI - result buffer
|
||||
mov word [si], 0x1e ; Buffer size
|
||||
int 0x13
|
||||
jc .done ; CF set - error; we never pop ebp, eax, si & dx! (could cause issues)
|
||||
mov bp, word [si+24] ; Bytes per sector
|
||||
|
||||
; Convert byte count in ECX to sector count in CX
|
||||
mov ax, cx ; Low word
|
||||
shr ecx, 16 ; Shift high word into low word of ECX (therefore just CX)
|
||||
mov dx, cx ; High word
|
||||
xor cx, cx ; Clear CX
|
||||
div bp ; Divide byte count in ax (low word) by bytes per sector
|
||||
test dx, dx ; DX will contain remainder
|
||||
setnz cl ; (dx != 0) ? cl = 1 : cl = 0
|
||||
add cx, ax ; Add remaining sectors to cx
|
||||
|
||||
pop edx ; Restore pushed EBP to EDX
|
||||
pop eax ; Restore EAX
|
||||
pop si ; Restore SI
|
||||
|
||||
; Calculate destination LBA
|
||||
div ebp ; Divide EAX by EBP
|
||||
mov dword [si+8], eax ; LBA low
|
||||
mov dword [si+12], 0 ; LBA high
|
||||
|
||||
pop dx ; Restore DX
|
||||
|
||||
; Read sectors one by one
|
||||
.loop:
|
||||
mov ah, 0x42 ; Extended read
|
||||
clc ; Clear CF
|
||||
int 0x13
|
||||
jc .done ; Error
|
||||
|
||||
add word [si+4], bp ; Increment destination by sector byte count
|
||||
xor ebx, ebx ; EBX = 0
|
||||
inc dword [si+8] ; Increment LBA low
|
||||
seto bl ; Will set BL to 1 in case of overflow
|
||||
add dword [si+12], ebx ; Increment LBA high
|
||||
|
||||
loop .loop ; dec cx; jnz .loop
|
||||
|
||||
.done:
|
||||
popa
|
||||
ret
|
||||
|
||||
; Disk Address Packet
|
||||
.da_packet: equ 0x8000
|
||||
|
||||
; Drive Parameters from int 13h, ah = 0x48
|
||||
.drive_params: equ 0x8010
|
||||
|
||||
+26
-2
@@ -1,7 +1,31 @@
|
||||
include ../defaults.mk
|
||||
|
||||
BIN = ./bin
|
||||
STAGE1_SRC = ./stage1
|
||||
STAGE2_SRC = ./stage2
|
||||
|
||||
STAGE1_SRCS = $(wildcard $(STAGE1_SRC)/*.s)
|
||||
STAGE2_SRCS = $(wildcard $(STAGE2_SRC)/*.c)
|
||||
STAGE2_OBJS = $(patsubst $(STAGE2_SRC)/%.c, $(BIN)/%.o, $(STAGE2_SRCS))
|
||||
|
||||
LINKER = $(STAGE2_SRC)/linker.ld
|
||||
STAGE1 = stage1.bin
|
||||
STAGE2 = stage2.bin
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all:
|
||||
@echo "TODO: Write this makefile..."
|
||||
all: $(STAGE1) $(STAGE2)
|
||||
|
||||
$(STAGE1): $(STAGE1_SRCS)
|
||||
$(AS) $(ASFLAGS) -fbin -o $@ $(STAGE1_SRC)/bootsect.s
|
||||
|
||||
$(STAGE2): $(STAGE2_OBJS)
|
||||
$(LD) $(LDFLAGS) -T$(LINKER) -o $@ $^
|
||||
|
||||
$(BIN)/%.o: $(STAGE2_SRC)/%.c
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -fr $(BIN) $(STAGE1) $(STAGE2)
|
||||
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
; KBOOT - Kern Bootloader
|
||||
; Most of the code is taken from Limine (https://github.com/limine-bootloader/limine)
|
||||
; I tried to add more documentation than the Limine code had, but it's not everything
|
||||
; Any of my code is pretty bad, so i recommend using an existing bootloader
|
||||
|
||||
[org 0x7c00]
|
||||
[bits 16]
|
||||
|
||||
; BPB Requires these
|
||||
jmp short .bpb_end
|
||||
nop
|
||||
|
||||
; FAT32 Bios Parameter Block
|
||||
.bpb:
|
||||
.bpb_oem_id: db "KERN "
|
||||
.bpb_sector_size: dw 0
|
||||
.bpb_sects_per_clust: db 0
|
||||
.bpb_reserved_sects: dw 0
|
||||
.bpb_fat_count: db 0
|
||||
.bpb_root_dir_entries: dw 0
|
||||
.bpb_sector_count: dw 0
|
||||
.bpb_media_type: db 0
|
||||
.bpb_sects_per_fat: dw 0
|
||||
.bpb_sects_per_track: dw 18
|
||||
.bpb_heads_count: dw 2
|
||||
.bpb_hidden_sects: dd 0
|
||||
.bpb_sect_count_big: dd 0
|
||||
; Extended BPB
|
||||
.bpb_drive_num: db 0
|
||||
.bpb_reserved: db 0
|
||||
.bpb_signature: db 0
|
||||
.bpb_volume_id: dd 0
|
||||
.bpb_volume_label: dd "KERN "
|
||||
.bpb_fs_type: times 8 db 0
|
||||
.bpb_end:
|
||||
cli
|
||||
cld
|
||||
jmp 0x0000:.init_codeseg ; Long jump to set CS = 0
|
||||
|
||||
; Zero out segment regs (Because segmentation is shit)
|
||||
.init_codeseg:
|
||||
xor si, si ; We cannot change segment regs directly
|
||||
mov ds, si ; Data Segment
|
||||
mov es, si ; Extra Segment
|
||||
mov ss, si ; Stack Segment
|
||||
mov sp, 0x7c00 ; Set Stack Pointer
|
||||
sti
|
||||
|
||||
; We probably won't be booting from a floppy, so
|
||||
; ignore if boot drive is < 0x80 and assume an error
|
||||
cmp dl, 0x80
|
||||
jl err.0
|
||||
; Also anything above 0x8f is "dubious" so we also
|
||||
; just assume an error
|
||||
cmp dl, 0x8f
|
||||
jg err.1
|
||||
|
||||
; Check that int 13h extensions are supported
|
||||
.int13chk:
|
||||
mov ah, 0x41
|
||||
mov bx, 0x55aa ; Expects bx to be this magic value
|
||||
int 0x13 ; Will se CF if unsupported
|
||||
jc err.2
|
||||
cmp bx, 0xaa55 ; Also sets bx to this magic
|
||||
jne err.3
|
||||
|
||||
; Load the stage 2 bootloader code to 0x70000
|
||||
.load_stage2:
|
||||
mov eax, 1 ; LBA
|
||||
mov cx, 20 ; Read 20 sectors (we have space for 2048)
|
||||
|
||||
; Destination - 0x70000
|
||||
push 0x7000
|
||||
pop es
|
||||
xor bx, bx
|
||||
|
||||
call read_sectors
|
||||
jc err.4 ; Failed to read stage 2
|
||||
|
||||
.enable_protected:
|
||||
; Load GDT Pointer
|
||||
lgdt [gdtp]
|
||||
|
||||
; Set PE (Protected mode Enable) flag
|
||||
cli
|
||||
mov eax, cr0
|
||||
or eax, 1 ; Bit 1 - PE
|
||||
mov cr0, eax
|
||||
|
||||
; Far jump to protected mode
|
||||
jmp code_seg:vector
|
||||
|
||||
%include "stage1/disk.s" ; Disk I/O helper functions
|
||||
%include "stage1/gdt.s" ; Global Descriptor Table
|
||||
|
||||
; Handles an error
|
||||
err:
|
||||
; Error codes
|
||||
.4: inc si ; Failed to read stage2 from disk
|
||||
.3: inc si ; Int 13h extensions unsupported (BX wasn't magic)
|
||||
.2: inc si ; Int 13h extensions unsupported (CF was set)
|
||||
.1: inc si ; Invalid boot drive number (> 0x8f)
|
||||
.0: ; Invalid boot drive number (< 0x80)
|
||||
; Common error handler
|
||||
add si, '0' | (0x4f << 8) ; Store error code number char in SI, white on red
|
||||
push 0xb800 ; VGA Text mode video memory
|
||||
pop es ; ES = 0xb800
|
||||
mov word [es:0], si ; Write character
|
||||
|
||||
; Hang
|
||||
sti
|
||||
.h: hlt
|
||||
jmp .h
|
||||
|
||||
[bits 32]
|
||||
; Protected mode entry vector
|
||||
vector:
|
||||
mov eax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
|
||||
and edx, 0xff
|
||||
|
||||
; Call stage 2 bootloader
|
||||
call 0x70000
|
||||
|
||||
; Padding and boot signature
|
||||
times 510-($-$$) db 0
|
||||
dw 0xaa55
|
||||
@@ -0,0 +1,26 @@
|
||||
; Reads sectors from disk
|
||||
; eax - LBA
|
||||
; cx - Sector count
|
||||
; dl - Drive number
|
||||
; es:dx - Destination
|
||||
read_sectors:
|
||||
pusha
|
||||
|
||||
; Fill out Disk Address Packet
|
||||
mov si, .da_packet
|
||||
mov word [si], 0x10 ; Packet Size and Unused
|
||||
mov word [si+2], cx ; Sector count
|
||||
mov word [si+4], bx ; Dest. offset
|
||||
mov word [si+6], es ; Dest. segment
|
||||
mov dword [si+8], eax ; LBA
|
||||
|
||||
mov ah, 0x42 ; Extended read
|
||||
clc ; Clear CF
|
||||
int 0x13
|
||||
.done:
|
||||
popa
|
||||
ret
|
||||
|
||||
; Disk Address Packet
|
||||
.da_packet: equ 0x8000
|
||||
|
||||
@@ -26,4 +26,3 @@ gdtp:
|
||||
; Segments
|
||||
code_seg equ gdt.code_desc - gdt
|
||||
data_seg equ gdt.data_desc - gdt
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
void entry() {
|
||||
while (1);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
OUTPUT_FORMAT(binary)
|
||||
ENTRY(entry)
|
||||
|
||||
SECTIONS {
|
||||
/* Will be loaded at 0x70000 */
|
||||
. = 0x70000;
|
||||
|
||||
.text : {
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
}
|
||||
|
||||
.data : {
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
}
|
||||
|
||||
.bss : {
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
}
|
||||
|
||||
_end = .;
|
||||
}
|
||||
Reference in New Issue
Block a user