Merge pull request #3 from Nivirx/bss-setup

convert MBR, VBR, & Stage2 to use a BSS section.
This commit was merged in pull request #3.
This commit is contained in:
2024-10-13 18:05:19 -04:00
committed by GitHub
15 changed files with 456 additions and 271 deletions

View File

@@ -25,6 +25,7 @@ stage2: $(stage2_binary_files)
boottest: $(boottest_binary_files) boottest: $(boottest_binary_files)
clean: clean:
@rm -rvf *.map
@rm -rvf $(build_dir)/* @rm -rvf $(build_dir)/*
@rm -rvf $(iso) @rm -rvf $(iso)
@rm -rvf $(isoz) @rm -rvf $(isoz)

View File

@@ -48,7 +48,8 @@ GetMemoryMap:
mov eax, 0xE820 ; select 0xE820 function mov eax, 0xE820 ; select 0xE820 function
xor ebx, ebx ; Continuation value, 0 for the first call xor ebx, ebx ; Continuation value, 0 for the first call
mov dx, (BIOSMemoryMap >> 4) lea dx, [BIOSMemoryMap]
shr dx, 4
mov es, dx mov es, dx
xor di, di ; (BIOSMemoryMap >> 4):0 makes di an index into BIOSMemoryMap xor di, di ; (BIOSMemoryMap >> 4):0 makes di an index into BIOSMemoryMap

View File

@@ -36,6 +36,29 @@ struc LBAPkt_t
.lower_lba resd 1 .lower_lba resd 1
.upper_lba resd 1 .upper_lba resd 1
endstruc endstruc
; call_read_disk_raw <word segment> <word offset> <dword lba> <word count> <word drive_num>
%macro call_read_disk_raw 5
movzx ax, %5
push ax ; drive_num
movzx ax, %4
push ax ; count
movzx dword eax, %3
push dword eax ; lba
movzx ax, %2
push ax ; offset
movzx ax, %1
push ax ; segment = 0
; uint8_t read_stage2_raw(uint16_t buf_segment, uint16_t buf_offset,
; uint32_t lba,
; uint16_t count, uint16_t drive_num)
call read_disk_raw
add sp, 0xC
%endmacro
; Wrapper for AH=0x42 INT13h (Extended Read) ; Wrapper for AH=0x42 INT13h (Extended Read)
; ;

View File

@@ -21,7 +21,7 @@
%ifndef __INC_STEVIA_CONFIG %ifndef __INC_STEVIA_CONFIG
%define SECTOR_SIZE 512 %define SECTOR_SIZE 512
%define STAGE2_SECTOR_COUNT 0x40 %define STAGE2_SECTOR_COUNT 0x30
; 32 KiB ; 32 KiB
%define MAX_STAGE2_BYTES (SECTOR_SIZE * STAGE2_SECTOR_COUNT) %define MAX_STAGE2_BYTES (SECTOR_SIZE * STAGE2_SECTOR_COUNT)

View File

@@ -18,7 +18,7 @@
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
; SOFTWARE. ; SOFTWARE.
%ifndef __INC_MEM %ifndef __INC_EARLY_MEM
; ## Generic Low mem map (from osdev wiki) ## ; ## Generic Low mem map (from osdev wiki) ##
@@ -43,54 +43,6 @@
; 0x0000000100000000 ??? ??? (whatever exists) RAM -- free for use (PAE/64bit)/More Extended memory ; 0x0000000100000000 ??? ??? (whatever exists) RAM -- free for use (PAE/64bit)/More Extended memory
; ???????????????? ??? ??? Potentially usable for memory mapped PCI devices in modern hardware (but typically not, due to backward compatibility) ; ???????????????? ??? ??? Potentially usable for memory mapped PCI devices in modern hardware (but typically not, due to backward compatibility)
; 0x2700 -> 0x28FF
%define disk_buffer 0x2700
; 0x2900 -> 0x2AFF
%define fat_buffer 0x2900
; 0x2B00 -> 0x2CFF
%define dir_buffer 0x2B00
; copy of partition table, 72 bytes
%define partition_table 0x3000
%define partition_table_SIZE 72
; copy of FAT32 BPB, 33 bytes (+1 to the next value to align to uint16_t)
;0x3048
%define fat32_bpb 0x304A
%define fat32_bpb_SIZE 36
; copy of FAT32 EBPB, 54 bytes
;0x306A
%define fat32_ebpb 0x306E
%define fat32_ebpb_SIZE 54
; FAT32 FSInfo, 512 bytes
;0x30A2
%define fat32_fsinfo 0x30B0
%define fat32_fsinfo_SIZE 512
; some stored state for the fat32 driver
;0x32A2
%define fat32_state 0x34B0
%define fat32_state_SIZE 32
; next free space is 0x32D0
%define fat32_nc_data 0x35D0
%define fat32_nc_data_size 16
; lba_packet for raw_disk_read
%define lba_packet 0x4000
%define BIOSMemoryMap 0x4200
%define SteviaInfo 0x5200
; High memory addresses for loading kernel (for use with unreal mode and 32bit override)
; file load buffer at 16MB
%define HMEM_load_buffer 0x1000000
;PhysicalAddress = Segment * 16 + Offset ;PhysicalAddress = Segment * 16 + Offset
%define SEG_TO_LINEAR(s,o) ((s << 4) + o) %define SEG_TO_LINEAR(s,o) ((s << 4) + o)
@@ -100,17 +52,5 @@
; Seg = (physical - offset) / 16 ; Seg = (physical - offset) / 16
%define LINEAR_TO_SEGMENT(p,o) ((p - o) >> 4) %define LINEAR_TO_SEGMENT(p,o) ((p - o) >> 4)
; create normalized linear addres from seg:off (16:4)
; Segement = linear >> 4 (top 16 bits)
; offset = linear & 0x0F (low 4 bits)
; 20 bytes, passed to loaded kernel
struc SteviaInfoStruct_t
.MemoryMapPtr resd 1
.MemoryMapEntries resd 1
.BPBDataPtr resd 1
.EBPBDataPtr resd 1
endstruc
%endif %endif
%define __INC_MEM %define __INC_EARLY_MEM

View File

@@ -21,10 +21,10 @@
%ifndef __INC_ENTRY %ifndef __INC_ENTRY
; 8KiB from 0x2500 -> 0x500 ; 8KiB from 0x2500 -> 0x500
%define EARLY_STACK_START 0x2500 %define EARLY_STACK_START 0xFFFF
%define MBR_ENTRY 0x7A00 %define MBR_ENTRY 0x0600
%define VBR_ENTRY 0x7C00 %define VBR_ENTRY 0x7C00
%define STAGE2_ENTRY 0x7E00 %define STAGE2_ENTRY 0x0500
%endif %endif
%define __INC_ENTRY %define __INC_ENTRY

View File

@@ -28,7 +28,7 @@ ALIGN 4, db 0x90
InitFATDriver: InitFATDriver:
__CDECL16_ENTRY __CDECL16_ENTRY
.func: .func:
mov ax, fat32_state_SIZE mov ax, FAT32_State_t_size
push ax ; length of fat32_state structure push ax ; length of fat32_state structure
xor ax, ax xor ax, ax
push ax ; init fat32_state with zero push ax ; init fat32_state with zero

View File

@@ -63,6 +63,7 @@
; resulting in a value which does not fit in the Number of Sectors entry at 0x13. ; resulting in a value which does not fit in the Number of Sectors entry at 0x13.
struc FAT32_bpb_t struc FAT32_bpb_t
.reserved_init resb 3
.ident_8 resb 8 .ident_8 resb 8
.bytes_per_sector_16 resb 2 .bytes_per_sector_16 resb 2
.sectors_per_cluster_8 resb 1 .sectors_per_cluster_8 resb 1

View File

@@ -34,15 +34,15 @@ struc PartEntry_t
.chs_start resb 3 .chs_start resb 3
.part_type resb 1 .part_type resb 1
.chs_end resb 3 .chs_end resb 3
.lba_start resb 4 .lba_start resd 1
.lba_length resb 4 .lba_length resd 1
endstruc endstruc
struc PartTable_t struc PartTable_t
.partition1 resb 16 .partition1 resb PartEntry_t_size
.partition2 resb 16 .partition2 resb PartEntry_t_size
.partition3 resb 16 .partition3 resb PartEntry_t_size
.partition4 resb 16 .partition4 resb PartEntry_t_size
endstruc endstruc
%endif %endif

View File

@@ -22,9 +22,7 @@
%macro ERROR 1 %macro ERROR 1
mov al, %1 ; al = 1 byte error code mapped to ascii values mov al, %1 ; al = 1 byte error code mapped to ascii values
db 0xEA ; jmp far imm16:imm16 jmp error
dw error ; error_far_seg
dw 0x0000 ; error_far_ptr
%endmacro %endmacro
; pass error as ascii character in al, errors a-zA-Z or 0-9 ; pass error as ascii character in al, errors a-zA-Z or 0-9

View File

@@ -0,0 +1,53 @@
; Copyright (c) 2024 Elaina Claus
;
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included in all
; copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
; SOFTWARE.
%ifndef __INC_KMEMCPY5_FUNC
%include 'cdecl16.inc'
; uint8_t* kmemset(word dest_segment, word dest, word src_segment, word src, byte len);
; not overlap safe, only for
ALIGN 4, db 0x90
kmemcpy5:
__CDECL16_ENTRY
push ds
push es
.setup_segments:
mov ax, [bp + 4]
mov ds, ax ; destination segment
mov ax, [ bp + 8]
mov es, ax ; source segment
.func:
mov cx, [bp + 12] ; len
mov si, [bp + 10] ; src
mov di, [bp + 6] ; dest
cld ; ensure we are incrementing
rep movsb ; move ds:si -> es:di
mov ax, di ; return pointer to dest
.restore_segments:
pop es
pop ds
.endf:
__CDECL16_EXIT
ret
%define __INC_KMEMCPY5_FUNC
%endif

View File

@@ -0,0 +1,47 @@
; Copyright (c) 2024 Elaina Claus
;
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included in all
; copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
; SOFTWARE.
%ifndef __INC_KMEMSET4_FUNC
%include 'cdecl16.inc'
; word kmemset_byte(word segment, word dst, byte val, word len);
ALIGN 4, db 0x90
kmemset4:
__CDECL16_ENTRY
.setup_segment:
push es
mov ax, [bp + 4]
mov es, ax
.func:
mov cx, [bp + 10] ; size_t len
mov al, [bp + 8] ; uint8_t val
mov di, [bp + 6] ; word dst
cld
rep stosb ; move al -> es:di
mov ax, di ; return pointer to dest
.restore_segments:
pop es
.endf:
__CDECL16_EXIT
ret
%endif
%define __INC_KMEMSET4_FUNC

View File

@@ -19,46 +19,51 @@
; SOFTWARE. ; SOFTWARE.
[BITS 16] [BITS 16]
[ORG 0x7A00] [ORG 0x0600]
[CPU KATMAI] [CPU KATMAI]
[WARNING -reloc-abs-byte] [WARNING -reloc-abs-byte]
[WARNING -reloc-abs-word] ; Yes, we use absolute addresses. surpress these warnings. [WARNING -reloc-abs-word] ; Yes, we use absolute addresses. surpress these warnings.
[map all mbr.map] [map all mbr.map]
%define __STEVIA_MBR %define __STEVIA_MBR
jmp short (init - $$) jmp short (init - $$)
nop nop
; ############### ; ###############
;
; Headers/Includes/Definitions ; Headers/Includes/Definitions
;
; ############### ; ###############
%include "util/bochs_magic.inc" %include "util/bochs_magic.inc"
%include "cdecl16.inc" %include "cdecl16.inc"
%include "entry.inc" %include "entry.inc"
%include "config.inc" %include "config.inc"
%include "mem.inc"
%include "error_codes.inc" %include "error_codes.inc"
%include "partition_table.inc" %include "partition_table.inc"
%include "fat32/fat32_structures.inc"
; ############### ALIGN 4
; End Section
; ###############
ALIGN 4, db 0x90
init: init:
cli ; We do not want to be interrupted cli ; We do not want to be interrupted
xor ax, ax
mov ds, ax ; Set segment registers to 0x0000
mov es, ax
mov fs, ax
mov gs, ax
xor ax, ax ; 0 AX ;
mov ds, ax ; Set segment registers to 0 ; Zero BSS section
mov cx, (end_bss - begin_bss) ; count = bss length
mov ax, begin_bss
mov di, ax ; es:di is dest
xor ax, ax
cld
rep stosb ; zero bss section
mov ss, ax ; Set Stack Segment to 0 mov ss, ax ; Set Stack Segment to 0
mov sp, EARLY_STACK_START ; Setup stack mov sp, stack_top ; Setup stack
mov bp, sp ; base ptr = stack ptr mov bp, sp ; base ptr = stack ptr
sub sp, 0x20 ; local varible space sub sp, 0x10 ; local varible space
xor cx, cx
mov ch, 0x01 ; 256 WORDs in MBR (512 bytes), 0x0100 in cx mov ch, 0x01 ; 256 WORDs in MBR (512 bytes), 0x0100 in cx
mov si, 0x7C00 ; Current MBR Address (loaded here by BIOS) mov si, 0x7C00 ; Current MBR Address (loaded here by BIOS)
mov di, MBR_ENTRY ; New MBR Address (our new relocation address) mov di, MBR_ENTRY ; New MBR Address (our new relocation address)
@@ -69,23 +74,15 @@ init:
jmp 0:main jmp 0:main
; ############### ; ###############
;
; Extra/Shared Functions ; Extra/Shared Functions
;
; ############### ; ###############
%include "util/kmem_func.nasm" %include "util/kmem_func.nasm"
%include "util/error_func.nasm" %include "util/error_func.nasm"
; ###############
; End Section
; ###############
; ;
; bp - 2 : uint8_t boot_drive ; bp - 2 : uint8_t boot_drive
; bp - 4 : uint16_t part_offset ; bp - 4 : uint16_t part_offset
;
ALIGN 4, db 0x90 ALIGN 4, db 0x90
main: main:
mov byte [bp - 2], dl ; BIOS passes drive number in DL mov byte [bp - 2], dl ; BIOS passes drive number in DL
@@ -130,12 +127,11 @@ main:
mov dword eax, dword [bx + PartEntry_t.lba_start] mov dword eax, dword [bx + PartEntry_t.lba_start]
push dword eax ; lba push dword eax ; lba
xor ax, ax
push ax ; offset = 0
mov ax, VBR_ENTRY mov ax, VBR_ENTRY
shr ax, 4 push ax ; offset = 0x7c00
push ax ; segment = 7C0
xor ax, ax
push ax ; segment = 0
; uint8_t read_stage2_raw(uint16_t buf_segment, uint16_t buf_offset, ; uint8_t read_stage2_raw(uint16_t buf_segment, uint16_t buf_offset,
; uint32_t lba, ; uint32_t lba,
@@ -147,18 +143,19 @@ main:
je main.sig_ok je main.sig_ok
ERROR MBR_ERROR_NO_VBR_SIG ; no signature present ERROR MBR_ERROR_NO_VBR_SIG ; no signature present
.sig_ok: .sig_ok:
mov ax, partition_table_SIZE ; 72 bytes of data mov ax, PartTable_t_size
push ax push ax
mov ax, DiskSig ; start of partition table mov ax, DiskSig ; start of partition table
push ax push ax
mov ax, partition_table ; defined in memory.inc mov ax, partition_table
push ax push ax
call kmemcpy ; copy partition table to memory call kmemcpy ; copy partition table to bss
add sp, 0x6 add sp, 0x6
mov si, word [bp - 4] mov si, word [bp - 4]
mov dl, byte [bp - 2] mov dl, byte [bp - 2]
jmp 0:0x7C00 mov bx, partition_table
jmp word 0x0000:0x7C00
; ############### ; ###############
; ;
@@ -168,10 +165,6 @@ main:
%include 'BIOS/func/ext_read.nasm' %include 'BIOS/func/ext_read.nasm'
; ###############
; End Section
; ###############
%assign bytes_remaining (440 - ($ - $$)) %assign bytes_remaining (440 - ($ - $$))
%warning MBR has bytes_remaining bytes remaining for code (MAX: 440 bytes) %warning MBR has bytes_remaining bytes remaining for code (MAX: 440 bytes)
times ((512 - 72) - ($ - $$)) nop ; Fill the rest of sector with nop times ((512 - 72) - ($ - $$)) nop ; Fill the rest of sector with nop
@@ -193,3 +186,26 @@ PartEntry4:
times 16 db 0x00 times 16 db 0x00
BootSig: BootSig:
dw 0xAA55 ; Add boot signature at the end of bootloader dw 0xAA55 ; Add boot signature at the end of bootloader
; this should mark the 512 byte mark...if not, something has gone wrong.
section .bss follows=.text
begin_bss:
align 16, resb 1
partition_table resb PartTable_t_size
align 16, resb 1
fat32_bpb resb FAT32_bpb_t_size
fat32_ebpb resb FAT32_ebpb_t_size
align 16, resb 1
fat32_nc_data resb 16
align 16, resb 1
lba_packet resb LBAPkt_t_size
align 512, resb 1
stack_bottom resb 1024 ; 1Kib stack early on
stack_top:
mbr_redzone resb 32
end_bss:

View File

@@ -19,27 +19,24 @@
; SOFTWARE. ; SOFTWARE.
[BITS 16] [BITS 16]
[ORG 0X7E00] [ORG 0x0500] ; IF YOU CHANGE ORG CHANGE THE SIGN OFFSET AT THE END
[CPU KATMAI] [CPU KATMAI]
[map all stage2.map] [map all stage2.map]
[WARNING -reloc-abs-byte] [WARNING -reloc-abs-byte]
[WARNING -reloc-abs-word] [WARNING -reloc-abs-word]
[WARNING -reloc-abs-dword] ; Yes, we use absolute addresses. surpress these warnings. [WARNING -reloc-abs-dword] ; Yes, we use absolute addresses. surpress these warnings.
%define __STEVIA_STAGE2 %define __STEVIA_STAGE2
%define __STAGE2_SEGMENT 0x0000
; ############### ; ###############
;
; Headers/Includes/Definitions ; Headers/Includes/Definitions
;
; ############### ; ###############
%include "util/bochs_magic.inc" %include "util/bochs_magic.inc"
%include "cdecl16.inc" %include "cdecl16.inc"
%include "entry.inc" %include "entry.inc"
%include "config.inc" %include "config.inc"
%include "mem.inc" %include "early_mem.inc"
%include "error_codes.inc" %include "error_codes.inc"
%macro print_string 1 %macro print_string 1
@@ -50,57 +47,130 @@
%endmacro %endmacro
section .text section .text
org 0x7E00 org 0x0500
begin_text: begin_text:
jmp short (init - $$) jmp short (init - $$)
nop nop
; dl = byte boot_drive
; si = word part_offset (active partition offset)
; bx = ptr PartTable_t partition_table
; dx = ptr FAT32_bpb_t fat32_bpb
ALIGN 4, db 0x90 ALIGN 4, db 0x90
init: init:
cli ; We do not want to be interrupted cli ; We do not want to be interrupted
xor ax, ax ; 0 AX ;
mov ds, ax ; Set segment registers to 0 ; Zero BSS section
;
mov cx, (end_bss - begin_bss) ; count = bss length
mov ax, begin_bss
shr ax, 4
mov es, ax ; es = begining of bss section
xor ax, ax
mov di, ax ; dst = 0
cld
rep stosb ; zero bss section
; done zeroing BSS
mov ax, __STAGE2_SEGMENT ; set all our segments to the configured segment
mov ds, ax ; *
mov es, ax ; * mov es, ax ; *
mov fs, ax ; * mov fs, ax ; *
mov gs, ax ; * mov gs, ax ; *
mov ss, ax ; Set Stack Segment to 0 mov ss, ax ; Set Stack Segment to data segment
mov sp, EARLY_STACK_START ; Set Stack Pointer mov sp, stack_top ; Set Stack Pointer
mov bp, sp mov bp, sp
sub sp, 0x20 ; 32 bytes for local varibles sub sp, 0x20 ; 32 bytes for local varibles
sti sti
jmp 0:main jmp word __STAGE2_SEGMENT:main
; ############### ; ###############
; ; Functions
; Extra/Shared Functions
;
; ############### ; ###############
%include "util/kmem_func.nasm" %include "util/kmem_func.nasm"
%include "util/kmemcpy5_func.nasm"
%include "util/kmemset4_func.nasm"
%include "util/error_func.nasm" %include "util/error_func.nasm"
; bp - 2 : uint8_t boot_drive ; ###############
; bp - 4 : uint16_t part_offset ; FAT32 Driver
; ###############
boot_drive_ptr:
dw 0x0000
partition_offset_ptr:
dw 0x0000
%include 'fat32/FAT32_SYS.inc'
; ###############
; BIOS functions
; ###############
%include 'BIOS/BIOS_SYS.inc'
; structures
struc SteviaInfoStruct_t
.MemoryMapPtr resd 1
.MemoryMapEntries resd 1
endstruc
struc EarlyBootStruct_t
.partition_table resb PartTable_t_size
.fat32_bpb resb FAT32_bpb_t_size
.fat32_ebpb resb FAT32_ebpb_t_size
endstruc
; bp - 2 : byte boot_drive
; bp - 4 : word part_offset
; bp - 6 : ptr PartTable_t partition_table
; bp - 8 : ptr FAT32_bpb_t fat32_bpb
ALIGN 4, db 0x90 ALIGN 4, db 0x90
main: main:
lea ax, [bp - 2] lea ax, [bp - 2]
mov [boot_drive_ptr], ax mov [boot_drive_ptr], ax
lea ax, [bp - 4] lea ax, [bp - 4]
mov [partition_offset_ptr], ax ; setup pointers to boot_drive and partition offset on stack mov [partition_offset_ptr], ax ; setup pointers to boot_drive and partition offset on stack
mov byte [bp - 2], dl ; boot_drive (probably 0x80) mov byte [bp - 2], dl ; boot_drive (probably 0x80)
mov word [bp - 4], si ; partition_offset mov word [bp - 4], si ; partition_offset
mov word [bp - 6], bx ; partition_table
mov word [bp - 8], dx ; fat32_bpb
.check_sig:
mov eax, dword [STAGE2_SIG] mov eax, dword [STAGE2_SIG]
cmp eax, 0xDEADBEEF cmp eax, 0xDEADBEEF
je main.signature_present je main.stage2_main
ERROR STAGE2_SIGNATURE_MISSING ERROR STAGE2_SIGNATURE_MISSING
.stage2_main:
mov ax, PartTable_t_size
push ax
mov ax, [bp - 6] ; ptr partition_table
mov ax, partition_table
push ax
call kmemcpy ; copy partition table data
add sp, 0x6
mov ax, (FAT32_bpb_t_size + FAT32_ebpb_t_size) ; size in byte
push ax
mov ax, [bp - 8] ; start of bpb - 0x3 for the jump short main at the start
push ax
mov ax, fat32_bpb ; defined in memory.inc, destination
push ax
call kmemcpy ; copy bpb & ebpb to memory
add sp, 0x6
.signature_present:
call SetTextMode call SetTextMode
call disable_cursor call disable_cursor
print_string HelloPrompt_cstr print_string HelloPrompt_cstr
@@ -121,6 +191,7 @@ main:
call InitFATDriver call InitFATDriver
print_string InitFATSYS_OK_cstr print_string InitFATSYS_OK_cstr
ERROR STEVIA_DEBUG_HALT
; ;
; Find first cluster of bootable file ; Find first cluster of bootable file
; ;
@@ -136,27 +207,6 @@ hcf:
hlt hlt
jmp short (hcf - $$) jmp short (hcf - $$)
; ###############
;
; FAT32 Driver
;
; ###############
boot_drive_ptr:
dw 0x0000
partition_offset_ptr:
dw 0x0000
%include 'fat32/FAT32_SYS.inc'
; ###############
;
; BIOS functions
;
; ###############
%include 'BIOS/BIOS_SYS.inc'
; ############################## ; ##############################
; ;
; SYSTEM CONFIGURATION FUNCTIONS ; SYSTEM CONFIGURATION FUNCTIONS
@@ -280,14 +330,16 @@ EnterUnrealMode:
push ss push ss
push cs ; save real mode code selector push cs ; save real mode code selector
xor ax, ax ;
pop ax ; save cs to ax to setup far jump pop ax ; save cs to ax to setup far jump
mov word [ds:__UNREAL_SEGMENT], ax mov word [__UNREAL_SEGMENT], ax
lgdt [((__STAGE2_SEGMENT << 4) + unreal_gdt_info)] ; load unreal gdt
lgdt [unreal_gdt_info]
mov eax, cr0 mov eax, cr0
or al,1 ; set pmode bit or al,1 ; set pmode bit
mov cr0, eax ; switch to pmode mov cr0, eax ; switch to pmode
jmp $+2 ; clear instruction cache jmp short $+2
;jmp far 0x0008:EnterUnrealMode.load_cs ;jmp far 0x0008:EnterUnrealMode.load_cs
db 0xEA ; jmp far imm16:imm16 db 0xEA ; jmp far imm16:imm16
@@ -304,7 +356,7 @@ EnterUnrealMode:
and al,0xFE ; toggle bit 1 of cr0 and al,0xFE ; toggle bit 1 of cr0
mov cr0, eax ; back to realmode mov cr0, eax ; back to realmode
jmp $+2 ; clear instruction cache again jmp short $+2
;jmp far 0x0008:EnterUnrealMode.unload_cs ;jmp far 0x0008:EnterUnrealMode.unload_cs
db 0xEA ; jmp far imm16:imm16 db 0xEA ; jmp far imm16:imm16
@@ -367,58 +419,33 @@ IntToHex_table:
db '0123456789ABCDEF' db '0123456789ABCDEF'
; see docs/gdt.txt for a quick refresher on GDT ; see docs/gdt.txt for a quick refresher on GDT
ALIGN 4, db 0 ALIGN 16, db 0
unreal_gdt_info: unreal_gdt_info:
unreal_gdt_size: dw (unreal_gdt_end - unreal_gdt_start) - 1 unreal_gdt_size: dw (unreal_gdt_end - unreal_gdt_start) - 1
unreal_gdt_ptr: dd unreal_gdt_start unreal_gdt_ptr: dd ((__STAGE2_SEGMENT << 4) + unreal_gdt_start)
unreal_gdt_start: unreal_gdt_start:
; entry 0 ; entry 0 (null descriptor)
dq 0 ; first entry is null dq 0 ; first entry is null
; entry 1 (4 GiB flat code map) ; entry 1 (16bit code 64KiB limit)
dw 0xFFFF ; Segment Limit 15:0 (Same large limit as data segment) dd 0x0000FFFF ; Base Address(15:0) 31:16, Segment Limit(15:0) 15:0
dw 0x0000 ; Base Address 15:0
db 0x00 ; Base Address 23:16 db 0x00 ; Base Address 23:16
db 1001_1010b ; Access Byte: 1001_1010b for executable code db 1001_1010b ; Access Byte: Present, ring0, S = 1, executable (1), non-conforming, readable, Accessed
db 1000_1111b ; Flags and Segment Limit 19:16 (Same as data segment) db 0000_0000b ; Flags: GR = 4KiB, attr = <DB/L/Avl>, Granularity = 4KiB & 16:19 of limit
db 0x00 ; Base Address 31:24 db 0x00 ; Base Address 31:24
; entry 2 (4 GiB flat data map) ; entry 2 (16bit data segment with 4 GiB flat mapping)
dw 0xFFFF ; 0:15 limit dd 0x0000FFFF ; Base Address(15:0) 31:16, Segment Limit(15:0) 15:0
dw 0x0000 ; 0:15 base db 0x00 ; Base Address(23:16)
db 0x00 ; 16:23 base db 1001_0010b ; Access Byte: Present, ring0, S = 1, data (0), non-confirming, writable, present
db 1001_0010b ; bit 0:4 = S/Type, [1, DC, RW, Ac] <code> or [0, E, RW, Ac] <data> db 1000_1111b ; Flags: GR = 4KiB, attr = <16-bit/?/?>, Granularity = 4KiB & 16:19 of limit
; bit 5:6 = Privl db 0x00 ; Base Address(31:24)
; bit 7 = Present
db 1000_1111b ; bit 0:3 = 16:19 of Limit
; bit 4 = Availible to software bit
; bit 5 = Reserved (?)
; bit 6 = D/B bit, depending on if this is code/data 1 = 32 bit operands or stack size
; bit 7 = Granularity bit. 1 = multiply limit by 4096
db 0x00 ; base 24:31
; at the end of the day...
; base = 0x00000000
; limit = 0xFFFFF
; Accessed = 0, ignore this field
; RW = 1, data is Read/Write
; E = 0, Expand up, valid data is from base -> limit, if 1 valid data is from (limit + 1) -> base
; C/D = 0, Segment is a data segment
; S = 1, Segment is a system segment
; Privl = 00b, Ring0 segment
; Pr = 1, segment is present
; AVL = 0, ignore this field
; D/B bit = 0, 16bit code/stack
; Gr = 1, multiply limit by 4096
unreal_gdt_end: unreal_gdt_end:
ALIGN 4, db 0 ALIGN 16, db 0
gdt32_info: gdt32_info:
gdt32_size: dw (gdt32_end - gdt32_start) - 1 gdt32_size: dw (gdt32_end - gdt32_start) - 1
gdt32_ptr: dd gdt32_start gdt32_ptr: dd ((__STAGE2_SEGMENT << 4) + gdt32_start)
; check above for detailed information
gdt32_start: gdt32_start:
dq 0 dq 0
.gdt32_code: .gdt32_code:
@@ -465,15 +492,58 @@ end_data:
; section start location needs to be a 'critical expression' ; section start location needs to be a 'critical expression'
; i.e resolvable at build time, we are setting 0x7E00 as the offset since ; i.e resolvable at build time, we are setting 0x7E00 as the offset since
section .sign start=((MAX_STAGE2_BYTES - 512) + 0x7E00) section .sign start=((MAX_STAGE2_BYTES - 512) + 0x0500)
times ((512 - 4) - ($ -$$) ) db 0x90 ; nop times ((512 - 4) - ($ -$$) ) db 0x90 ; nop
STAGE2_SIG: dd 0xDEADBEEF ; Signature to mark the end of the stage2 STAGE2_SIG: dd 0xDEADBEEF ; Signature to mark the end of the stage2
section .bss follows=.sign section .bss follows=.sign
align 512 align 512, resb 1
begin_bss: begin_bss:
buffer1 resb 512 stack_bottom:
buffer2 resb 512 resb 4096
buffer3 resb 512 stack_top:
buffer4 resb 512 stage2_main_redzone:
resb 32
align 16, resb 1
partition_table resb PartTable_t_size
align 16, resb 1
fat32_bpb resb FAT32_bpb_t_size
fat32_ebpb resb FAT32_ebpb_t_size
align 16, resb 1
fat32_nc_data resb 16
align 16, resb 1
lba_packet resb LBAPkt_t_size
align 16, resb 1
SteviaInfo:
resd 4
align 16, resb 1
fat32_state:
resb FAT32_State_t_size
align 16, resb 1
mbr_sector_data:
resb 512
vbr_sector_data:
resb 512
align 16, resb 1
disk_buffer:
resb 512
fat_buffer:
resb 512
dir_buffer:
resb 512
fat_fsinfo:
resb 512
align 16, resb 1
%define BIOSMemoryMap_SIZE 2048
BIOSMemoryMap:
resb 2048
end_bss: end_bss:

View File

@@ -24,12 +24,11 @@
[WARNING -reloc-abs-word] [WARNING -reloc-abs-word]
[map all vbr.map] ; Yes, we use absolute addresses. surpress these warnings. [map all vbr.map] ; Yes, we use absolute addresses. surpress these warnings.
%define __STEVIA_VBR %define __STEVIA_VBR
section .text
__ENTRY: __ENTRY:
jmp short (init - $$) jmp short (init - $$)
nop nop
phy_bpb_start:
; fill BPB area with 0x00 since we skip writing this part to disk ; fill BPB area with 0x00 since we skip writing this part to disk
; but we need it for the 'jmp short entry; nop' above ; but we need it for the 'jmp short entry; nop' above
times 33 db 0x00 times 33 db 0x00
@@ -47,35 +46,43 @@ times 54 db 0x00
%include "cdecl16.inc" %include "cdecl16.inc"
%include "entry.inc" %include "entry.inc"
%include "config.inc" %include "config.inc"
%include "mem.inc" %include "early_mem.inc"
%include "error_codes.inc" %include "error_codes.inc"
%include "partition_table.inc"
%include "fat32/fat32_structures.inc"
%include "fat32/bpb_offset_bx.inc" %include "fat32/bpb_offset_bx.inc"
;
; ############### ; dl = boot_drive
; End Section ; si = part_offset
; ############### ; bx = partition_table location from mbr
ALIGN 4
ALIGN 4, db 0x90
init: init:
cli ; We do not want to be interrupted cli ; We do not want to be interrupted
xor ax, ax
mov ds, ax ; Set segment registers to 0x0000
mov es, ax
xor ax, ax ; 0 AX ; zero bss section
mov ds, ax ; Set segment registers to 0 mov cx, (end_bss - begin_bss) ; count = bss length
mov ax, begin_bss
mov di, ax ; es:di is dest
xor ax, ax
cld
rep stosb
xor ax, ax
mov ss, ax ; Set Stack Segment to 0 mov ss, ax ; Set Stack Segment to 0
mov sp, EARLY_STACK_START ; Setup stack mov sp, stack_top ; Setup stack
mov bp, sp ; base ptr = stack ptr mov bp, sp ; base ptr = stack ptr
sub sp, 0x20 ; local varible space sub sp, 0x10 ; local varible space
mov bx, VBR_ENTRY ; move Bx to the new start of the initial boot sector mov cx, bx ; mov partition_table locaiton to cx
sti ; all done with inital setup and relocation, reenable interupts sti ; all done with inital setup and relocation, reenable interupts
jmp 0:main ; fix up cs:ip just in case and jump to relocated code jmp 0:main ; fix up cs:ip just in case and jump to relocated code
; ############### ; ###############
;
; Extra/Shared Functions ; Extra/Shared Functions
;
; ############### ; ###############
%include "util/kmem_func.nasm" %include "util/kmem_func.nasm"
@@ -85,27 +92,41 @@ init:
; End Section ; End Section
; ############### ; ###############
;
; byte boot_drive @ bp - 2
; word part_offset @ bp - 4
; ptr partition_table
ALIGN 4, db 0x90 ALIGN 4, db 0x90
main: main:
mov byte [bp - 2], dl ; boot_drive mov byte [bp - 2], dl ; boot_drive
mov [bp - 4], si ; part_offset mov word [bp - 4], si ; part_offset
mov word [bp - 6], cx ; partition_table
.load_fs_data:
mov ax, PartTable_t_size
push ax
mov ax, [bp - 6] ; ptr partition_table
mov ax, partition_table
push ax
call kmemcpy ; copy partition table data
add sp, 0x6
mov ax, (FAT32_bpb_t_size + FAT32_ebpb_t_size) ; size in byte
push ax
mov ax, __ENTRY
push ax
mov ax, fat32_bpb ;
push ax
call kmemcpy ; copy bpb & ebpb to memory
add sp, 0x6
mov bx, fat32_bpb ; bx now points to aligned memory structure
.check_FAT_size: ; we only support a very specific setup of FAT32 .check_FAT_size: ; we only support a very specific setup of FAT32
cmp dword [bsSectorHuge], 0 ; SectorsHuge will not be set if FAT12/16 cmp dword [bsSectorHuge], 0 ; SectorsHuge will not be set if FAT12/16
ja main.load_stage2 ja main.load_stage2
ERROR VBR_ERROR_WRONG_FAT_SIZE ERROR VBR_ERROR_WRONG_FAT_SIZE
.load_stage2: ; read sectors 1-63 to stage2 entry point .load_stage2:
mov ax, (fat32_bpb_SIZE + fat32_ebpb_SIZE) ; size in byte ; read sectors 1-(MAX_STAGE2_BYTES / 512) to stage2 entry point
push ax
mov ax, (phy_bpb_start - 0x3) ; start of bpb - 0x3 for the jump short main at the start
push ax
mov ax, fat32_bpb ; defined in memory.inc, destination
push ax
call kmemcpy ; copy bpb to memory
add sp, 0x6
mov bx, fat32_bpb ; bx now points to aligned memory structure
movzx ax, byte [bp - 2] movzx ax, byte [bp - 2]
push ax ; drive_num push ax ; drive_num
@@ -115,32 +136,23 @@ main:
mov dword eax, 0x1 mov dword eax, 0x1
push dword eax ; lba push dword eax ; lba
xor ax, ax
push ax ; offset = 0
; 07E0:0 = 0x00007e00
mov ax, STAGE2_ENTRY mov ax, STAGE2_ENTRY
shr ax, 4 push ax ; offset
push ax ; segment = 7E0
xor ax, ax
push ax ; segment = 0
; uint8_t read_stage2_raw(uint16_t buf_segment, uint16_t buf_offset, ; uint8_t read_stage2_raw(uint16_t buf_segment, uint16_t buf_offset,
; uint32_t lba, ; uint32_t lba,
; uint16_t count, uint16_t drive_num) ; uint16_t count, uint16_t drive_num)
call read_disk_raw call read_disk_raw
add sp, 0xC add sp, 0xC
.enter_stage2:
.check_sig: mov dl, byte [bp - 2] ; boot_drive
mov ax, 0x7E0 mov si, word [bp - 4] ; part_offset
mov fs, ax mov bx, partition_table
cmp dword [fs:0x7FFC], 0xDEADBEEF mov dx, fat32_bpb
je main.sig_ok jmp word 0x0000:STAGE2_ENTRY
ERROR VBR_ERROR_NO_SIGNATURE ; no signature present in stage2
.sig_ok:
mov si, word [bp - 4]
mov dl, byte [bp - 2]
jmp 0:0x7E00
; ############### ; ###############
; Required BIOS function(s) ; Required BIOS function(s)
@@ -155,3 +167,26 @@ times (510 - ($ - $$)) nop ; Fill the rest of sector with nop
BootSig: BootSig:
dw 0xAA55 ; Add boot signature at the end of bootloader dw 0xAA55 ; Add boot signature at the end of bootloader
section .bss follows=.text
begin_bss:
align 16, resb 1
partition_table resb PartTable_t_size
align 16, resb 1
fat32_bpb resb FAT32_bpb_t_size
fat32_ebpb resb FAT32_ebpb_t_size
align 16, resb 1
fat32_nc_data resb 16
align 16, resb 1
lba_packet resb LBAPkt_t_size
align 512, resb 1
stack_bottom resb 1024 ; 1Kib stack early on
stack_top:
vbr_redzone resb 32
end_bss: