Compare commits
29 Commits
b9b3e92632
...
trunk
| Author | SHA1 | Date | |
|---|---|---|---|
| 528e3d69fe | |||
| 9a6fea658d | |||
| 891bff9509 | |||
| 1e181bc22c | |||
| 68c8200aa4 | |||
| 766c67c041 | |||
| 49d82be0e8 | |||
| 69bd7d8f56 | |||
| 875527aa98 | |||
| c0d47d4db0 | |||
| 81a3442ac5 | |||
| 3ec55f5a39 | |||
| 9493aefa68 | |||
| 6f2fc627be | |||
| 20c715fadd | |||
| 920c623a93 | |||
| af8e7d74d3 | |||
| fde7abc544 | |||
| 69223a1ad2 | |||
| 130cd22ff1 | |||
| 4e5112b45b | |||
| 66e8e3c7fc | |||
| b0bd4b27b0 | |||
| cd316afdd1 | |||
| 9a478aa4d4 | |||
| 31d05c35e5 | |||
| 534e04ef34 | |||
| f58bf93507 | |||
| b5ae11f850 |
2
.github/workflows/daily.yaml
vendored
2
.github/workflows/daily.yaml
vendored
@@ -3,7 +3,7 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches: [ $default-branch ]
|
branches: [ $default-branch ]
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 7 * * *" # daily 07:00
|
- cron: "0 7 * * 1" # mondays at 07:00
|
||||||
workflow_dispatch: {}
|
workflow_dispatch: {}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -9,3 +9,5 @@ stevia-log
|
|||||||
.vscode/
|
.vscode/
|
||||||
*.map
|
*.map
|
||||||
compose-dev.yaml
|
compose-dev.yaml
|
||||||
|
eth_null-tx.log
|
||||||
|
eth_null-txdump.txt
|
||||||
45
README.md
45
README.md
@@ -1,6 +1,6 @@
|
|||||||
# Stevia Bootloader
|
# Stevia Bootloader
|
||||||
|
|
||||||
Stevia is a lightweight, hobby bootloader written in Assembly and C, designed for educational purposes. It targets x86 (Pentium III era) and aims to be simple, approachable, and understandable, focusing on minimalism and core functionality.
|
Stevia is a lightweight, hobby bootloader written in Assembly and C, designed for educational purposes. It targets 686+ and aims to be simple, approachable, and understandable, focusing on minimalism and core functionality.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@@ -10,18 +10,13 @@ Stevia is a lightweight, hobby bootloader written in Assembly and C, designed fo
|
|||||||
- **Stage 2 Bootloader**: Loads the kernel into memory and passes control.
|
- **Stage 2 Bootloader**: Loads the kernel into memory and passes control.
|
||||||
- **Basic Filesystem Support**: Initial filesystem recognition (details depend on implemented filesystem support).
|
- **Basic Filesystem Support**: Initial filesystem recognition (details depend on implemented filesystem support).
|
||||||
- **Memory Map Parsing**: Detects available memory regions via BIOS interrupts.
|
- **Memory Map Parsing**: Detects available memory regions via BIOS interrupts.
|
||||||
- **GDT Initialization**: Sets up the Global Descriptor Table for protected mode.
|
- **GDT Initialization**: Sets up the Global Descriptor Table for protected/unreal mode.
|
||||||
|
|
||||||
### In Progress
|
|
||||||
|
|
||||||
- **Interrupt Descriptor Table (IDT) Setup**: Setting up basic interrupt handling.
|
|
||||||
- **Basic Keyboard Input**: Initial support for capturing keystrokes.
|
|
||||||
|
|
||||||
### Planned Features
|
### Planned Features
|
||||||
|
|
||||||
- **Task Scheduling**: Basic round-robin task switching.
|
- **Interrupt Descriptor Table (IDT) Setup**: Setting up basic interrupt handling.
|
||||||
|
- **Basic Keyboard Input**: Initial support for capturing keystrokes.
|
||||||
- **Filesystem Expansion**: Support for additional filesystems.
|
- **Filesystem Expansion**: Support for additional filesystems.
|
||||||
- **More Robust Driver Support**: Additional hardware drivers, such as for storage devices.
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -29,41 +24,37 @@ Stevia is a lightweight, hobby bootloader written in Assembly and C, designed fo
|
|||||||
|
|
||||||
To build and run Stevia, you will need the following tools installed on your system:
|
To build and run Stevia, you will need the following tools installed on your system:
|
||||||
|
|
||||||
- **Assembler**: NASM for assembling bootloader components.
|
- **Assembler**: NASM for assembling bootloader components, you could use a compatible assembler but YMMV.
|
||||||
- **C Compiler**: GCC (cross-compiler recommended).
|
- **GNU make**: For building the project.
|
||||||
- **Emulator**: Bochs or QEMU for testing.
|
- **mtools**: To access the FAT partition
|
||||||
- **GNU Make**: For building the project.
|
- **fdisk**: To create disk images and setup partition tables
|
||||||
- **Utilities**:
|
- **dosfstools**: FAT32 creation
|
||||||
- **dd**: For creating raw disk images.
|
- **an x86 Emulator**: Bochs is the primary dev target, but stevia should run on any x86 emulator/hardware with at least a Pentium 3 and 640KiB of memory.
|
||||||
- **losetup** (Linux only): For associating loop devices with disk images.
|
|
||||||
- **sfdisk**: For creating DOS disk partitions.
|
|
||||||
- **mkfs.fat**: For formatting partitions as FAT32.
|
|
||||||
- **hdiutil** (macOS only): For attaching disk images.
|
|
||||||
- **newfs\_msdos** (macOS only): For formatting FAT32 partitions.
|
|
||||||
|
|
||||||
### Building and Running
|
### Building and Running
|
||||||
|
|
||||||
1. **Clone the repository**:
|
1. **Clone the repository**:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/Nivirx/stevia.git
|
git clone https://github.com/Nivirx/stevia.git
|
||||||
cd stevia
|
cd stevia
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Build the bootloader and create a bootable disk image**:
|
2. **Build the bootloader and create a bootable disk image**:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Run using Bochs**:
|
3. **Run using Bochs**:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
bochs -f bochsrc.txt
|
bochs -q -f bochsrc.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
## Project Goals
|
## Project Goals
|
||||||
|
|
||||||
Stevia is intended to be a learning tool for those interested in low-level programming, focusing on understanding the basics of how a computer starts up and manages early system resources. Contributions and forks are welcome, especially from those interested in expanding the functionality.
|
Stevia is intended to be a learning tool for those interested in low-level programming, focusing on understanding the basics of how a computer starts up and manages early system resources.
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
We welcome contributions! Feel free to open issues for bugs or feature requests, and submit pull requests for any improvements. Please ensure that your code follows the existing style and includes appropriate comments.
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
66
bochsrc.txt
66
bochsrc.txt
@@ -1,44 +1,44 @@
|
|||||||
# configuration file generated by Bochs
|
#
|
||||||
plugin_ctrl: voodoo=false, unmapped=true, biosdev=true, speaker=true, extfpuirq=true, parallel=true, serial=true, busmouse=false, e1000=false, es1370=false, gameport=true, ne2k=false, sb16=false, usb_uhci=false, usb_ohci=false, usb_ehci=false, usb_xhci=false
|
# Bochs config
|
||||||
|
#
|
||||||
config_interface: textconfig
|
config_interface: textconfig
|
||||||
display_library: x, options=gui_debug
|
display_library: x, options=gui_debug
|
||||||
memory: guest=64, host=64, block_size=128
|
plugin_ctrl: voodoo=false, unmapped=true, biosdev=true, speaker=true, extfpuirq=true, parallel=true, serial=true, busmouse=false, e1000=true, es1370=false, gameport=true, ne2k=false, sb16=false, usb_uhci=true, usb_ohci=false, usb_ehci=false, usb_xhci=false
|
||||||
romimage: file="/usr/share/bochs/BIOS-bochs-legacy", address=0x00000000, options=none, flash_data=none
|
print_timestamps: enabled=1
|
||||||
vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest"
|
|
||||||
boot: disk
|
|
||||||
floppy_bootsig_check: disabled=0
|
|
||||||
floppya: type=1_44
|
|
||||||
# no floppyb
|
|
||||||
ata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
|
|
||||||
ata0-master: type=disk, path="./build/disk.img", mode=flat, cylinders=0, heads=0, spt=0, sect_size=512, model="Stevia Disk", biosdetect=auto, translation=lba
|
|
||||||
ata0-slave: type=none
|
|
||||||
ata1: enabled=false
|
|
||||||
ata1-master: type=none
|
|
||||||
ata1-slave: type=none
|
|
||||||
ata2: enabled=false
|
|
||||||
ata3: enabled=false
|
|
||||||
optromimage1: file=none
|
|
||||||
optromimage2: file=none
|
|
||||||
optromimage3: file=none
|
|
||||||
optromimage4: file=none
|
|
||||||
optramimage1: file=none
|
|
||||||
optramimage2: file=none
|
|
||||||
optramimage3: file=none
|
|
||||||
optramimage4: file=none
|
|
||||||
pci: enabled=1, chipset=i440fx, slot1=none, slot2=none, slot3=none, slot4=none, slot5=none
|
|
||||||
vga: extension=vbe, update_freq=10, realtime=1, ddc=builtin
|
|
||||||
cpu: count=1, ips=1000000, model=p3_katmai, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
|
|
||||||
print_timestamps: enabled=0
|
|
||||||
port_e9_hack: enabled=false, all_rings=false
|
|
||||||
private_colormap: enabled=0
|
private_colormap: enabled=0
|
||||||
clock: sync=none, time0=local, rtc_sync=0
|
|
||||||
# no cmosimage
|
|
||||||
log: -
|
log: -
|
||||||
logprefix: %t%e%d
|
logprefix: %t%e%d
|
||||||
debug: action=ignore
|
debug: action=ignore
|
||||||
info: action=report
|
info: action=report
|
||||||
error: action=report
|
error: action=report
|
||||||
panic: action=ask
|
panic: action=ask
|
||||||
|
magic_break: enabled=1
|
||||||
|
port_e9_hack: enabled=1, all_rings=false
|
||||||
|
#
|
||||||
|
# Machine Spec
|
||||||
|
# 1x Pentium 3 @ (1M IPS) w/ 64MiB of System memory on the i440fx
|
||||||
|
cpu: count=1, ips=1000000, model=p3_katmai, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
|
||||||
|
memory: guest=64, host=64, block_size=128
|
||||||
|
romimage: file="/usr/share/bochs/BIOS-bochs-legacy", address=0x00000000, options=none, flash_data=none
|
||||||
|
vgaromimage: file="/usr/share/vgabios/vgabios-stdvga.bin"
|
||||||
|
pci: enabled=1, chipset=i440fx
|
||||||
|
vga: extension=vbe, update_freq=10, realtime=1, ddc=builtin
|
||||||
|
clock: sync=none, time0=local, rtc_sync=0
|
||||||
|
#
|
||||||
|
# Disks
|
||||||
|
#
|
||||||
|
boot: disk
|
||||||
|
floppy_bootsig_check: disabled=0
|
||||||
|
floppya: type=1_44
|
||||||
|
floppyb: type=1_44
|
||||||
|
ata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
|
||||||
|
ata0-master: type=disk, path="./build/disk.img", mode=flat, cylinders=0, heads=0, spt=0, sect_size=512, model="Stevia Disk", biosdetect=auto, translation=lba
|
||||||
|
ata0-slave: type=none
|
||||||
|
#
|
||||||
|
# Other hardware
|
||||||
|
#
|
||||||
|
usb_ehci: enabled=1, companion=ohci
|
||||||
|
e1000: enabled=1, mac=52:54:00:12:34:56, ethmod=null
|
||||||
keyboard: type=mf, serial_delay=150, paste_delay=100000, user_shortcut=none
|
keyboard: type=mf, serial_delay=150, paste_delay=100000, user_shortcut=none
|
||||||
mouse: type=none, enabled=false, toggle=ctrl+mbutton
|
mouse: type=none, enabled=false, toggle=ctrl+mbutton
|
||||||
sound: waveoutdrv=dummy, waveout=none, waveindrv=dummy, wavein=none, midioutdrv=dummy, midiout=none
|
sound: waveoutdrv=dummy, waveout=none, waveindrv=dummy, wavein=none, midioutdrv=dummy, midiout=none
|
||||||
@@ -49,5 +49,3 @@ com1: enabled=true, mode=null
|
|||||||
com2: enabled=false
|
com2: enabled=false
|
||||||
com3: enabled=false
|
com3: enabled=false
|
||||||
com4: enabled=false
|
com4: enabled=false
|
||||||
magic_break: enabled=1
|
|
||||||
port_e9_hack: enabled=1, all_rings=false
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ endstruc
|
|||||||
|
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
GetMemoryMap:
|
GetMemoryMap:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
push es ; save segment register
|
push es ; save segment register
|
||||||
.func:
|
.func:
|
||||||
mov dword [SteviaInfo + SteviaInfoStruct_t.MemoryMapEntries], 0
|
mov dword [SteviaInfo + SteviaInfoStruct_t.MemoryMapEntries], 0
|
||||||
@@ -83,11 +83,11 @@ GetMemoryMap:
|
|||||||
ERROR STAGE2_MM_E820_NO_SMAP
|
ERROR STAGE2_MM_E820_NO_SMAP
|
||||||
.endp:
|
.endp:
|
||||||
pop es
|
pop es
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
PrintMemoryMap:
|
PrintMemoryMap:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
mov eax, dword [SteviaInfo + SteviaInfoStruct_t.MemoryMapEntries]
|
mov eax, dword [SteviaInfo + SteviaInfoStruct_t.MemoryMapEntries]
|
||||||
cmp eax, 0
|
cmp eax, 0
|
||||||
@@ -106,15 +106,15 @@ PrintMemoryMap:
|
|||||||
; print_string strformat_buffer
|
; print_string strformat_buffer
|
||||||
|
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
FormatMemoryMapEntry:
|
FormatMemoryMapEntry:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
; create a string buffer somewhere and return address to result string in ax
|
; create a string buffer somewhere and return address to result string in ax
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
; Bits 6-7 - 00: HDD activity LED off; any other value is "on"
|
; Bits 6-7 - 00: HDD activity LED off; any other value is "on"
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
EnableA20:
|
EnableA20:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
push ds
|
push ds
|
||||||
push es
|
push es
|
||||||
.a20_check:
|
.a20_check:
|
||||||
@@ -134,7 +134,7 @@ EnableA20:
|
|||||||
.endp:
|
.endp:
|
||||||
pop es
|
pop es
|
||||||
pop ds
|
pop ds
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ endstruc
|
|||||||
; uint16_t count, uint8_t drive_num)
|
; uint16_t count, uint8_t drive_num)
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
read_disk_raw:
|
read_disk_raw:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
mov ax, LBAPkt_t_size
|
mov ax, LBAPkt_t_size
|
||||||
push ax ; len
|
push ax ; len
|
||||||
@@ -123,7 +123,7 @@ read_disk_raw:
|
|||||||
ERROR STAGE2_MBR_DISK_READ_ERROR
|
ERROR STAGE2_MBR_DISK_READ_ERROR
|
||||||
%endif
|
%endif
|
||||||
.endf:
|
.endf:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
SetTextMode:
|
SetTextMode:
|
||||||
.prolog:
|
.prolog:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
pushf
|
pushf
|
||||||
.func:
|
.func:
|
||||||
xor ah, ah ; Set Video mode BIOS function
|
xor ah, ah ; Set Video mode BIOS function
|
||||||
@@ -33,14 +33,14 @@ SetTextMode:
|
|||||||
int 0x10 ; call video interrupt
|
int 0x10 ; call video interrupt
|
||||||
.endp:
|
.endp:
|
||||||
popf
|
popf
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; disables blinking text mode cursor via crtc pokes
|
; disables blinking text mode cursor via crtc pokes
|
||||||
; 0x3D4/0x3D5 for color, mono at 0x3B4/0x3B5
|
; 0x3D4/0x3D5 for color, mono at 0x3B4/0x3B5
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
disable_cursor_crtc:
|
disable_cursor_crtc:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
mov dx, 0x3D4
|
mov dx, 0x3D4
|
||||||
mov al, 0xA ; low cursor shape register
|
mov al, 0xA ; low cursor shape register
|
||||||
@@ -50,13 +50,13 @@ disable_cursor_crtc:
|
|||||||
mov al, 0x20 ; bits 6-7 unused, bit 5 disables the cursor, bits 0-4 control the cursor shape
|
mov al, 0x20 ; bits 6-7 unused, bit 5 disables the cursor, bits 0-4 control the cursor shape
|
||||||
out dx, al
|
out dx, al
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; disables blinking text mode cursor via BIOS int 10h, ah = 01
|
; disables blinking text mode cursor via BIOS int 10h, ah = 01
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
disable_cursor_bios:
|
disable_cursor_bios:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
push bx
|
push bx
|
||||||
mov ah, 03h ; read cursor pos & shape
|
mov ah, 03h ; read cursor pos & shape
|
||||||
@@ -68,14 +68,14 @@ disable_cursor_bios:
|
|||||||
int 10h
|
int 10h
|
||||||
pop bx
|
pop bx
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Prints a C-Style string (null terminated) using BIOS vga teletype call
|
; Prints a C-Style string (null terminated) using BIOS vga teletype call
|
||||||
; void PrintString(char* buf)
|
; void PrintString(char* buf)
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
PrintString:
|
PrintString:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
mov di, [bp + 4] ; first arg is char[]
|
mov di, [bp + 4] ; first arg is char[]
|
||||||
.str_len:
|
.str_len:
|
||||||
xor cx, cx ; ECX = 0
|
xor cx, cx ; ECX = 0
|
||||||
@@ -91,6 +91,9 @@ PrintString:
|
|||||||
mov si, [bp + 4] ; source string
|
mov si, [bp + 4] ; source string
|
||||||
.print_L0:
|
.print_L0:
|
||||||
movzx ax, byte [si]
|
movzx ax, byte [si]
|
||||||
|
%ifdef __STEVIA_DEV_DEBUG
|
||||||
|
out 0xe9, byte al ; bochs magic debug port
|
||||||
|
%endif
|
||||||
push ax
|
push ax
|
||||||
call PrintCharacter
|
call PrintCharacter
|
||||||
add sp, 0x2
|
add sp, 0x2
|
||||||
@@ -101,14 +104,14 @@ PrintString:
|
|||||||
jcxz PrintString.endp
|
jcxz PrintString.endp
|
||||||
jmp PrintString.print_L0 ; Fetch next character from string
|
jmp PrintString.print_L0 ; Fetch next character from string
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret ; Return from procedure
|
ret ; Return from procedure
|
||||||
|
|
||||||
; Prints a single character
|
; Prints a single character
|
||||||
; void PrintCharacter(char c);
|
; void PrintCharacter(char c);
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
PrintCharacter:
|
PrintCharacter:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
mov al, byte [bp + 4] ; AL = character c
|
mov al, byte [bp + 4] ; AL = character c
|
||||||
mov ah, 0x0E ; INT 0x10, AH=0x0E call
|
mov ah, 0x0E ; INT 0x10, AH=0x0E call
|
||||||
@@ -116,7 +119,7 @@ PrintCharacter:
|
|||||||
int 0x10 ; call video interrupt
|
int 0x10 ; call video interrupt
|
||||||
; TODO: check for carry and clear carry before call
|
; TODO: check for carry and clear carry before call
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; TODO: fix the prolog, epilog and stack usage to confirm with cdecl16
|
; TODO: fix the prolog, epilog and stack usage to confirm with cdecl16
|
||||||
@@ -124,7 +127,7 @@ PrintCharacter:
|
|||||||
; void PrintDWORD(uint32_t val);
|
; void PrintDWORD(uint32_t val);
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
PrintDWORD:
|
PrintDWORD:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
mov si, IntToHex_table
|
mov si, IntToHex_table
|
||||||
mov ebx, 16 ; base-16
|
mov ebx, 16 ; base-16
|
||||||
@@ -166,7 +169,7 @@ PrintDWORD:
|
|||||||
jmp PrintDWORD.print_stack
|
jmp PrintDWORD.print_stack
|
||||||
|
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
%endif
|
%endif
|
||||||
%define __INC_VIDEO
|
%define __INC_VIDEO
|
||||||
@@ -13,8 +13,8 @@
|
|||||||
; You should have received a copy of the GNU General Public License
|
; You should have received a copy of the GNU General Public License
|
||||||
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
%ifnmacro __CDECL16_ENTRY
|
%ifnmacro __CDECL16_PROC_ENTRY
|
||||||
%macro __CDECL16_ENTRY 0-1
|
%macro __CDECL16_PROC_ENTRY 0-1
|
||||||
push bp
|
push bp
|
||||||
mov bp, sp
|
mov bp, sp
|
||||||
|
|
||||||
@@ -28,8 +28,8 @@
|
|||||||
%endmacro
|
%endmacro
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%ifnmacro __CDECL16_EXIT
|
%ifnmacro __CDECL16_PROC_EXIT
|
||||||
%macro __CDECL16_EXIT 0
|
%macro __CDECL16_PROC_EXIT 0
|
||||||
pop bx
|
pop bx
|
||||||
pop di
|
pop di
|
||||||
pop si
|
pop si
|
||||||
@@ -39,19 +39,88 @@
|
|||||||
%endmacro
|
%endmacro
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%ifnmacro __CDECL16_CALLER_SAVE
|
; __CDECL16_PROC_ARGS nargs
|
||||||
%macro __CDECL16_CALLER_SAVE 0
|
; Creates %$arg1 .. %$argN as [bp+4], [bp+6], ...
|
||||||
push ax
|
; for use inside of function bodies
|
||||||
push cx
|
%ifnmacro __CDECL16_PROC_ARGS
|
||||||
push dx
|
%macro __CDECL16_PROC_ARGS 1
|
||||||
|
%push __CDECL16_PROC_ARGS
|
||||||
|
%assign %$__i 1
|
||||||
|
%rep %1
|
||||||
|
%xdefine %$arg%$__i [bp + 4 + 2*(%$__i-1)]
|
||||||
|
%assign %$__i %$__i + 1
|
||||||
|
%endrep
|
||||||
|
%pop
|
||||||
%endmacro
|
%endmacro
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%ifnmacro __CDECL16_CALLER_RESTORE
|
; __CDECL16_CALL_ARGS a,b,c ==> push c / push b / push a
|
||||||
%macro __CDECL16_CALLER_RESTORE 0
|
; handles pushing values to the stack in the correct order
|
||||||
pop dx
|
%ifnmacro __CDECL16_CALL_ARGS
|
||||||
pop cx
|
%macro __CDECL16_CALL_ARGS 1-*
|
||||||
pop ax
|
%rep %0
|
||||||
|
%rotate -1 ; move the last argument into %1
|
||||||
|
push %1 ; push last, then next-to-last, ...
|
||||||
|
%endrep
|
||||||
|
%endmacro
|
||||||
|
%endif
|
||||||
|
|
||||||
|
; __CDECL16_CALL func, nargs ; adds sp by nargs*2 after call
|
||||||
|
; adds up word pushes to restore stack frame
|
||||||
|
; WARNING: if you push a dword it will only count 2, use __CDECL16_CALL_ARGS_SIZED
|
||||||
|
%ifnmacro __CDECL16_CALL
|
||||||
|
%macro __CDECL16_CALL 2
|
||||||
|
call %1
|
||||||
|
add sp, %2*2
|
||||||
|
%endmacro
|
||||||
|
%endif
|
||||||
|
|
||||||
|
; __CDECL16_CALL_ARGS_SIZED func, size1[, size2 ...] ; sizes in BYTES
|
||||||
|
; if you *need* to pass dword sized args in 16-bit mode, use this to properly
|
||||||
|
; count the stack frame to restore later!
|
||||||
|
%ifnmacro __CDECL16_CALL_ARGS_SIZED
|
||||||
|
%macro __CDECL16_CALL_ARGS_SIZED 2-*
|
||||||
|
%push __CDECL16_CALL_ARGS_SIZED
|
||||||
|
call %1
|
||||||
|
%assign %$__sum 0
|
||||||
|
%assign %$__i 2
|
||||||
|
%rep %0-1
|
||||||
|
%assign %$__sum %$__sum + %[%$__i] ; sizes may be expressions
|
||||||
|
%assign %$__i %$__i + 1
|
||||||
|
%endrep
|
||||||
|
%if %$__sum & 1
|
||||||
|
%error "__CDECL16_CALL_ARGS_SIZED: total size is odd; pushes must sum to whole bytes actually pushed (usually even)."
|
||||||
|
%endif
|
||||||
|
add sp, %$__sum
|
||||||
|
%pop
|
||||||
|
%endmacro
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%ifnmacro __CDECL16_CLOB
|
||||||
|
; Save registers in the order listed. Supports "flags" as a pseudo-reg.
|
||||||
|
%macro __CDECL16_CLOB 1-*
|
||||||
|
%rep %0
|
||||||
|
%ifidni %1, flags
|
||||||
|
pushf
|
||||||
|
%else
|
||||||
|
push %1
|
||||||
|
%endif
|
||||||
|
%rotate 1
|
||||||
|
%endrep
|
||||||
|
%endmacro
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%ifnmacro __CDECL16_UNCLOB
|
||||||
|
; Restore in reverse order of CLOB. Supports "flags".
|
||||||
|
%macro __CDECL16_UNCLOB 1-*
|
||||||
|
%rep %0
|
||||||
|
%rotate -1
|
||||||
|
%ifidni %1, flags
|
||||||
|
popf
|
||||||
|
%else
|
||||||
|
pop %1
|
||||||
|
%endif
|
||||||
|
%endrep
|
||||||
%endmacro
|
%endmacro
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
@@ -68,34 +137,3 @@
|
|||||||
pop bp
|
pop bp
|
||||||
%endmacro
|
%endmacro
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%ifnmacro __DEFLAT_DS_ES
|
|
||||||
%macro __DEFLAT_DS_ES 0
|
|
||||||
mov ax, __STAGE2_SEGMENT
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
%endmacro
|
|
||||||
%endif
|
|
||||||
|
|
||||||
%ifnmacro __REFLAT_DS_ES
|
|
||||||
%macro __REFLAT_ES 0
|
|
||||||
cli ; no interrupts
|
|
||||||
lgdt [((__STAGE2_SEGMENT << 4) + unreal_gdt_info)] ; load unreal gdt
|
|
||||||
|
|
||||||
mov eax, cr0
|
|
||||||
or eax, 1 ; set pmode bit
|
|
||||||
mov cr0, eax ; switch to pmode
|
|
||||||
jmp short $+2 ; i-cache flush
|
|
||||||
|
|
||||||
mov ax, 0x10 ; select descriptor 2
|
|
||||||
mov ds, ax ; 10h = 0001_0000b
|
|
||||||
mov es, ax ; es to big data
|
|
||||||
|
|
||||||
mov eax, cr0
|
|
||||||
and eax, ~1 ; toggle bit 1 of cr0
|
|
||||||
mov cr0, eax ; back to realmode
|
|
||||||
jmp short $+2 ; i-cache flush
|
|
||||||
sti
|
|
||||||
|
|
||||||
%endmacro
|
|
||||||
%endif
|
|
||||||
@@ -23,16 +23,11 @@
|
|||||||
; returns: none
|
; returns: none
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
InitFATDriver:
|
InitFATDriver:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
mov ax, FAT32_State_t_size
|
|
||||||
push ax ; length of fat32_state structure
|
__CDECL16_CALL_ARGS fat32_state, 0x0000, FAT32_State_t_size
|
||||||
xor ax, ax
|
__CDECL16_CALL kmemset, 3
|
||||||
push ax ; init fat32_state with zero
|
|
||||||
mov ax, fat32_state
|
|
||||||
push ax ; address of structure
|
|
||||||
call kmemset
|
|
||||||
add sp, 0x6
|
|
||||||
|
|
||||||
.calc_active_part:
|
.calc_active_part:
|
||||||
mov ax, word [partition_offset]
|
mov ax, word [partition_offset]
|
||||||
@@ -70,14 +65,14 @@ InitFATDriver:
|
|||||||
mov eax, dword [bx + FAT32_ebpb_t.root_clus_dword]
|
mov eax, dword [bx + FAT32_ebpb_t.root_clus_dword]
|
||||||
mov dword [di + FAT32_State_t.curr_dir_cluster_32], eax
|
mov dword [di + FAT32_State_t.curr_dir_cluster_32], eax
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
.error:
|
.error:
|
||||||
ERROR STAGE2_FAT32_INIT_CF
|
ERROR STAGE2_FAT32_INIT_CF
|
||||||
|
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
FSInfoPrinter:
|
FSInfoPrinter:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
;info we want to print to validate we are loading stuff from the disk correctly
|
;info we want to print to validate we are loading stuff from the disk correctly
|
||||||
; boot_drive # (i.e 0x80)
|
; boot_drive # (i.e 0x80)
|
||||||
@@ -88,7 +83,7 @@ FSInfoPrinter:
|
|||||||
; print entire FAT32 state
|
; print entire FAT32 state
|
||||||
;
|
;
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
.error:
|
.error:
|
||||||
ERROR STAGE2_ERROR_INFOPRINTER
|
ERROR STAGE2_ERROR_INFOPRINTER
|
||||||
@@ -104,18 +99,19 @@ FSInfoPrinter:
|
|||||||
; uint32_t SearchFATDIR(uint8_t* SFN);
|
; uint32_t SearchFATDIR(uint8_t* SFN);
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
SearchFATDIR:
|
SearchFATDIR:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.file_lookup:
|
.file_lookup:
|
||||||
print_string SearchFATDIR_info
|
__CDECL16_CALL_ARGS SearchFATDIR_info
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
mov bx, fat32_state
|
mov bx, fat32_state
|
||||||
.load_first_dir:
|
.load_first_dir:
|
||||||
mov eax, dword [bx + FAT32_State_t.curr_dir_cluster_32]
|
|
||||||
push dword eax ; cluster
|
; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
|
||||||
mov ax, dir_buffer
|
push dword [bx + FAT32_State_t.curr_dir_cluster_32] ; cluster
|
||||||
push ax ; offset
|
push dir_buffer ; offset
|
||||||
xor ax, ax
|
push 0x0000 ; segment
|
||||||
push ax ; segment
|
call ReadFATCluster
|
||||||
call ReadFATCluster ; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
|
|
||||||
add sp, 0x8
|
add sp, 0x8
|
||||||
|
|
||||||
mov si, dir_buffer
|
mov si, dir_buffer
|
||||||
@@ -125,9 +121,9 @@ SearchFATDIR:
|
|||||||
; if eax >= 0x0FFFFFF8 then there are no more clusters (end of chain)
|
; if eax >= 0x0FFFFFF8 then there are no more clusters (end of chain)
|
||||||
; if eax == 0x0FFFFFF7 then this is a cluster that is marked as bad
|
; if eax == 0x0FFFFFF7 then this is a cluster that is marked as bad
|
||||||
|
|
||||||
mov eax, dword [bx + FAT32_State_t.curr_dir_cluster_32]
|
; uint32_t NextCluster(uint32_t active_cluster);
|
||||||
push dword eax
|
push dword [bx + FAT32_State_t.curr_dir_cluster_32]
|
||||||
call NextCluster ; uint32_t NextCluster(uint32_t active_cluster);
|
call NextCluster
|
||||||
add sp, 0x4
|
add sp, 0x4
|
||||||
|
|
||||||
cmp eax, 0x0fff_fff7
|
cmp eax, 0x0fff_fff7
|
||||||
@@ -137,16 +133,14 @@ SearchFATDIR:
|
|||||||
|
|
||||||
.load_next_dir_next_OK:
|
.load_next_dir_next_OK:
|
||||||
; load 512 bytes of directory entries from data sector
|
; load 512 bytes of directory entries from data sector
|
||||||
mov eax, [bx + FAT32_State_t.curr_dir_cluster_32]
|
|
||||||
push dword eax ; cluster
|
|
||||||
|
|
||||||
mov ax, dir_buffer
|
; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
|
||||||
push ax ; offset
|
push dword [bx + FAT32_State_t.curr_dir_cluster_32] ; cluster
|
||||||
|
push dir_buffer ; offset
|
||||||
xor ax, ax
|
push 0x0000 ; segment
|
||||||
push ax ; segment
|
call ReadFATCluster
|
||||||
call ReadFATCluster ; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
|
|
||||||
add sp, 0x8
|
add sp, 0x8
|
||||||
|
|
||||||
.empty_dir_entry:
|
.empty_dir_entry:
|
||||||
; check for 0x0 in first byte, if true then there are no more files
|
; check for 0x0 in first byte, if true then there are no more files
|
||||||
; if true we did not find the file, we should error here
|
; if true we did not find the file, we should error here
|
||||||
@@ -176,7 +170,9 @@ SearchFATDIR:
|
|||||||
|
|
||||||
; TODO: move this to a seperate string search function
|
; TODO: move this to a seperate string search function
|
||||||
.parse_dir:
|
.parse_dir:
|
||||||
print_string MaybeFound_Boot_info
|
__CDECL16_CALL_ARGS MaybeFound_Boot_info
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
.lfn_check:
|
.lfn_check:
|
||||||
; check for ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID (0x0F) in offset 11
|
; check for ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID (0x0F) in offset 11
|
||||||
; TODO: going to skip LFN for now, since all valid volumes will have SFN's
|
; TODO: going to skip LFN for now, since all valid volumes will have SFN's
|
||||||
@@ -201,7 +197,7 @@ SearchFATDIR:
|
|||||||
mov ax, [si + FAT32_SFN_t.cluster_16_low]
|
mov ax, [si + FAT32_SFN_t.cluster_16_low]
|
||||||
; eax == first cluster of file
|
; eax == first cluster of file
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; BUG: this function needs review
|
; BUG: this function needs review
|
||||||
@@ -210,20 +206,15 @@ SearchFATDIR:
|
|||||||
; if eax == 0x0FFFFFF7 then this is a cluster that is marked as bad
|
; if eax == 0x0FFFFFF7 then this is a cluster that is marked as bad
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
NextCluster:
|
NextCluster:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
print_string NextFATCluster_info
|
__CDECL16_CALL_ARGS NextFATCluster_info
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
mov ax, FAT32_NextClusterData_t_size
|
__CDECL16_CALL_ARGS fat32_nc_data, 0x0000, FAT32_NextClusterData_t_size
|
||||||
push ax ; length
|
__CDECL16_CALL kmemset, 3
|
||||||
xor ax, ax
|
|
||||||
push ax ; init with zero
|
|
||||||
mov ax, fat32_nc_data
|
|
||||||
push ax ; address of structure
|
|
||||||
call kmemset
|
|
||||||
add sp, 0x6
|
|
||||||
|
|
||||||
mov edx, dword [bp + 4]
|
mov edx, dword [bp + 4] ; active_cluster
|
||||||
mov si, fat32_nc_data ; instead of push/pop and moving the data back
|
mov si, fat32_nc_data ; instead of push/pop and moving the data back
|
||||||
mov di, fat32_bpb ; load si & di then use xchg
|
mov di, fat32_bpb ; load si & di then use xchg
|
||||||
mov bx, fat32_state
|
mov bx, fat32_state
|
||||||
@@ -274,8 +265,9 @@ NextCluster:
|
|||||||
mov ebx, dword [si + FAT32_NextClusterData_t.entry_offset]
|
mov ebx, dword [si + FAT32_NextClusterData_t.entry_offset]
|
||||||
mov si, fat_buffer
|
mov si, fat_buffer
|
||||||
mov eax, dword [bx+si+0]
|
mov eax, dword [bx+si+0]
|
||||||
|
; BUG: ???
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
.error_cfdivz:
|
.error_cfdivz:
|
||||||
ERROR STAGE2_FAT32_NCLUS_CFDIVZ
|
ERROR STAGE2_FAT32_NCLUS_CFDIVZ
|
||||||
@@ -283,9 +275,10 @@ NextCluster:
|
|||||||
; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
|
; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
ReadFATCluster:
|
ReadFATCluster:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
print_string ReadFATCluster_info
|
__CDECL16_CALL_ARGS ReadFATCluster_info
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
mov bx, fat32_bpb
|
mov bx, fat32_bpb
|
||||||
mov si, fat32_ebpb
|
mov si, fat32_ebpb
|
||||||
@@ -318,7 +311,7 @@ ReadFATCluster:
|
|||||||
call read_disk_raw
|
call read_disk_raw
|
||||||
add sp, 0xC
|
add sp, 0xC
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
.error:
|
.error:
|
||||||
ERROR STAGE2_FAT32_CLS2LBA_CF
|
ERROR STAGE2_FAT32_CLS2LBA_CF
|
||||||
|
|||||||
@@ -12,18 +12,19 @@ endstruc
|
|||||||
; void arena_init(ArenaState *a)
|
; void arena_init(ArenaState *a)
|
||||||
;
|
;
|
||||||
arena_init:
|
arena_init:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
movzx eax, word [bp + 4] ; ptr to state structure
|
mov ax, word [bp + 4] ; ptr to state structure
|
||||||
mov di, ax
|
mov di, ax
|
||||||
|
|
||||||
xor eax, eax
|
xor ax, ax
|
||||||
mov word [di + ArenaStateStruc_t.mark], eax
|
mov word [di + ArenaStateStruc_t.mark], ax
|
||||||
mov word [di + ArenaStateStruc_t.end], word (__ARENA_HEAP_START + __ARENA_HEAP_SIZE)
|
mov word [di + ArenaStateStruc_t.end], word (__ARENA_HEAP_START + __ARENA_HEAP_SIZE)
|
||||||
mov word [di + ArenaStateStruc_t.start], __ARENA_HEAP_START
|
mov word [di + ArenaStateStruc_t.start], __ARENA_HEAP_START
|
||||||
|
|
||||||
; zero out heap area on init
|
; zero out heap area on init
|
||||||
; void* kmemset_byte(void* dst, uint8_t val, uint16_t len);
|
; void* kmemset_byte(void* dst, uint8_t val, uint16_t len);
|
||||||
|
; TODO: use word or qword spacing at least to speed this up
|
||||||
mov ax, __ARENA_HEAP_SIZE
|
mov ax, __ARENA_HEAP_SIZE
|
||||||
push ax ; len
|
push ax ; len
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
@@ -34,7 +35,7 @@ arena_init:
|
|||||||
add sp, 0x6
|
add sp, 0x6
|
||||||
|
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; size_t align_up(size_t x, size_t a)
|
; size_t align_up(size_t x, size_t a)
|
||||||
@@ -43,57 +44,125 @@ arena_init:
|
|||||||
; (x + (a-1)) & ~(a-1)
|
; (x + (a-1)) & ~(a-1)
|
||||||
; return value in ax
|
; return value in ax
|
||||||
arena_align_up:
|
arena_align_up:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
|
; if a == 0 return x
|
||||||
mov ax, [bp + 4] ; x
|
mov ax, [bp + 4] ; x
|
||||||
|
mov bx, [bp + 6] ; a
|
||||||
|
|
||||||
mov bx, [bp + 6]
|
test bx, bx
|
||||||
sub bx, 1 ; a - 1
|
jz .endp
|
||||||
|
|
||||||
|
; enforce power-of-two for alignment, return x
|
||||||
|
; for example...
|
||||||
|
; alignment = 0x0010,
|
||||||
|
; 0x0010 & (0x0010 - 0x0001)
|
||||||
|
; 0x0010 & 0x000F -> 1_0000000b & 0_11111111b => 0b == zero
|
||||||
|
;
|
||||||
|
; alignment = 0x0006
|
||||||
|
; 0x0006 & (0x0006 - 0x0001)
|
||||||
|
; 0x0006 & 0x0005 -> 00000110b & 00000101b => 00000100b != 0
|
||||||
|
;
|
||||||
|
; i.e any power of 2 has only 1 bit set in binary (2 = 0010b, 4 = 0100b, 8 = 1000b and so on)
|
||||||
|
; subtracting 1 from a power of 2 'flips' lower bits ( 7 = 0111b, 15 = 1111b ...)
|
||||||
|
; so 'and'ing a power of two with (itself - 1) will result in none of the bit's being set
|
||||||
|
mov cx, bx
|
||||||
|
dec cx
|
||||||
|
test bx, cx
|
||||||
|
jnz .endp
|
||||||
|
|
||||||
|
dec bx ; a - 1
|
||||||
|
|
||||||
mov cx, ax
|
mov cx, ax
|
||||||
add cx, bx ; x + (a+1)
|
add cx, bx ; x + (a-1)
|
||||||
not bx ; ~(a-1)
|
not bx ; ~(a-1)
|
||||||
|
|
||||||
and cx, bx ; and with the inverse
|
and cx, bx ; and with the inverse
|
||||||
|
|
||||||
mov ax, cx ; move to ax and return
|
mov ax, cx ; move to ax and return
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; void* arena_alloc(void* a, size_t bytes, size_t align)
|
; void* arena_alloc(size_t bytes, size_t align)
|
||||||
|
; bp-2 - current used arena (i.e 'highmark')
|
||||||
|
; bp-4 - aligned_ptr
|
||||||
|
; bp-6 - new_end
|
||||||
arena_alloc:
|
arena_alloc:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY 0x10
|
||||||
.func:
|
.func:
|
||||||
; remove bytes from pool and increment mark to the new cursor location
|
; remove bytes from pool and increment mark to the new cursor location
|
||||||
; return a pointer to the begining of allocated segment
|
; return a pointer to the begining of allocated segment
|
||||||
|
mov bx, early_heap_state
|
||||||
|
|
||||||
|
mov ax, word [bx + ArenaStateStruc_t.start]
|
||||||
|
mov dx, word [bx + ArenaStateStruc_t.mark]
|
||||||
|
add ax, dx ; i.e the total used arena
|
||||||
|
mov word [bp - 2], ax ; save as a local
|
||||||
|
|
||||||
|
push bx ; save heap_state pointer
|
||||||
|
|
||||||
|
mov ax, word [bp + 6] ; requested next allocation alignment
|
||||||
|
push ax
|
||||||
|
mov ax, word [bp - 2] ; current arena 'highmark'
|
||||||
|
push ax
|
||||||
|
call arena_align_up
|
||||||
|
add sp, 0x4
|
||||||
|
mov word [bp - 4], ax ; save return value
|
||||||
|
|
||||||
|
pop bx ; restore heap_state pointer
|
||||||
|
|
||||||
|
; new_end = aligned_ptr + bytes
|
||||||
|
add ax, word [bp + 4] ; add to total (so current aligned mark + bytes)
|
||||||
|
mov word [bp - 6], ax ; save as local
|
||||||
|
|
||||||
|
mov dx, word [bx + ArenaStateStruc_t.end]
|
||||||
|
cmp ax, dx
|
||||||
|
ja arena_alloc.error ; if our heap end is < the requested throw an error, heap is full
|
||||||
|
; else update the mark to the new value & return the aligned pointer
|
||||||
|
|
||||||
|
; mark_delta = new_end - curr_used
|
||||||
|
mov dx, word [bp - 6]
|
||||||
|
sub dx, word [bp - 2]
|
||||||
|
|
||||||
|
; mark += mark_delta
|
||||||
|
mov ax, word [bx + ArenaStateStruc_t.mark]
|
||||||
|
add ax, dx
|
||||||
|
mov word [bx + ArenaStateStruc_t.mark], ax
|
||||||
|
|
||||||
|
; return aligned_ptr
|
||||||
|
mov ax, word [bp - 4]
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
.error:
|
||||||
|
ERROR STEVIA_DEBUG_ERR
|
||||||
|
|
||||||
arena_mark:
|
arena_mark:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
; return the current location of the 'cursor' in the allocator
|
; return the current location of the 'cursor' in the allocator
|
||||||
|
ERROR STEVIA_DEBUG_UNIMPLEMENTED
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
arena_reset_to:
|
arena_reset_to:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
; rewind the arena to a previously marked point
|
; rewind the arena to a previously marked point
|
||||||
|
ERROR STEVIA_DEBUG_UNIMPLEMENTED
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
arena_reset:
|
arena_reset:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
; reset the entire heap to a fresh state
|
; reset the entire heap to a fresh state
|
||||||
|
ERROR STEVIA_DEBUG_UNIMPLEMENTED
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
; void* kmemset_byte(void* dst, uint8_t val, uint16_t len);
|
; void* kmemset_byte(void* dst, uint8_t val, uint16_t len);
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
kmemset:
|
kmemset:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
mov cx, [bp + 8] ; uint16_t len
|
mov cx, [bp + 8] ; uint16_t len
|
||||||
mov al, byte [bp + 6] ; uint8_t val
|
mov al, byte [bp + 6] ; uint8_t val
|
||||||
@@ -29,14 +29,14 @@ kmemset:
|
|||||||
rep stosb
|
rep stosb
|
||||||
mov ax, di ; return pointer to dest + len (last elem of dest)
|
mov ax, di ; return pointer to dest + len (last elem of dest)
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; uint8_t* kmemset(uint16_t* dest, uint16_t* src, uint16_t len);
|
; uint8_t* kmemset(uint16_t* dest, uint16_t* src, uint16_t len);
|
||||||
; not overlap safe
|
; not overlap safe
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
kmemcpy:
|
kmemcpy:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
mov cx, [bp + 8] ; len
|
mov cx, [bp + 8] ; len
|
||||||
mov si, [bp + 6] ; src
|
mov si, [bp + 6] ; src
|
||||||
@@ -46,7 +46,7 @@ kmemcpy:
|
|||||||
rep movsb
|
rep movsb
|
||||||
mov ax, di ; return pointer to dest
|
mov ax, di ; return pointer to dest
|
||||||
.endf:
|
.endf:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
; not overlap safe, only for
|
; not overlap safe, only for
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
kmemcpy5:
|
kmemcpy5:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
push ds
|
push ds
|
||||||
push es
|
push es
|
||||||
.setup_segments:
|
.setup_segments:
|
||||||
@@ -41,7 +41,7 @@ kmemcpy5:
|
|||||||
pop es
|
pop es
|
||||||
pop ds
|
pop ds
|
||||||
.endf:
|
.endf:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
%define __INC_KMEMCPY5_FUNC
|
%define __INC_KMEMCPY5_FUNC
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
; word kmemset_byte(word segment, word dst, byte val, word len);
|
; word kmemset_byte(word segment, word dst, byte val, word len);
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
kmemset4:
|
kmemset4:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.setup_segment:
|
.setup_segment:
|
||||||
push es
|
push es
|
||||||
mov ax, [bp + 4]
|
mov ax, [bp + 4]
|
||||||
@@ -35,7 +35,7 @@ kmemset4:
|
|||||||
.restore_segments:
|
.restore_segments:
|
||||||
pop es
|
pop es
|
||||||
.endf:
|
.endf:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|||||||
@@ -17,8 +17,7 @@ set -euo pipefail
|
|||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
if [ $(id -u) = 0 ]; then
|
if [ $(id -u) = 0 ]; then
|
||||||
echo "Script should not be run as root, it could break something! Exiting!" >&2
|
echo "Script should not be run as root, it could break something!" >&2
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# paths to bootcode
|
# paths to bootcode
|
||||||
@@ -125,8 +124,11 @@ if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
|||||||
echo "[2/7] Write DOS partition table (single FAT32 LBA @ 2048)"
|
echo "[2/7] Write DOS partition table (single FAT32 LBA @ 2048)"
|
||||||
"$SF" --no-reread "$disk_img" < /tmp/pt.sfdisk
|
"$SF" --no-reread "$disk_img" < /tmp/pt.sfdisk
|
||||||
|
|
||||||
echo "[3/7] Make FAT32 filesystem in partition image"
|
# BUG: the default disk img is 256MiB which mkfs.fat wants to create
|
||||||
"$MKFS" -v -F32 -s 1 -n 'STEVIAFS' "$part_img"
|
# a FAT16 FS by default. it needs to be at least 2GiB to to 'lock out'
|
||||||
|
# FAT16 as an option. Force FAT32 here, might(?) break some things.
|
||||||
|
echo "[3/7] Make FAT filesystem in partition image"
|
||||||
|
"$MKFS" -F32 -v -n 'STEVIAFS' "$part_img"
|
||||||
|
|
||||||
echo "[4/7] Patch VBR inside partition image (preserve BPB)"
|
echo "[4/7] Patch VBR inside partition image (preserve BPB)"
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
[BITS 16]
|
[BITS 16]
|
||||||
[ORG 0x0500] ; IF YOU CHANGE ORG CHANGE THE SIGN OFFSET AT THE END
|
[ORG 0x0500] ; IF YOU CHANGE ORG CHANGE THE SIGN OFFSET AT THE END
|
||||||
[CPU KATMAI]
|
[CPU 686]
|
||||||
[map all build/stage2.map]
|
[map all build/stage2.map]
|
||||||
[WARNING -reloc-abs-byte]
|
[WARNING -reloc-abs-byte]
|
||||||
[WARNING -reloc-abs-word]
|
[WARNING -reloc-abs-word]
|
||||||
@@ -34,13 +34,6 @@
|
|||||||
%include "early_mem.inc"
|
%include "early_mem.inc"
|
||||||
%include "error_codes.inc"
|
%include "error_codes.inc"
|
||||||
|
|
||||||
%macro print_string 1
|
|
||||||
mov ax, %1
|
|
||||||
push ax
|
|
||||||
call PrintString
|
|
||||||
add sp, 0x2
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
begin_text:
|
begin_text:
|
||||||
; dl = byte boot_drive
|
; dl = byte boot_drive
|
||||||
@@ -88,7 +81,7 @@ init:
|
|||||||
jmp word __STAGE2_SEGMENT:main
|
jmp word __STAGE2_SEGMENT:main
|
||||||
|
|
||||||
; ###############
|
; ###############
|
||||||
; Functions
|
; Core Functions
|
||||||
; ###############
|
; ###############
|
||||||
|
|
||||||
%include "util/kmem_func.nasm"
|
%include "util/kmem_func.nasm"
|
||||||
@@ -96,6 +89,11 @@ init:
|
|||||||
%include "util/kmemset4_func.nasm"
|
%include "util/kmemset4_func.nasm"
|
||||||
%include "util/error_func.nasm"
|
%include "util/error_func.nasm"
|
||||||
|
|
||||||
|
; ###############
|
||||||
|
; Functions
|
||||||
|
; ###############
|
||||||
|
%include "util/arena_alloc.nasm"
|
||||||
|
|
||||||
; ###############
|
; ###############
|
||||||
; FAT32 Driver
|
; FAT32 Driver
|
||||||
; ###############
|
; ###############
|
||||||
@@ -130,50 +128,53 @@ main:
|
|||||||
je main.stage2_main
|
je main.stage2_main
|
||||||
ERROR STAGE2_SIGNATURE_MISSING
|
ERROR STAGE2_SIGNATURE_MISSING
|
||||||
.stage2_main:
|
.stage2_main:
|
||||||
mov ax, PartTable_t_size
|
; copy partition table data to .data section in stage2
|
||||||
push ax ; len = PartTable_t_size
|
__CDECL16_CALL_ARGS partition_table, word [vbr_part_table_ptr], PartTable_t_size
|
||||||
mov ax, word [vbr_part_table_ptr] ; src = ptr to vbr partition_table
|
__CDECL16_CALL kmemcpy, 3
|
||||||
push ax
|
|
||||||
mov ax, partition_table ; dst
|
|
||||||
push ax
|
|
||||||
call kmemcpy ; copy partition table data to .data section in stage2
|
|
||||||
add sp, 0x6
|
|
||||||
|
|
||||||
mov ax, (FAT32_bpb_t_size + FAT32_ebpb_t_size) ; len
|
; copy bpb & ebpb to memory
|
||||||
push ax
|
__CDECL16_CALL_ARGS fat32_bpb, word [vbr_fat32_bpb_ptr], (FAT32_bpb_t_size + FAT32_ebpb_t_size)
|
||||||
mov ax, word [vbr_fat32_bpb_ptr] ; src
|
__CDECL16_CALL kmemcpy, 3
|
||||||
push ax
|
|
||||||
mov ax, fat32_bpb ; dst
|
|
||||||
push ax
|
|
||||||
call kmemcpy ; copy bpb & ebpb to memory
|
|
||||||
add sp, 0x6
|
|
||||||
|
|
||||||
call SetTextMode
|
call SetTextMode
|
||||||
call disable_cursor_bios
|
call disable_cursor_bios
|
||||||
print_string HelloPrompt_info
|
|
||||||
|
__CDECL16_CALL_ARGS HelloPrompt_info
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
|
; setup the early heap
|
||||||
|
__CDECL16_CALL_ARGS early_heap_state
|
||||||
|
|
||||||
; enable A20 gate
|
; enable A20 gate
|
||||||
call EnableA20
|
call EnableA20
|
||||||
print_string A20_Enabled_OK_info
|
__CDECL16_CALL_ARGS A20_Enabled_OK_info
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
; get system memory map
|
; get system memory map
|
||||||
call GetMemoryMap
|
call GetMemoryMap
|
||||||
print_string MemoryMap_OK_info
|
__CDECL16_CALL_ARGS MemoryMap_OK_info
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
; enter unreal mode (16 bit code, 32 bit flat memory model)
|
; enter unreal mode (enter PM w/ 16 bit code, 32 bit flat memory model & return to real)
|
||||||
|
; ds, es will be set to the 64KiB STAGE2_SEGMENT, fs/gs will be flat/huge memory (4GiB)
|
||||||
|
; use __REFLAT macros to re-flat ds/es for easy transfers to >1MiB
|
||||||
|
; NOTE: if you modify a segment register you will need to re-unreal it
|
||||||
call EnterUnrealMode
|
call EnterUnrealMode
|
||||||
print_string UnrealMode_OK_info
|
__CDECL16_CALL_ARGS UnrealMode_OK_info
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
; FAT Driver setup
|
; FAT Driver setup
|
||||||
call InitFATDriver
|
call InitFATDriver
|
||||||
print_string InitFATSYS_OK_info
|
__CDECL16_CALL_ARGS InitFATSYS_OK_info
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
;
|
;
|
||||||
; Find first cluster of bootable file
|
; Find first cluster of bootable file
|
||||||
call SearchFATDIR
|
call SearchFATDIR
|
||||||
push dword eax ; save first cluster of bootable file
|
push dword eax ; save first cluster of bootable file
|
||||||
|
|
||||||
print_string FileFound_OK_info
|
__CDECL16_CALL_ARGS FileFound_OK_info
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
pop dword eax
|
pop dword eax
|
||||||
push dword eax ; print Cluster of boot file
|
push dword eax ; print Cluster of boot file
|
||||||
@@ -187,13 +188,69 @@ hcf:
|
|||||||
|
|
||||||
; ##############################
|
; ##############################
|
||||||
;
|
;
|
||||||
; SYSTEM CONFIGURATION FUNCTIONS
|
; SYSTEM CONFIGURATION FUNCTIONS & MACROS
|
||||||
;
|
;
|
||||||
; ##############################
|
; ##############################
|
||||||
|
|
||||||
|
; set ds and es segments back to the base of the loader
|
||||||
|
%ifnmacro __TINY_DS_ES
|
||||||
|
%macro __TINY_DS_ES 0
|
||||||
|
mov ax, __STAGE2_SEGMENT
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
%endmacro
|
||||||
|
%endif
|
||||||
|
|
||||||
|
; for copying between locations in high memory
|
||||||
|
%ifnmacro __REFLAT_DS_ES
|
||||||
|
%macro __REFLAT_DS_ES 0
|
||||||
|
cli ; no interrupts
|
||||||
|
lgdt [((__STAGE2_SEGMENT << 4) + unreal_gdt_info)] ; load unreal gdt
|
||||||
|
|
||||||
|
mov eax, cr0
|
||||||
|
or eax, 1 ; set pmode bit
|
||||||
|
mov cr0, eax ; switch to pmode
|
||||||
|
jmp short $+2 ; i-cache flush
|
||||||
|
|
||||||
|
mov ax, 0x10 ; select descriptor 2
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
|
||||||
|
mov eax, cr0
|
||||||
|
and eax, ~1 ; toggle bit 1 of cr0
|
||||||
|
mov cr0, eax ; back to realmode
|
||||||
|
jmp short $+2 ; i-cache flush
|
||||||
|
sti
|
||||||
|
|
||||||
|
%endmacro
|
||||||
|
%endif
|
||||||
|
|
||||||
|
; for copying from low memory to high memory (ds on a real segment, es in flat mode)
|
||||||
|
%ifnmacro __REFLAT_ES
|
||||||
|
%macro __REFLAT_ES 0
|
||||||
|
cli ; no interrupts
|
||||||
|
lgdt [((__STAGE2_SEGMENT << 4) + unreal_gdt_info)] ; load unreal gdt
|
||||||
|
|
||||||
|
mov eax, cr0
|
||||||
|
or eax, 1 ; set pmode bit
|
||||||
|
mov cr0, eax ; switch to pmode
|
||||||
|
jmp short $+2 ; i-cache flush
|
||||||
|
|
||||||
|
mov ax, 0x10 ; select descriptor 2
|
||||||
|
mov es, ax
|
||||||
|
|
||||||
|
mov eax, cr0
|
||||||
|
and eax, ~1 ; toggle bit 1 of cr0
|
||||||
|
mov cr0, eax ; back to realmode
|
||||||
|
jmp short $+2 ; i-cache flush
|
||||||
|
sti
|
||||||
|
|
||||||
|
%endmacro
|
||||||
|
%endif
|
||||||
|
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
EnterUnrealMode:
|
EnterUnrealMode:
|
||||||
__BOCHS_MAGIC_DEBUG
|
__CDECL16_PROC_ENTRY
|
||||||
__CDECL16_ENTRY
|
|
||||||
cli ; no interrupts
|
cli ; no interrupts
|
||||||
.func:
|
.func:
|
||||||
lgdt [((__STAGE2_SEGMENT << 4) + unreal_gdt_info)] ; load unreal gdt
|
lgdt [((__STAGE2_SEGMENT << 4) + unreal_gdt_info)] ; load unreal gdt
|
||||||
@@ -201,19 +258,14 @@ EnterUnrealMode:
|
|||||||
mov eax, cr0
|
mov eax, cr0
|
||||||
or eax, 1 ; set pmode bit
|
or eax, 1 ; set pmode bit
|
||||||
mov cr0, eax ; switch to pmode
|
mov cr0, eax ; switch to pmode
|
||||||
;jmp short $+2 ; i-cache flush
|
|
||||||
|
|
||||||
; set cs to a pm code segment (0x8) w/ the following
|
; set cs to a pm code segment (0x8) w/ the following
|
||||||
jmp 0x0008:EnterUnrealMode.set_segs
|
jmp 0x0008:EnterUnrealMode.set_segs
|
||||||
;db 0xEA ; jmp far imm16:imm16
|
|
||||||
;dw EnterUnrealMode.set_segs ; error_far_ptr
|
|
||||||
;dw 0x0008 ; error_far_seg
|
|
||||||
.set_segs:
|
.set_segs:
|
||||||
mov ax, 0x10 ; select descriptor 2
|
mov ax, 0x10 ; select descriptor 2
|
||||||
mov ds, ax ; 10h = 0001_0000b
|
mov ds, ax ; 10h = 0001_0000b
|
||||||
mov es, ax ; es to big data
|
mov es, ax ; es to big data
|
||||||
|
|
||||||
mov ss, ax ; big stack
|
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax ; extra segments to big data as well
|
mov gs, ax ; extra segments to big data as well
|
||||||
.pm_start:
|
.pm_start:
|
||||||
@@ -223,11 +275,16 @@ EnterUnrealMode:
|
|||||||
mov eax, cr0
|
mov eax, cr0
|
||||||
and eax, ~1 ; toggle bit 1 of cr0
|
and eax, ~1 ; toggle bit 1 of cr0
|
||||||
mov cr0, eax ; back to realmode
|
mov cr0, eax ; back to realmode
|
||||||
jmp 0x0000:EnterUnrealMode.endp
|
jmp __STAGE2_SEGMENT:EnterUnrealMode.endp
|
||||||
;jmp short $+2 ; i-cache flush
|
|
||||||
.endp:
|
.endp:
|
||||||
sti ; re-enable interupts
|
sti ; re-enable interupts
|
||||||
__CDECL16_EXIT
|
|
||||||
|
; set ds, es to the STAGE2_SEGMENT, for our model (generally) ds == es == cs
|
||||||
|
; fs, gs & ss are all still huge data model, and the macro(s) "__REFLAT_xxx" exists
|
||||||
|
; to easily access data outside of 64KiB boundries using ds/es addressing
|
||||||
|
__TINY_DS_ES
|
||||||
|
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
end_text:
|
end_text:
|
||||||
|
|
||||||
@@ -410,6 +467,10 @@ fat32_state:
|
|||||||
align 16, resb 1
|
align 16, resb 1
|
||||||
SteviaInfo:
|
SteviaInfo:
|
||||||
resd 4
|
resd 4
|
||||||
|
|
||||||
|
align 16, resb 1
|
||||||
|
early_heap_state:
|
||||||
|
resb ArenaStateStruc_t_size
|
||||||
;
|
;
|
||||||
; post-bss init globals
|
; post-bss init globals
|
||||||
;
|
;
|
||||||
|
|||||||
Reference in New Issue
Block a user