Added a secondary stage bootloader.

This commit is contained in:
Arron David Nelson 2023-11-01 00:38:16 -07:00
parent cd323834ff
commit 61776524a9
5 changed files with 135 additions and 111 deletions

View File

@ -5,6 +5,7 @@ set(CMAKE_BINARY_DIR ${CMAKE_CURRENT_LIST_DIR}/build)
include(x86-baremetal-toolchain.cmake)
project(ClassicOSBL VERSION 0.0.1 LANGUAGES ASM_NASM)
project(ClassicOS VERSION 0.0.1 LANGUAGES C CXX ASM_NASM)
set(IS_OS_WINDOWS FALSE)
@ -28,12 +29,10 @@ set(BOOT_SOURCE_FILES
src/boot/linker.ld
)
#[[
set(GRUB_SOURCE_FILES
src/boot/grub/grub.cfg
src/boot/grub/menu.lst
)
]]
set(DRIVERS_SOURCE_FILES
src/drivers/audio/audio.c
@ -111,18 +110,13 @@ set(UTIL_SOURCE_FILES
)
add_executable(ClassicOS
${GRUB_SOURCE_FILES}
${KERNEL_SOURCE_FILES}
${DRIVERS_SOURCE_FILES}
)
if (IS_OS_LINUX)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -f elf")
set(CMAKE_EXE_LINKER_FLAGS "-g -s")
set(CMAKE_LINK_FLAGS "${CMAKE_LINK_FLAGS} -e kernel_main")
add_executable(ClassicOSBL
${BOOT_SOURCE_FILES}
${GRUB_SOURCE_FILES}
)
#set_target_properties(ClassicOS PROPERTIES LINK_FLAGS "-T ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld")
elseif (IS_OS_WINDOWS)
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -f win32")
endif ()
message("${CMAKE_EXE_LINKER_FLAGS}")

View File

@ -1,112 +1,87 @@
[BITS 16]
[ORG 0x7c00]
; Set up the segment registers
xor ax, ax
mov ds, ax
mov es, ax
start:
XOR AX, AX
MOV DS, AX
MOV SS, AX
MOV SP, 0x7c00
; Set up stack and jump to main
mov ss, ax
mov sp, 0x7c00
jmp main
MOV SI, loading
CALL printnl
; Print 'Booting ClassicOS!' to the screen
print:
mov si, message
mov ah, 0x0e
.loop:
lodsb
test al, al
jz .done
int 0x10
jmp .loop
.done:
ret
CALL reset_drives
CALL read_drive
; Set the video mode to a 40 column text mode
set_video_mode:
mov ax, 0x0003 ; Set up a 80x25 text mode
int 0x10
MOV SI, loadedSS
CALL printnl
; Set the number of columns to 40
mov ax, 0x1112
mov bx, 0x0007
int 0x10
JMP 0x1000:0x0000
ret
RET
; Detect floppy disk drive
detect_disk:
mov ah, 0x08
int 0x13
cmp ah, 0
jne .error
ret
printnl:
LODSB
OR AL, AL
JZ .stop
.error:
; Handle disk detection error
; Display error message or take appropriate action
ret
MOV AH, 0x0E
MOV BH, 0x00
MOV BL, 0x07
INT 0x10
; Read sectors from floppy disk
read_sectors:
mov ah, 0x02
mov al, 1 ; Number of sectors to read
mov ch, 0 ; Cylinder/Track number
mov cl, 2 ; Sector number (starting from 1)
mov dh, 0 ; Head number
mov dl, 0 ; Drive number (0 for floppy disk)
JMP printnl
mov bx, buffer ; Destination buffer
mov es, bx
xor bx, bx
.stop:
MOV AH, 0x03 ; AH = 0x03 (Get Cursor Position and Shape)
XOR BH, BH ; BH = 0x00 (Video Page Number)
INT 0x10 ; Call video interrupt
int 0x13
INC DH
jc .error ; Check carry flag for error
ret
MOV AH, 0x02 ; Set cursor position
XOR BH, BH ; Page number
XOR DL, DL ; Column (start from 0)
INT 0x10 ; Call video interrupt
RET
.error:
; Handle read error
; Display error message or take appropriate action
ret
reset_drives:
XOR AH, AH ; 0 = Reset floppy disk
INT 0x13
JC .reset_error ; If carry flag was set, try again
RET
; Bootloader entry point
main:
; Call the set_video_mode function
call set_video_mode
.reset_error:
MOV SI, resetError
CALL printnl
RET
; Clear the screen
mov ah, 0x06
mov al, 0
xor bx, bx
xor cx, cx
mov dh, 24
mov dl, 39
int 0x10
read_drive:
MOV AH, 0x02
MOV AL, 1 ; Number of sectors to read
XOR CH, CH ; Cylinder/Track number
MOV CL, 2 ; Sector number (starting from 1)
XOR DH, DH ; Head number
XOR DL, DL ; Drive number (0x0 for floppy disk / 0x80 for hard disk)
; Call the print function
call print
MOV BX, 0x1000
MOV ES, BX
XOR BX, BX
; Wait for a key press to exit the loop
mov ah, 0x00
int 0x16
INT 0x13
; Call the detect_disk function
call detect_disk
JC .read_error
RET
; Call the read_sectors function
call read_sectors
.read_error:
MOV SI, readError
CALL printnl
RET
; Infinite loop
.loop:
jmp .loop
; Message to print
message db 'Booting ClassicOS!', 0
; Buffer to store read sectors
buffer times 512 db 0
loading db "Loading Second Stage", 0
resetError db "Failed to reset drives.", 0
readError db "Failed to read drive", 0
loadedSS db "Loaded second stage...", 0
times 510-($-$$) db 0
dw 0xaa55

43
src/boot/boot2.asm Normal file
View File

@ -0,0 +1,43 @@
[BITS 16]
[ORG 0x0000]
start:
MOV AX, CS
MOV DS, AX
MOV SS, AX
MOV SP, 0xFFFF
MOV SI, msg
JMP println
JMP $
RET
println:
.next_char:
LODSB
OR AL, AL
JZ .stop
MOV AH, 0x0E
MOV BH, 0x00
MOV BL, 0x07
INT 0x10
JMP .next_char
.stop:
MOV AH, 0x03 ; AH = 0x03 (Get Cursor Position and Shape)
XOR BH, BH ; BH = 0x00 (Video Page Number)
INT 0x10 ; Call video interrupt
INC DH
MOV AH, 0x02 ; Set cursor position
XOR BH, BH ; Page number
XOR DL, DL ; Column (start from 0)
INT 0x10 ; Call video interrupt
RET
msg db "Second stage loaded, and Gbowne1 stinks.", 0

View File

@ -1,21 +1,33 @@
ENTRY(kernel_main)
SECTIONS {
. = 0x100000;
.text : {
*(.text)
}
.rodata : {
*(.rodata)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
}
PHDRS {
headers PT_PHDR PHDRS ;
text_seg PT_LOAD FLAGS(5); /* Read and Execute */
data_seg PT_LOAD FLAGS(6); /* Read and Write */
}
SECTIONS {
. = 0xC0000000; /* Starting virtual address */
/* Text Section */
.text : AT(ADDR(.text) - 0xC0000000)
{
*(.text)
} :text_seg
. = ALIGN(4096); /* Align to page boundary */
/* Data Section */
.data : AT(ADDR(.data) - 0xC0000000)
{
*(.data)
} :data_seg
. = ALIGN(4096); /* Align to page boundary */
/* BSS Section */
.bss : AT(ADDR(.bss) - 0xC0000000)
{
*(.bss)
} :data_seg /* Use the same segment as .data */
}

View File

@ -12,4 +12,4 @@ set(CMAKE_CXX_STANDARD 20)
set(CMAKE_ASM_NASM_FLAGS "-f elf32")
set(CMAKE_C_FLAGS "-m32 -ffreestanding -nostdlib")
set(CMAKE_CXX_FLAGS "-m32 -ffreestanding -nostdlib")
set(CMAKE_EXE_LINKER_FLAGS "-T${CMAKE_CURRENT_LIST_DIR}/linker.ld -m32")
set(CMAKE_EXE_LINKER_FLAGS "-e kernel_main -T${CMAKE_CURRENT_LIST_DIR}/linker.ld -m32 -z noexecstack")