-
Notifications
You must be signed in to change notification settings - Fork 1
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
0 parents
commit 4a3be59
Showing
27 changed files
with
1,650 additions
and
0 deletions.
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 |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# Prerequisites | ||
*.d | ||
|
||
# Object files | ||
*.o | ||
*.ko | ||
*.obj | ||
*.elf | ||
|
||
# Linker output | ||
*.ilk | ||
*.map | ||
*.exp | ||
|
||
# Precompiled Headers | ||
*.gch | ||
*.pch | ||
|
||
# Libraries | ||
*.lib | ||
*.a | ||
*.la | ||
*.lo | ||
|
||
# Shared objects (inc. Windows DLLs) | ||
*.dll | ||
*.so | ||
*.so.* | ||
*.dylib | ||
|
||
# Executables | ||
*.exe | ||
*.out | ||
*.bin | ||
*.app | ||
*.i*86 | ||
*.x86_64 | ||
*.hex | ||
|
||
# Debug files | ||
*.dSYM/ | ||
*.su | ||
*.idb | ||
*.pdb | ||
|
||
# Kernel Module Compile Results | ||
*.mod* | ||
*.cmd | ||
.tmp_versions/ | ||
modules.order | ||
Module.symvers | ||
Mkfile.old | ||
dkms.conf | ||
|
||
# Visual Studio Code | ||
.vscode/ |
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,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2022 bemxio | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
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,34 @@ | ||
SOURCES = $(wildcard kernel/*.c drivers/*.c cpu/*.c) | ||
HEADERS = $(wildcard kernel/*.h drivers/*.h cpu/*.h) | ||
OBJECTS = ${SOURCES:.c=.o cpu/interrupt.o} | ||
|
||
bemxOS.bin: boot/bootloader.bin kernel.bin | ||
cat $^ > bemxOS.bin | ||
|
||
kernel.bin: kernel/entry_point.o ${OBJECTS} | ||
"${CC_PATH}/i386-elf-ld" -Ttext 0x1000 --oformat binary $^ -o $@ | ||
|
||
# for debugging | ||
kernel.elf: kernel/entry_point.o ${OBJECTS} | ||
"${CC_PATH}/i386-elf-ld" -Ttext 0x1000 $^ -o $@ | ||
|
||
run: bemxOS.bin | ||
"${QEMU_PATH}/qemu-system-i386.exe" -fda bemxOS.bin | ||
|
||
debug: bemxOS.bin kernel.elf | ||
"${QEMU_PATH}/qemu-system-i386.exe" -s -fda bemxOS.bin & | ||
"${GDB_PATH}" -ex "target remote localhost:1234" -ex "symbol-file kernel.elf" | ||
|
||
# generic rules for wildcards | ||
%.o: %.c ${HEADERS} | ||
"${CC_PATH}/i386-elf-gcc" -g -ffreestanding -c $< -o $@ | ||
|
||
%.o: %.asm | ||
nasm $< -f elf -o $@ | ||
|
||
%.bin: %.asm | ||
nasm $< -f bin -o $@ | ||
|
||
clean: | ||
rm -rf *.bin *.o *.elf | ||
rm -rf kernel/*.o boot/*.bin drivers/*.o boot/*.o cpu/*.o |
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,46 @@ | ||
# bemxOS | ||
bemxOS (pronounced "bemsh-OS" but people pronounce it wrongly as "bem-x-OS" and other people get to be pedantic and correct those people) is a little operating system created by me (bemxio!), just for learning OS development. | ||
|
||
Based on [this](https://github.com/cfenollosa/os-tutorial) cool tutorial. If you want to make your own OS, you should follow that tutorial too! | ||
|
||
I plan to add network support and all of the other cool stuff later on, don't expect it soon though. | ||
For now, it will probably just have a few basic commands with a basic filesystem as well. | ||
|
||
## Running | ||
As it seems, the system only works on QEMU, however I plan to look at the issues with VirtualBox and VMware. | ||
|
||
Just simply run the `bemxOS.bin` file within the command line with the following command: | ||
``` | ||
qemu-system-i386 -fda bemxOS.bin | ||
``` | ||
|
||
## Building | ||
You will need some prerequisites before you start compiling the system: | ||
|
||
- a Linux host system (if you are on Windows, WSL will do the job) | ||
- a GCC cross-compiler (feel free to follow [this](https://github.com/cfenollosa/os-tutorial/blob/master/11-kernel-crosscompiler/README.md) tutorial for steps on how to compile one yourself) | ||
- (optionally) GCC, for debugging | ||
- (optionally) QEMU, for testing & debugging the system | ||
|
||
1. Export some global environment variables: | ||
- `CC_PATH`, that points to the directory path of your cross-compiler. | ||
- (optionally) `QEMU_PATH`, that points to the QEMU directory. (for Windows peeps, install QEMU on Windows and point to it in WSL, where `/mnt\/c/` is `C:\`) | ||
- (optionally) `GDB_PATH`, that points to the GDB **executable**. (for Windows peeps, it's the same as with QEMU) | ||
|
||
2. Clone the repository using `git`, and use `cd` to change the current directory. | ||
|
||
3. Just run the `make` command, and it should work! | ||
|
||
It should produce a `bemxOS.bin` file at the end, that you can launch with QEMU. | ||
|
||
If you want to clean all of the mess the compilers made, you can run `make clean` to quickly get rid of all of the files. | ||
|
||
### Debugging | ||
If you set up the `QEMU_PATH` and `GDB_PATH` environment variables, you can use `make debug` to compile the code and run it inside of a debugging session in GDB. | ||
|
||
You can also do `make run`, if you just want to run it, although you still need `QEMU_PATH` to be set up. | ||
|
||
## Contributions | ||
Feel free to point out any mistakes or issues you've found while using this little thing! | ||
|
||
Anything from a simple question to a pull request is really appreciated! |
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,53 @@ | ||
[org 0x7c00] ; bootloader offset | ||
KERNEL_OFFSET equ 0x1000 ; the same one used when linking the kernel | ||
|
||
mov bp, 0x9000 ; set the stack | ||
mov sp, bp | ||
|
||
mov bx, MSG_REAL_MODE | ||
call println ; this will be written after the BIOS messages | ||
|
||
call load_kernel ; read the kernel from the disk | ||
call switch_to_pm ; disable interrupts, load GDT, etc. | ||
jmp $ ; this will actually never be executed | ||
|
||
; printing functions | ||
%include "boot/functions/print.asm" | ||
%include "boot/functions/print32.asm" | ||
%include "boot/functions/print_hex.asm" | ||
|
||
; other needed functions for loading the kernel | ||
%include "boot/functions/disk.asm" | ||
%include "boot/functions/gdt.asm" | ||
%include "boot/functions/switch_pm.asm" | ||
|
||
[bits 16] | ||
load_kernel: | ||
mov bx, MSG_LOAD_KERNEL | ||
call println | ||
|
||
mov bx, KERNEL_OFFSET ; read from disk and store in 0x1000 | ||
mov dh, 32 ; number of sectors to read (make sure to expand it when the kernel code gets big) | ||
mov dl, [BOOT_DRIVE] | ||
|
||
call disk_load | ||
ret | ||
|
||
[bits 32] | ||
BEGIN_PM: ; after the switch we will get here | ||
mov ebx, MSG_PROT_MODE | ||
call print32 ; note that this will be written at the top left corner | ||
call KERNEL_OFFSET ; give control to the kernel | ||
jmp $ ; stay here when the kernel returns control to us (if ever) | ||
|
||
; constants | ||
MSG_REAL_MODE db "Started in 16-bit real mode", 0 | ||
MSG_PROT_MODE db "Loaded 32-bit protected mode", 0 | ||
MSG_LOAD_KERNEL db "Loading kernel into memory...", 0 | ||
|
||
BOOT_DRIVE db 0 | ||
|
||
; padding & magic number | ||
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,36 @@ | ||
disk_load: | ||
pusha | ||
push dx | ||
|
||
mov ah, 0x02 ; an 'int 0x13' function for reading stuff | ||
mov al, dh ; number of sectors to read | ||
|
||
mov cl, 0x02 ; sector (0x02 is the first 'available' sector) | ||
mov ch, 0x00 ; cylinder (from 0x0 to 0x3FF) | ||
mov dh, 0x00 ; head number (from 0x0 to 0xF) | ||
|
||
int 0x13 ; BIOS interrupt | ||
jc disk_error ; if something bad happened | ||
|
||
pop dx | ||
cmp al, dh | ||
jne sector_error ; if al (number of sectors that got read) is not equal to dh (number of sectors to read) | ||
|
||
popa | ||
ret | ||
|
||
disk_error: | ||
mov bx, DISK_ERROR | ||
call println | ||
|
||
mov dh, ah ; ah is the error code, dl is the disk drive that raised the error | ||
call print_hex | ||
|
||
hlt | ||
|
||
sector_error: | ||
mov bx, SECTOR_ERROR | ||
call print | ||
|
||
DISK_ERROR: db "Disk read error", 0 | ||
SECTOR_ERROR: db "Incorrect number of sectors read", 0 |
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,35 @@ | ||
gdt_start: ; the GDT starts with a null 8-byte | ||
dd 0x0 | ||
dd 0x0 | ||
|
||
gdt_code: | ||
dw 0xffff ; segment length, bits 0-15 | ||
|
||
dw 0x0 ; segment base, bits 0-15 | ||
db 0x0 ; segment base, bits 16-23 | ||
db 10011010b ; flags (8 bits) | ||
db 11001111b ; flags (4 bits) + segment length, bits 16-19 | ||
db 0x0 ; segment base, bits 24-31 | ||
|
||
gdt_data: ; base and length identical to code segment | ||
dw 0xffff | ||
dw 0x0 | ||
db 0x0 | ||
db 10010010b | ||
db 11001111b | ||
db 0x0 | ||
|
||
gdt_end: | ||
|
||
gdt_descriptor: | ||
dw gdt_end - gdt_start - 1 ; size (16 bit), always one less of its true size | ||
dd gdt_start ; address (32 bit) | ||
|
||
; constants | ||
CODE_SEG equ gdt_code - gdt_start | ||
DATA_SEG equ gdt_data - gdt_start |
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,35 @@ | ||
print: | ||
pusha | ||
|
||
print_loop: ; the comparison for string end (null byte) | ||
mov al, [bx] ; 'bx' is the base address for the string | ||
cmp al, 0 | ||
je print_end ; if 'al' is the null byte | ||
|
||
mov ah, 0x0e | ||
int 0x10 ; 'al' already contains the char | ||
|
||
; increment pointer and loop | ||
add bx, 1 | ||
jmp print_loop | ||
|
||
print_end: | ||
popa | ||
ret | ||
|
||
print_newline: | ||
pusha | ||
mov ah, 0x0e | ||
mov al, 0x0a ; newline character | ||
int 0x10 | ||
mov al, 0x0d ; carriage return | ||
int 0x10 | ||
popa | ||
ret | ||
|
||
println: | ||
call print | ||
call print_newline |
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,26 @@ | ||
[bits 32] ; using 32-bit protected mode | ||
|
||
; constants | ||
VIDEO_MEMORY equ 0xb8000 | ||
WHITE_ON_BLACK equ 0x0f ; the color byte for each character | ||
|
||
print32: | ||
pusha | ||
mov edx, VIDEO_MEMORY | ||
|
||
print32_loop: | ||
mov al, [ebx] ; [ebx] is the address of our character | ||
mov ah, WHITE_ON_BLACK | ||
|
||
cmp al, 0 ; check for the null byte | ||
je print32_end | ||
|
||
mov [edx], ax ; store character + attribute in video memory | ||
add ebx, 1 ; next char | ||
add edx, 2 ; next video memory position | ||
|
||
jmp print32_loop | ||
|
||
print32_end: | ||
popa | ||
ret |
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,37 @@ | ||
print_hex: ; we'll assume that it's called with dx = 0x1234 | ||
pusha | ||
mov cx, 0 ; the index variable | ||
|
||
step1: ; convert last char of 'dx' to ascii | ||
cmp cx, 4 ; loop 4 times | ||
je end | ||
|
||
mov ax, dx | ||
and ax, 0x000f ; 0x1234 -> 0x0004 by masking first three to zeros | ||
add al, 0x30 ; add 0x30 to N to convert it to ASCII "N" | ||
|
||
cmp al, 0x39 ; if > 9, add extra 8 to represent 'A' to 'F' | ||
jle step2 | ||
add al, 7 ; 'A' is ASCII 65 instead of 58, so 65 - 58 = 7 | ||
|
||
step2: ; get the correct position of the string to place the ASCII char | ||
mov bx, HEX_OUT + 5 ; base + length | ||
sub bx, cx ; the index variable yet again | ||
|
||
mov [bx], al ; copy the ASCII char on 'al' to the position pointed by 'bx' | ||
ror dx, 4 ; 0x1234 -> 0x4123 -> 0x3412 -> 0x2341 -> 0x1234 | ||
; increment index and loop | ||
add cx, 1 | ||
jmp step1 | ||
|
||
end: ; prepare the parameter and call the function | ||
mov bx, HEX_OUT ; remember that print receives parameters in 'bx' | ||
call print | ||
|
||
popa | ||
ret | ||
|
||
HEX_OUT: | ||
db "0x0000", 0 |
Oops, something went wrong.