Skip to content

Commit

Permalink
add all of the project's files
Browse files Browse the repository at this point in the history
  • Loading branch information
bemxio committed Jul 13, 2022
0 parents commit 4a3be59
Show file tree
Hide file tree
Showing 27 changed files with 1,650 additions and 0 deletions.
56 changes: 56 additions & 0 deletions .gitignore
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/
21 changes: 21 additions & 0 deletions LICENSE
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.
34 changes: 34 additions & 0 deletions Makefile
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
46 changes: 46 additions & 0 deletions README.md
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!
53 changes: 53 additions & 0 deletions boot/bootloader.asm
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
36 changes: 36 additions & 0 deletions boot/functions/disk.asm
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
35 changes: 35 additions & 0 deletions boot/functions/gdt.asm
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
35 changes: 35 additions & 0 deletions boot/functions/print.asm
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
26 changes: 26 additions & 0 deletions boot/functions/print32.asm
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
37 changes: 37 additions & 0 deletions boot/functions/print_hex.asm
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
Loading

0 comments on commit 4a3be59

Please sign in to comment.