forked from cfenollosa/os-tutorial
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
14f51e8
commit 2f1378d
Showing
7 changed files
with
180 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
/*/*.bin | ||
/*/*.o | ||
/*/*.swp | ||
/*/*.dis |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# $@ = target file | ||
# $< = first dependency | ||
# $^ = all dependencies | ||
|
||
# First rule is the one executed when no paramaters are fed to the Makefile | ||
all: run | ||
|
||
# Notice how dependencies are built as needed | ||
kernel.bin: kernel_entry.o kernel.o | ||
i386-elf-ld -o $@ -Ttext 0x1000 $^ --oformat binary | ||
|
||
kernel_entry.o: kernel_entry.asm | ||
nasm $< -f elf -o $@ | ||
|
||
kernel.o: kernel.c | ||
i386-elf-gcc -ffreestanding -c $< -o $@ | ||
|
||
# Rule to disassemble the kernel - may be useful to debug | ||
kernel.dis: kernel.bin | ||
ndisasm -b 32 $< > $@ | ||
|
||
bootsect.bin: bootsect.asm | ||
nasm $< -f bin -o $@ | ||
|
||
os-image.bin: bootsect.bin kernel.bin | ||
cat $^ > os-image.bin | ||
|
||
run: os-image.bin | ||
qemu-system-i386 -fda $< | ||
|
||
clean: | ||
rm *.bin *.o *.dis |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
*Concepts you may want to Google beforehand: kernel, ELF format, makefile* | ||
|
||
**Goal: Create a simple kernel and a bootsector capable of booting it** | ||
|
||
The kernel | ||
---------- | ||
|
||
Our C kernel will just print an 'X' on the top left corner of the screen. Go ahead | ||
and open `kernel.c`. | ||
|
||
You will notice a dummy function that does nothing. That function will force us | ||
to create a kernel entry routine which does not point to byte 0x0 in our kernel, but | ||
to an actual label which we know that launches it. In our case, function `main()`. | ||
|
||
`i386-elf-gcc -ffreestanding -c kernel.c -o kernel.o` | ||
|
||
That routine is coded on `kernel_entry.asm`. Read it and you will learn how to | ||
use `[extern]` declarations in assembly. To compile this file, instead of generating | ||
a binary, we will generate an `elf` format file which will be linked with `kernel.o` | ||
|
||
`nasm kernel_entry.asm -f elf -o kernel_entry.o` | ||
|
||
|
||
The linker | ||
---------- | ||
|
||
A linker is a very powerful tool and we only started to benefit from it. | ||
|
||
To link both object files into a single binary kernel and resolve label references, | ||
run: | ||
|
||
`i386-elf-ld -o kernel.bin -Ttext 0x1000 kernel_entry.o kernel.o --oformat binary` | ||
|
||
Notice how our kernel will be placed not at `0x0` in memory, but at `0x1000`. The | ||
bootsector will need to know this address too. | ||
|
||
|
||
The bootsector | ||
-------------- | ||
|
||
It is very similar to the one in lesson 10. Open `bootsect.asm` and examine the code. | ||
Actually, if you remove all the lines used to print messages on the screen, it accounts | ||
to a couple dozen lines. | ||
|
||
Compile it with `nasm bootsect.asm -f bin -o bootsect.bin` | ||
|
||
|
||
Putting it all together | ||
----------------------- | ||
|
||
Now what? We have two separate files for the bootsector and the kernel? | ||
|
||
Can't we just "link" them together into a single file? Yes, we can, and it's easy, | ||
just concatenate them: | ||
|
||
`cat bootsect.bin kernel.bin > os-image.bin` | ||
|
||
|
||
Run! | ||
---- | ||
|
||
You can now run `os-image.bin` with qemu. | ||
|
||
Remember that if you find disk load errors you may need to play with the disk numbers | ||
or qemu parameters (floppy = `0x0`, hdd = `0x80`). I usually use | ||
|
||
`qemu-system-i386 -fda os-image.bin` | ||
|
||
You will see four messages: | ||
|
||
- "Started in 16-bit Real Mode" | ||
- "Loading kernel into memory" | ||
- (Top left) "Landed in 32-bit Protected Mode" | ||
- (Top left, overwriting previous message) "X" | ||
|
||
Congratulations! | ||
|
||
|
||
Makefile | ||
-------- | ||
|
||
As a last step, we will tidy up the compilation process with a Makefile. Open the `Makefile` | ||
script and examine its contents. If you don't know what a Makefile is, now is a good time | ||
to Google and learn it, as this will save us a lot of time in the future. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
[org 0x7c00] | ||
KERNEL_OFFSET equ 0x1000 ; The same one we used when linking the kernel | ||
|
||
mov [BOOT_DRIVE], dl ; Remember that the BIOS sets us the boot drive in 'dl' on boot | ||
mov bp, 0x9000 | ||
mov sp, bp | ||
|
||
mov bx, MSG_REAL_MODE | ||
call print | ||
call print_nl | ||
|
||
call load_kernel ; read the kernel from disk | ||
call switch_to_pm ; disable interrupts, load GDT, etc. Finally jumps to 'BEGIN_PM' | ||
jmp $ ; Never executed | ||
|
||
%include "../05-bootsector-functions-strings/boot_sect_print.asm" | ||
%include "../05-bootsector-functions-strings/boot_sect_print_hex.asm" | ||
%include "../07-bootsector-disk/boot_sect_disk.asm" | ||
%include "../09-32bit-gdt/32bit-gdt.asm" | ||
%include "../08-32bit-print/32bit-print.asm" | ||
%include "../10-32bit-enter/32bit-switch.asm" | ||
|
||
[bits 16] | ||
load_kernel: | ||
mov bx, MSG_LOAD_KERNEL | ||
call print | ||
call print_nl | ||
|
||
mov bx, KERNEL_OFFSET ; Read from disk and store in 0x1000 | ||
mov dh, 2 | ||
mov dl, [BOOT_DRIVE] | ||
call disk_load | ||
ret | ||
|
||
[bits 32] | ||
BEGIN_PM: | ||
mov ebx, MSG_PROT_MODE | ||
call print_string_pm | ||
call KERNEL_OFFSET ; Give control to the kernel | ||
jmp $ ; Stay here when the kernel returns control to us (if ever) | ||
|
||
|
||
BOOT_DRIVE db 0 ; It is a good idea to store it in memory because 'dl' may get overwritten | ||
MSG_REAL_MODE db "Started in 16-bit Real Mode", 0 | ||
MSG_PROT_MODE db "Landed in 32-bit Protected Mode", 0 | ||
MSG_LOAD_KERNEL db "Loading kernel into memory", 0 | ||
|
||
; padding | ||
times 510 - ($-$$) db 0 | ||
dw 0xaa55 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/* This will force us to create a kernel entry function */ | ||
void dummy_test_entrypoint() { | ||
} | ||
|
||
void main() { | ||
char* video_memory = (char*) 0xb8000; | ||
*video_memory = 'X'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[bits 32] | ||
[extern main] ; Define calling point. Must haveSame name as kernel.c 'main' function | ||
call main ; Calls the C function. The linker will know where it is placed in memory | ||
jmp $ |