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

View File

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