Over the past hours, I have been messing around with floppy drives. It seems as though I have sort of managed to load the file I have been after loading, only it is just certain functionality within the loaded (and then "jmp:d" to) file that seems to be working properly.
What I have is two files (I am attempting to create a multiboot bootloader), a boot.asm (stage 1) and a loader.asm (stage 2). I then compile these to a boot.bin and a loader.bin respectively. I then merge these files into one file (each file at the moment contains 512 bytes for testing purposes - oh and hey, the STAGE 1 file contains 512 bytes for obvious reasons). In the merged file, the contents of boot.bin comes first and the contents from loader.bin comes after. The file they are merged into is called floppy.img (and is called that to represent a floppy). The floppy.img is however not formatted to be in a particular "file system layout" (such as FAT-12, FAT-16, ext, etc.), it is simply the binary from the two files "stacked on top of each other".
Whilst the STAGE 1 (boot.asm) contains the 0xaa55, that logically is what is booted by the BIOS. In that file, I attempt loading the second file (which honestly is not really a file, only a disk sector - but you know this ); I attempt loading the second file into 0x1000:0x0000, which I am pretty sure works. I then do a jump over to that location (0x1000:0x0000) and the code is executed (at least I am pretty sure it is executed, more about that in just a second). The thing is, it acts rather weird...
What you are seeing here is what happens when I run the bootloader in Bochs. The "broad" steps that happens are...
- 1. "Booting from floppy..." (from Bochs, telling us we are booting from a floppy)
2. "Boot, stage one." (printed by the STAGE 1 (or boot.asm (whoah, there are a lot of brackets (in here))), it means that STAGE 1 was successfully ran)
3. "*" (printed by the STAGE 1 - indicates that the floppy sector was successfully loaded)
4. "The things from after the '*' but before the 'u'" (assumably printed by STAGE 2, this is supposed to say "Boot, stage two." - it evidently does not)
5. "u" (printed by STAGE 2, right after printing the string which evidently does not display correctly - for some reason the "u" turns out fine. It is however printed using a slightly different method which you will see in the code below.
Something to note: there is a similar print function in the STAGE 1, which opposed to the print function in STAGE 2 is working. I have tried changing its name and... Well, many many many more things... I was highly surprised when I noticed that it was possible to print out a "u" (or any other ASCII symbol) to the "VGA monitor" for that matter.
Once again, many apologies for the rather big chunk of code.
Here is the STAGE 1 (boot.asm):
Code: Select all
; Since we enter in 16 bit realmode
[bits 16]
; Set the offset, this is where the BIOS loads us
[org 0x0]
; Far jump to start
jmp start
; DEFINE INNER FUNCTIONS
; PRINT STRING
; Function for printing strings
Print:
mov ah, 0eh ; Used for printing a character to the screen
PrintString:
lodsb ; Take the next character (byte) from SI and store in AL
and al, al ; Pointless operation to check whether or not AL is zero
jz PrintDone ; If it is, the print is finished
int 10h ; Execute
jmp PrintString ; Carry on printing until zero has been found
PrintDone:
ret ; Return back to from where function was called
; LOAD BOOT LOADER STAGE TWO
; Load sectors from second boot loader into memory
Stage:
mov di, 05h ; Five tries to load
StageReset:
mov ah, 0 ; Reset disk function
mov dl, 0 ; Disk type is floppy
int 13h ; Invoke BIOS
jc StageReset ; Upon error, retry
StageReadLoopPrepare:
mov ah, 02h ; BIOS read sector
mov al, 1 ; Read one sector
mov ch, 0 ; Read from same track
mov cl, 2 ; Sector to read
mov dh, 0 ; Head number
StageReadLoop:
int 13h ; Invoke BIOS
jc StageReadLoopPrepare ; Upon error, try again
StageSuccess:
mov si, messageProgress
call Print
jmp 0x1000:0x0000 ; Jump to execute sector
start:
; Setup registers to point to segments
cli
mov ax, 0x07c0
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
sti
mov si, messageWelcome
call Print
; Attempt to load stage two, error handling is done in function
; Read into memory at 0x7c00:0x0200
xor ax, 0x1000
mov es, ax ; Load position piece one
mov bx, 0x0000 ; Load position for stage two bootloader (512 bytes)
call Stage
; This message is supposed not to appear
mov si, messageWelcome
call Print
; Disable interrupts and halt system
cli
hlt
; Data
messageDebug: ; Message used for debugging purposes
db "$$$", 0
messageWelcome: ; Message when entering the boot part of the multiboot loader
db "Boot, stage one.", 0ah, 0dh, 0
messageProgress: ; Message upon successfully loading one sector of the stage two bootloader
db "*", 0
; 510 - (current address - starting address)
; Pad out with blank space
times 510 - ($-$$) db 0
; The magic BIOS bootsector number
; Highly magical
dw 0xaa55
Code: Select all
; We are still in 16-bit real mode
; We are still in 16-bit real mode
[bits 16]
; Go to program entry point
jmp main
; DEFINE INNER FUNCTIONS
; PRINT STRING
; Function for printing strings
Print:
mov ah, 0eh ; Used for printing a character to the screen
PrintString:
lodsb ; Take the next character (byte) from SI and store in AL
and al, al ; Pointless operation to check whether or not AL is zero
jz PrintDone ; If it is, the print is finished
int 10h ; Execute
jmp PrintString ; Carry on printing until zero has been found
PrintDone:
ret ; Return back to from where function was called
; PROGRAM ENTRY
main:
; FRIENDS, FRIENDS HERE IS THE ERROR
; FRIENDS, HERE I AM: THE CODE WHO IS NOT BEHAVING
; PLEASE SAVE ME
; I AM HERE EVERYBODY!
; Print a string (NOT WORKING)
mov si, messageWelcome
call Print
; I FOR SOME ODD REASON WORK, EVEN THOUGH I AM PRINTED
; OUT IN A RATHER SIMILAR WAY TO THAT OF MY BROTHER ABOVE
; YO
; Print a "u", which for some odd reason works...
mov ah, 0eh
mov al, "u"
int 10h
cli
hlt
; Data
messageWelcome: ; Message when entering the loader part of the multiboot loader, the part before the kernel
db "Boot, stage two.", 0ah, 0dh, 0
; Boot stage two is a whole lot larger than boot stage one
; Still not too big for our bootloader to handle
; Pad with zeroes
times 512 - ($-$$) db 0 ; Final version will be 4096 bytes
Thanks a hole lot in advance and thank you for for taking your time reading through all this! Many thanks!
Best regards,
Red Twtty