Merge pull request #3 from Nivirx/bss-setup
convert MBR, VBR, & Stage2 to use a BSS section.
This commit is contained in:
1
Makefile
1
Makefile
@@ -25,6 +25,7 @@ stage2: $(stage2_binary_files)
|
||||
boottest: $(boottest_binary_files)
|
||||
|
||||
clean:
|
||||
@rm -rvf *.map
|
||||
@rm -rvf $(build_dir)/*
|
||||
@rm -rvf $(iso)
|
||||
@rm -rvf $(isoz)
|
||||
|
||||
@@ -48,7 +48,8 @@ GetMemoryMap:
|
||||
mov eax, 0xE820 ; select 0xE820 function
|
||||
xor ebx, ebx ; Continuation value, 0 for the first call
|
||||
|
||||
mov dx, (BIOSMemoryMap >> 4)
|
||||
lea dx, [BIOSMemoryMap]
|
||||
shr dx, 4
|
||||
mov es, dx
|
||||
xor di, di ; (BIOSMemoryMap >> 4):0 makes di an index into BIOSMemoryMap
|
||||
|
||||
|
||||
@@ -36,6 +36,29 @@ struc LBAPkt_t
|
||||
.lower_lba resd 1
|
||||
.upper_lba resd 1
|
||||
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)
|
||||
;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
%ifndef __INC_STEVIA_CONFIG
|
||||
|
||||
%define SECTOR_SIZE 512
|
||||
%define STAGE2_SECTOR_COUNT 0x40
|
||||
%define STAGE2_SECTOR_COUNT 0x30
|
||||
; 32 KiB
|
||||
%define MAX_STAGE2_BYTES (SECTOR_SIZE * STAGE2_SECTOR_COUNT)
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
; SOFTWARE.
|
||||
|
||||
%ifndef __INC_MEM
|
||||
%ifndef __INC_EARLY_MEM
|
||||
|
||||
|
||||
; ## Generic Low mem map (from osdev wiki) ##
|
||||
@@ -43,54 +43,6 @@
|
||||
; 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)
|
||||
|
||||
; 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
|
||||
%define SEG_TO_LINEAR(s,o) ((s << 4) + o)
|
||||
|
||||
@@ -100,17 +52,5 @@
|
||||
; Seg = (physical - offset) / 16
|
||||
%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
|
||||
%define __INC_MEM
|
||||
%define __INC_EARLY_MEM
|
||||
@@ -21,10 +21,10 @@
|
||||
%ifndef __INC_ENTRY
|
||||
|
||||
; 8KiB from 0x2500 -> 0x500
|
||||
%define EARLY_STACK_START 0x2500
|
||||
%define MBR_ENTRY 0x7A00
|
||||
%define EARLY_STACK_START 0xFFFF
|
||||
%define MBR_ENTRY 0x0600
|
||||
%define VBR_ENTRY 0x7C00
|
||||
%define STAGE2_ENTRY 0x7E00
|
||||
%define STAGE2_ENTRY 0x0500
|
||||
|
||||
%endif
|
||||
%define __INC_ENTRY
|
||||
@@ -28,7 +28,7 @@ ALIGN 4, db 0x90
|
||||
InitFATDriver:
|
||||
__CDECL16_ENTRY
|
||||
.func:
|
||||
mov ax, fat32_state_SIZE
|
||||
mov ax, FAT32_State_t_size
|
||||
push ax ; length of fat32_state structure
|
||||
xor ax, ax
|
||||
push ax ; init fat32_state with zero
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
; resulting in a value which does not fit in the Number of Sectors entry at 0x13.
|
||||
|
||||
struc FAT32_bpb_t
|
||||
.reserved_init resb 3
|
||||
.ident_8 resb 8
|
||||
.bytes_per_sector_16 resb 2
|
||||
.sectors_per_cluster_8 resb 1
|
||||
|
||||
@@ -34,15 +34,15 @@ struc PartEntry_t
|
||||
.chs_start resb 3
|
||||
.part_type resb 1
|
||||
.chs_end resb 3
|
||||
.lba_start resb 4
|
||||
.lba_length resb 4
|
||||
.lba_start resd 1
|
||||
.lba_length resd 1
|
||||
endstruc
|
||||
|
||||
struc PartTable_t
|
||||
.partition1 resb 16
|
||||
.partition2 resb 16
|
||||
.partition3 resb 16
|
||||
.partition4 resb 16
|
||||
.partition1 resb PartEntry_t_size
|
||||
.partition2 resb PartEntry_t_size
|
||||
.partition3 resb PartEntry_t_size
|
||||
.partition4 resb PartEntry_t_size
|
||||
endstruc
|
||||
|
||||
%endif
|
||||
|
||||
@@ -22,9 +22,7 @@
|
||||
|
||||
%macro ERROR 1
|
||||
mov al, %1 ; al = 1 byte error code mapped to ascii values
|
||||
db 0xEA ; jmp far imm16:imm16
|
||||
dw error ; error_far_seg
|
||||
dw 0x0000 ; error_far_ptr
|
||||
jmp error
|
||||
%endmacro
|
||||
|
||||
; pass error as ascii character in al, errors a-zA-Z or 0-9
|
||||
|
||||
53
include/util/kmemcpy5_func.nasm
Normal file
53
include/util/kmemcpy5_func.nasm
Normal 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
|
||||
47
include/util/kmemset4_func.nasm
Normal file
47
include/util/kmemset4_func.nasm
Normal 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
|
||||
@@ -19,46 +19,51 @@
|
||||
; SOFTWARE.
|
||||
|
||||
[BITS 16]
|
||||
[ORG 0x7A00]
|
||||
[ORG 0x0600]
|
||||
[CPU KATMAI]
|
||||
[WARNING -reloc-abs-byte]
|
||||
[WARNING -reloc-abs-word] ; Yes, we use absolute addresses. surpress these warnings.
|
||||
[map all mbr.map]
|
||||
%define __STEVIA_MBR
|
||||
|
||||
jmp short (init - $$)
|
||||
nop
|
||||
|
||||
; ###############
|
||||
;
|
||||
; Headers/Includes/Definitions
|
||||
;
|
||||
; ###############
|
||||
|
||||
%include "util/bochs_magic.inc"
|
||||
%include "cdecl16.inc"
|
||||
%include "entry.inc"
|
||||
%include "config.inc"
|
||||
%include "mem.inc"
|
||||
%include "error_codes.inc"
|
||||
%include "partition_table.inc"
|
||||
%include "fat32/fat32_structures.inc"
|
||||
|
||||
; ###############
|
||||
; End Section
|
||||
; ###############
|
||||
|
||||
ALIGN 4, db 0x90
|
||||
ALIGN 4
|
||||
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 sp, EARLY_STACK_START ; Setup stack
|
||||
mov bp, sp ; base ptr = stack ptr
|
||||
sub sp, 0x20 ; local varible space
|
||||
mov ss, ax ; Set Stack Segment to 0
|
||||
mov sp, stack_top ; Setup stack
|
||||
mov bp, sp ; base ptr = stack ptr
|
||||
sub sp, 0x10 ; local varible space
|
||||
|
||||
xor cx, cx
|
||||
mov ch, 0x01 ; 256 WORDs in MBR (512 bytes), 0x0100 in cx
|
||||
mov si, 0x7C00 ; Current MBR Address (loaded here by BIOS)
|
||||
mov di, MBR_ENTRY ; New MBR Address (our new relocation address)
|
||||
@@ -69,23 +74,15 @@ init:
|
||||
jmp 0:main
|
||||
|
||||
; ###############
|
||||
;
|
||||
; Extra/Shared Functions
|
||||
;
|
||||
; ###############
|
||||
|
||||
%include "util/kmem_func.nasm"
|
||||
%include "util/error_func.nasm"
|
||||
|
||||
; ###############
|
||||
; End Section
|
||||
; ###############
|
||||
|
||||
;
|
||||
; bp - 2 : uint8_t boot_drive
|
||||
; bp - 4 : uint16_t part_offset
|
||||
;
|
||||
|
||||
ALIGN 4, db 0x90
|
||||
main:
|
||||
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]
|
||||
push dword eax ; lba
|
||||
|
||||
xor ax, ax
|
||||
push ax ; offset = 0
|
||||
|
||||
mov ax, VBR_ENTRY
|
||||
shr ax, 4
|
||||
push ax ; segment = 7C0
|
||||
push ax ; offset = 0x7c00
|
||||
|
||||
xor ax, ax
|
||||
push ax ; segment = 0
|
||||
|
||||
; uint8_t read_stage2_raw(uint16_t buf_segment, uint16_t buf_offset,
|
||||
; uint32_t lba,
|
||||
@@ -147,18 +143,19 @@ main:
|
||||
je main.sig_ok
|
||||
ERROR MBR_ERROR_NO_VBR_SIG ; no signature present
|
||||
.sig_ok:
|
||||
mov ax, partition_table_SIZE ; 72 bytes of data
|
||||
mov ax, PartTable_t_size
|
||||
push ax
|
||||
mov ax, DiskSig ; start of partition table
|
||||
push ax
|
||||
mov ax, partition_table ; defined in memory.inc
|
||||
mov ax, partition_table
|
||||
push ax
|
||||
call kmemcpy ; copy partition table to memory
|
||||
call kmemcpy ; copy partition table to bss
|
||||
add sp, 0x6
|
||||
|
||||
mov si, word [bp - 4]
|
||||
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'
|
||||
|
||||
; ###############
|
||||
; End Section
|
||||
; ###############
|
||||
|
||||
%assign bytes_remaining (440 - ($ - $$))
|
||||
%warning MBR has bytes_remaining bytes remaining for code (MAX: 440 bytes)
|
||||
times ((512 - 72) - ($ - $$)) nop ; Fill the rest of sector with nop
|
||||
@@ -192,4 +185,27 @@ PartEntry3:
|
||||
PartEntry4:
|
||||
times 16 db 0x00
|
||||
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:
|
||||
@@ -19,27 +19,24 @@
|
||||
; SOFTWARE.
|
||||
|
||||
[BITS 16]
|
||||
[ORG 0X7E00]
|
||||
[ORG 0x0500] ; IF YOU CHANGE ORG CHANGE THE SIGN OFFSET AT THE END
|
||||
[CPU KATMAI]
|
||||
[map all stage2.map]
|
||||
[WARNING -reloc-abs-byte]
|
||||
[WARNING -reloc-abs-word]
|
||||
[WARNING -reloc-abs-dword] ; Yes, we use absolute addresses. surpress these warnings.
|
||||
%define __STEVIA_STAGE2
|
||||
|
||||
|
||||
%define __STAGE2_SEGMENT 0x0000
|
||||
|
||||
; ###############
|
||||
;
|
||||
; Headers/Includes/Definitions
|
||||
;
|
||||
; ###############
|
||||
|
||||
%include "util/bochs_magic.inc"
|
||||
%include "cdecl16.inc"
|
||||
%include "entry.inc"
|
||||
%include "config.inc"
|
||||
%include "mem.inc"
|
||||
%include "early_mem.inc"
|
||||
%include "error_codes.inc"
|
||||
|
||||
%macro print_string 1
|
||||
@@ -50,57 +47,130 @@
|
||||
%endmacro
|
||||
|
||||
section .text
|
||||
org 0x7E00
|
||||
org 0x0500
|
||||
|
||||
begin_text:
|
||||
jmp short (init - $$)
|
||||
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
|
||||
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
|
||||
mov es, ax ; *
|
||||
mov fs, ax ; *
|
||||
mov gs, ax ; *
|
||||
;
|
||||
; 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 fs, ax ; *
|
||||
mov gs, ax ; *
|
||||
|
||||
mov ss, ax ; Set Stack Segment to data segment
|
||||
mov sp, stack_top ; Set Stack Pointer
|
||||
|
||||
mov ss, ax ; Set Stack Segment to 0
|
||||
mov sp, EARLY_STACK_START ; Set Stack Pointer
|
||||
mov bp, sp
|
||||
sub sp, 0x20 ; 32 bytes for local varibles
|
||||
|
||||
sti
|
||||
|
||||
jmp 0:main
|
||||
jmp word __STAGE2_SEGMENT:main
|
||||
|
||||
; ###############
|
||||
;
|
||||
; Extra/Shared Functions
|
||||
;
|
||||
; Functions
|
||||
; ###############
|
||||
|
||||
%include "util/kmem_func.nasm"
|
||||
%include "util/kmemcpy5_func.nasm"
|
||||
%include "util/kmemset4_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
|
||||
main:
|
||||
lea ax, [bp - 2]
|
||||
mov [boot_drive_ptr], ax
|
||||
|
||||
lea ax, [bp - 4]
|
||||
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 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]
|
||||
cmp eax, 0xDEADBEEF
|
||||
je main.signature_present
|
||||
je main.stage2_main
|
||||
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 disable_cursor
|
||||
print_string HelloPrompt_cstr
|
||||
@@ -121,6 +191,7 @@ main:
|
||||
call InitFATDriver
|
||||
print_string InitFATSYS_OK_cstr
|
||||
|
||||
ERROR STEVIA_DEBUG_HALT
|
||||
;
|
||||
; Find first cluster of bootable file
|
||||
;
|
||||
@@ -136,27 +207,6 @@ hcf:
|
||||
hlt
|
||||
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
|
||||
@@ -280,14 +330,16 @@ EnterUnrealMode:
|
||||
push ss
|
||||
|
||||
push cs ; save real mode code selector
|
||||
xor ax, ax ;
|
||||
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
|
||||
or al,1 ; set pmode bit
|
||||
mov cr0, eax ; switch to pmode
|
||||
jmp $+2 ; clear instruction cache
|
||||
jmp short $+2
|
||||
|
||||
;jmp far 0x0008:EnterUnrealMode.load_cs
|
||||
db 0xEA ; jmp far imm16:imm16
|
||||
@@ -302,10 +354,10 @@ EnterUnrealMode:
|
||||
mov fs, bx
|
||||
mov gs, bx ; other data/stack to index 2 (off 0x10)
|
||||
|
||||
and al,0xFE ; toggle bit 1 of cr0
|
||||
mov cr0, eax ; back to realmode
|
||||
jmp $+2 ; clear instruction cache again
|
||||
|
||||
and al,0xFE ; toggle bit 1 of cr0
|
||||
mov cr0, eax ; back to realmode
|
||||
jmp short $+2
|
||||
|
||||
;jmp far 0x0008:EnterUnrealMode.unload_cs
|
||||
db 0xEA ; jmp far imm16:imm16
|
||||
dw EnterUnrealMode.unload_cs ; error_far_ptr
|
||||
@@ -367,58 +419,33 @@ IntToHex_table:
|
||||
db '0123456789ABCDEF'
|
||||
|
||||
; see docs/gdt.txt for a quick refresher on GDT
|
||||
ALIGN 4, db 0
|
||||
ALIGN 16, db 0
|
||||
unreal_gdt_info:
|
||||
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:
|
||||
; entry 0
|
||||
; entry 0 (null descriptor)
|
||||
dq 0 ; first entry is null
|
||||
|
||||
; entry 1 (4 GiB flat code map)
|
||||
dw 0xFFFF ; Segment Limit 15:0 (Same large limit as data segment)
|
||||
dw 0x0000 ; Base Address 15:0
|
||||
; entry 1 (16bit code 64KiB limit)
|
||||
dd 0x0000FFFF ; Base Address(15:0) 31:16, Segment Limit(15:0) 15:0
|
||||
db 0x00 ; Base Address 23:16
|
||||
db 1001_1010b ; Access Byte: 1001_1010b for executable code
|
||||
db 1000_1111b ; Flags and Segment Limit 19:16 (Same as data segment)
|
||||
db 1001_1010b ; Access Byte: Present, ring0, S = 1, executable (1), non-conforming, readable, Accessed
|
||||
db 0000_0000b ; Flags: GR = 4KiB, attr = <DB/L/Avl>, Granularity = 4KiB & 16:19 of limit
|
||||
db 0x00 ; Base Address 31:24
|
||||
|
||||
; entry 2 (4 GiB flat data map)
|
||||
dw 0xFFFF ; 0:15 limit
|
||||
dw 0x0000 ; 0:15 base
|
||||
db 0x00 ; 16:23 base
|
||||
db 1001_0010b ; bit 0:4 = S/Type, [1, DC, RW, Ac] <code> or [0, E, RW, Ac] <data>
|
||||
; bit 5:6 = Privl
|
||||
; 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
|
||||
; entry 2 (16bit data segment with 4 GiB flat mapping)
|
||||
dd 0x0000FFFF ; Base Address(15:0) 31:16, Segment Limit(15:0) 15:0
|
||||
db 0x00 ; Base Address(23:16)
|
||||
db 1001_0010b ; Access Byte: Present, ring0, S = 1, data (0), non-confirming, writable, present
|
||||
db 1000_1111b ; Flags: GR = 4KiB, attr = <16-bit/?/?>, Granularity = 4KiB & 16:19 of limit
|
||||
db 0x00 ; Base Address(31:24)
|
||||
unreal_gdt_end:
|
||||
|
||||
ALIGN 4, db 0
|
||||
ALIGN 16, db 0
|
||||
gdt32_info:
|
||||
gdt32_size: dw (gdt32_end - gdt32_start) - 1
|
||||
gdt32_ptr: dd gdt32_start
|
||||
|
||||
; check above for detailed information
|
||||
gdt32_ptr: dd ((__STAGE2_SEGMENT << 4) + gdt32_start)
|
||||
gdt32_start:
|
||||
dq 0
|
||||
.gdt32_code:
|
||||
@@ -465,15 +492,58 @@ end_data:
|
||||
|
||||
; section start location needs to be a 'critical expression'
|
||||
; i.e resolvable at build time, we are setting 0x7E00 as the offset since
|
||||
section .sign start=((MAX_STAGE2_BYTES - 512) + 0x7E00)
|
||||
times ( (512 - 4) - ($ -$$)) db 0x90 ; nop
|
||||
STAGE2_SIG: dd 0xDEADBEEF ; Signature to mark the end of the stage2
|
||||
section .sign start=((MAX_STAGE2_BYTES - 512) + 0x0500)
|
||||
times ((512 - 4) - ($ -$$) ) db 0x90 ; nop
|
||||
STAGE2_SIG: dd 0xDEADBEEF ; Signature to mark the end of the stage2
|
||||
|
||||
section .bss follows=.sign
|
||||
align 512
|
||||
align 512, resb 1
|
||||
begin_bss:
|
||||
buffer1 resb 512
|
||||
buffer2 resb 512
|
||||
buffer3 resb 512
|
||||
buffer4 resb 512
|
||||
stack_bottom:
|
||||
resb 4096
|
||||
stack_top:
|
||||
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:
|
||||
145
src/vbr/vbr.nasm
145
src/vbr/vbr.nasm
@@ -24,12 +24,11 @@
|
||||
[WARNING -reloc-abs-word]
|
||||
[map all vbr.map] ; Yes, we use absolute addresses. surpress these warnings.
|
||||
%define __STEVIA_VBR
|
||||
|
||||
section .text
|
||||
__ENTRY:
|
||||
jmp short (init - $$)
|
||||
nop
|
||||
|
||||
phy_bpb_start:
|
||||
; fill BPB area with 0x00 since we skip writing this part to disk
|
||||
; but we need it for the 'jmp short entry; nop' above
|
||||
times 33 db 0x00
|
||||
@@ -47,35 +46,43 @@ times 54 db 0x00
|
||||
%include "cdecl16.inc"
|
||||
%include "entry.inc"
|
||||
%include "config.inc"
|
||||
%include "mem.inc"
|
||||
%include "early_mem.inc"
|
||||
%include "error_codes.inc"
|
||||
%include "partition_table.inc"
|
||||
%include "fat32/fat32_structures.inc"
|
||||
%include "fat32/bpb_offset_bx.inc"
|
||||
|
||||
; ###############
|
||||
; End Section
|
||||
; ###############
|
||||
|
||||
ALIGN 4, db 0x90
|
||||
;
|
||||
; dl = boot_drive
|
||||
; si = part_offset
|
||||
; bx = partition_table location from mbr
|
||||
ALIGN 4
|
||||
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
|
||||
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
|
||||
|
||||
mov ss, ax ; Set Stack Segment to 0
|
||||
mov sp, EARLY_STACK_START ; Setup stack
|
||||
mov bp, sp ; base ptr = stack ptr
|
||||
sub sp, 0x20 ; local varible space
|
||||
xor ax, ax
|
||||
mov ss, ax ; Set Stack Segment to 0
|
||||
mov sp, stack_top ; Setup stack
|
||||
mov bp, sp ; base ptr = stack ptr
|
||||
sub sp, 0x10 ; local varible space
|
||||
|
||||
mov bx, VBR_ENTRY ; move Bx to the new start of the initial boot sector
|
||||
sti ; all done with inital setup and relocation, reenable interupts
|
||||
mov cx, bx ; mov partition_table locaiton to cx
|
||||
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
|
||||
;
|
||||
; ###############
|
||||
|
||||
%include "util/kmem_func.nasm"
|
||||
@@ -85,27 +92,41 @@ init:
|
||||
; End Section
|
||||
; ###############
|
||||
|
||||
;
|
||||
; byte boot_drive @ bp - 2
|
||||
; word part_offset @ bp - 4
|
||||
; ptr partition_table
|
||||
ALIGN 4, db 0x90
|
||||
main:
|
||||
mov byte [bp - 2], dl ; boot_drive
|
||||
mov [bp - 4], si ; part_offset
|
||||
mov byte [bp - 2], dl ; boot_drive
|
||||
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
|
||||
cmp dword [bsSectorHuge], 0 ; SectorsHuge will not be set if FAT12/16
|
||||
ja main.load_stage2
|
||||
ERROR VBR_ERROR_WRONG_FAT_SIZE
|
||||
.load_stage2: ; read sectors 1-63 to stage2 entry point
|
||||
mov ax, (fat32_bpb_SIZE + fat32_ebpb_SIZE) ; size in byte
|
||||
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
|
||||
|
||||
.load_stage2:
|
||||
; read sectors 1-(MAX_STAGE2_BYTES / 512) to stage2 entry point
|
||||
movzx ax, byte [bp - 2]
|
||||
push ax ; drive_num
|
||||
|
||||
@@ -115,32 +136,23 @@ main:
|
||||
mov dword eax, 0x1
|
||||
push dword eax ; lba
|
||||
|
||||
xor ax, ax
|
||||
push ax ; offset = 0
|
||||
|
||||
; 07E0:0 = 0x00007e00
|
||||
mov ax, STAGE2_ENTRY
|
||||
shr ax, 4
|
||||
push ax ; segment = 7E0
|
||||
push ax ; offset
|
||||
|
||||
xor ax, ax
|
||||
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
|
||||
|
||||
.check_sig:
|
||||
mov ax, 0x7E0
|
||||
mov fs, ax
|
||||
cmp dword [fs:0x7FFC], 0xDEADBEEF
|
||||
je main.sig_ok
|
||||
|
||||
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
|
||||
.enter_stage2:
|
||||
mov dl, byte [bp - 2] ; boot_drive
|
||||
mov si, word [bp - 4] ; part_offset
|
||||
mov bx, partition_table
|
||||
mov dx, fat32_bpb
|
||||
jmp word 0x0000:STAGE2_ENTRY
|
||||
|
||||
; ###############
|
||||
; Required BIOS function(s)
|
||||
@@ -154,4 +166,27 @@ main:
|
||||
times (510 - ($ - $$)) nop ; Fill the rest of sector with nop
|
||||
|
||||
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:
|
||||
Reference in New Issue
Block a user