Building an OS - 2 - Reading from the disk

preview_player
Показать описание
Part 2 of a multipart series about making operating systems. In this part, we write the part of the bootloader that reads from the disk using the BIOS INT 0x13.

Tools:

Documentation:
Рекомендации по теме
Комментарии
Автор

Amazing Video!
The only bad thing was that there is no mkfs.fat command on mac so it took me 3 hours to find a replacement, but i did.
For anyone that is on mac just replace this line in the Makefile:
15 | mkfs.fat -F 12 -n "NBOS" $(BUILD_DIR)/main_floppy.img
with:
15 | newfs_msdos -F 12 -f 2880 $(BUILD_DIR)/main_floppy.img

tom-on
Автор

Rowing rowing your boat... Down the memory lane... That video brings me so many memories. Imagine troubleshooting that without QEMU or BOCHS, using a real floppy disk!

ecosta
Автор

Thank you for this. I used to play with that in the early 90s...

To pass parameters to a function, "high-level" languages use the stack:
my_function proc near
param1 equ [bp+4]
param2 equ [bp+6]
push bp
mov bp, sp
...
mov ax, param1
...
pop bp
ret 2 ; 2 words
my_function endp

and

push param1
push param 2
call my_function

Now, to be fair, this is pure 8086, as they add "bound" instructions since 80286 (long ago) to avoid the "ret 2" and needing to calculate the number of words to unstack, but that's more than enough in a 16bit real mode bootloader.

Also, function 41h of int 13h seems to take LBA values for read, which is more appropriate if you're using a different media (such as an empty hard disk or an ISO), so you don't need to bother calculating the CHS. Also, there are bitwise ways of filtering and calculating CHS (with and+shr and shl if you're using ecx/edx) and "or dl, dl" seems to be the fastest way to check for carry in dl (rather that "test dl").

I know "hlt" is short, but for a reboot, you can also do:
xor ax, ax
dec ax
push ax
inc ax
push ax
retf

...or simply
jmp 0ffffh:0000h

So you're sure everything is done properly at processor level, whatever "variant" of x86 you have (including Cyrix and AMD).

Also, for the teletype function to output a string, you can have a function that starts with "pop si", reads the string until it finds a '\0\ and "jmp si" (push si before calling if required) and thus have your messages directly inline, like:
write_string proc near
pop si
mov ah, 0eh ; int 10h:teletype
xor bl, bl ; screen 0
loop:
lodsb
or al, al
jz eos
int 10h
jmp loop
eos:
jmp si
write_string endp

/* ... some code... */
push si
call write_string
db 'hello world', 0
; code continues here...
pop si
...

That's a lot of jumps at the beginning, wouldn't it be better to have your first instruction as just "jmp start" and all functions before/after the main block instead of having "jmp start/jmp main"?

RegisMichelLeclerc
Автор

This series is a gold mine, please continue! Thank you for your hard work, it really helps when starting to learn more in-depth about OSs.

catalingoga
Автор

Thanks for putting in the hard work to get these videos posted. I liked how you used multiple tools to trace thru the code and really explained the theory behind it. Really informative.

numberformat
Автор

These tutorials are amazing so far!
I've written all of these on floppy disc and run it on a Pentium and they work fine :3

legacywolf
Автор

These tutorials are really nice, very good explanations. When starting bochs it helped me using "display_library: x", otherwise it wouldnt start. But everything else works as shown! :D

llytaii
Автор

Thank you for the video, I think that every CS student should be subscribed to this channel!

cristianhoger
Автор

great videos, I'm loving working through this series

aaroncirillo
Автор

I am enjoying this series a lot, so keep them coming!

As for the boot loader... Personally, I would actually simply use the standard boot sector for a FAT12 filesystem and patch this to load a custom file. This file would then be the boot loader and would in turn set things up and load the actual kernel. This ensures some compatibility with anything existing and also saves me from having to write a new boot sector every time I start a new experiment.

damouze
Автор

You are awesome! Your teaching style is so amazing! keep it up! :)

kennethlooney
Автор

This is amazing tutorial! I've not found another one more in depth than this!

programtrue
Автор

using the boch config shown here, I encountered the could not read physical memory on clicking continue on the box gui.
Changed the romimage to legacy, and removed the address argument, and it worked as expected.

amadlover
Автор

It was very cool. I was programming with you and it was a good experience that I came to the same conclusion as you. 😍

mehrdad-mixtape
Автор

Your content is amazing, thanks for showing up in my recommended :)

ari_archer
Автор

Important note to those using WSL:

If you're having trouble getting bochs to work, it's because of the weird nature of WSL not being able to access everything.
Bochs by default tries to access the sound cards during initialisation, which WSL has no support for. This results in a really annoying error when you try to run it.

The fix is adding this line to the bochs_config:
plugin_ctrl: speaker=0
If bochs is screaming about memory issues, check the address. In my case I had to change it to 0xffff0000.

creeperthecat
Автор

Thank you so much for this.. Your content is amazing, thanks for showing up in my recommended :).

CarterSherman-zn
Автор

i really like your voice. its very calm

joedew
Автор

I'm at 12:24 and when I run make, it says I don't have permissions for mcopy, and when I run sudo make, it says mcopy not found. I am on Windows 11 using WSL Ubuntu.
EDIT - Turns out I didn't have mtools installed, now I can use make.

Sebwazhere
Автор

I dont want to learn assembly but this video is very intresting.

HKN