diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e390b12 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/** \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9cf7e2f --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +ASM = nasm + +SRC = src +BUILD = build + +BOOTSTRAP_FILE = $(SRC)/bootstrap.asm +KERNEL_FILE = $(SRC)/simple_kernel.asm + +.PHONY: all build clean + +build: $(BOOTSTRAP_FILE) $(KERNEL_FILE) create_build_folder + $(ASM) -f bin $(BOOTSTRAP_FILE) -o $(BUILD)/bootstrap.o + $(ASM) -f bin $(KERNEL_FILE) -o $(BUILD)/kernel.o + dd if=$(BUILD)/bootstrap.o of=$(BUILD)/kernel.img + dd seek=1 conv=sync if=$(BUILD)/kernel.o of=$(BUILD)/kernel.img bs=512 + qemu-system-x86_64 -s $(BUILD)/kernel.img + +create_build_folder: + @mkdir -p build + +clean: + rm -f $(BUILD)/*.o $(BUILD)/*.img \ No newline at end of file diff --git a/README.md b/README.md index dfaeaf9..eda0ef1 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# MiniOS +# MiniOS \ No newline at end of file diff --git a/asset/v1.png b/asset/v1.png new file mode 100644 index 0000000..da2b465 Binary files /dev/null and b/asset/v1.png differ diff --git a/src/bootstrap.asm b/src/bootstrap.asm new file mode 100644 index 0000000..0155fc8 --- /dev/null +++ b/src/bootstrap.asm @@ -0,0 +1,102 @@ +; start indicates starting point of the execution +start: + ; we want to move 07C0h to ds (why? it will be explained in later segment) + ; we cannot mov ds, 0x08C0 directly because ds (segment register) cannot be loaded with value directly in x86 + ; further details: https://stackoverflow.com/questions/19074666/8086-why-cant-we-move-an-immediate-data-into-segment-register + mov ax, 07C0h + mov ds, ax + + ; define si to be title_string or message_string + ; call print_string which prints to screen the values saved in si + mov si, title_string + call print_string + + mov si, message_string + call print_string + + call load_kernel_from_disk + ; gives control to kernel by jumping to the start of the kernel + ; 0900h is the same value we have loaded in the register es in the beginning of load_kernel_from_disk + ; 0000 is the offset we have specified in the register bx in load_kernel_from_disk before calling 02h:13h + jmp 0900h:0000 + +load_kernel_from_disk: + mov ax, 0900h + mov es, ax + + ; service number 02h is specified to register ah + ; it reads sectors from the hard disk and loads them into the memory + mov ah, 02h + + ; 01h is the number of sector we ants to read (since simple_kernel.asm is < 512 bytes, 1 sector is enough) + mov al, 01h + + ; 0h is the track number we would like to read (track 0) + mov ch, 0h + + ; 02h is the sector number we would like to read (sector 2) + mov cl, 02h + + ; 0h is the head number (of the disk) + mov dh, 0h + + ; specifies the type of disk + ; 0h means floppy disk, 80h means hard disk #0, 81h means hard disk #1, etc. + mov dl, 80h + + ; the value of bx is the memory address that the content will be loaded into + ; we are reading one sector and the content will be stored on memory address 0h + mov bx, 0h + int 13h + + ; when the content is loaded successfully, BIOS service 13h:02h set carry flag to 0, otherwise 1 and stores error code in ax + ; if cf is 1 jc will jump + jc load_kernel_from_disk + + ret + +kernel_load_error: + mov si, load_error_string + call print_string + + jmp $ + +print_string: + ; specify function for printing character + mov ah, 0Eh + +print_char: + ; char to print is passed via si + ; lodsb will transfer first character of the string to the register al and increase value of si by 1 byte + lodsb + + cmp al, 0 + je printing_finished + + int 10h + + jmp print_char + +printing_finished: + mov al, 10d ; print new line 10d = ENDL + int 10h + + ; reading current cursor position + mov ah, 03h ; specify service for reading current position of cursor + mov bh, 0 + int 10h + + ; move the cursor to the beginning + mov ah, 02h ; specify service for setting cursor to position 0 + mov dl, 0 ; position to be set is passed to dl + int 10h + + ret + +title_string db 'The Bootloader of MiniOS Kernel.', 0 +message_string db 'The Kernel is loading...', 0 +load_error_string db 'The Kernel cannot be loaded', 0 + +; write the magic signature 0xAA55 +times 510-($-$$) db 0 ; pad with 0 so magic signature is at loc 510-511 (0-based) +dw 0xAA55 \ No newline at end of file diff --git a/src/simple_kernel.asm b/src/simple_kernel.asm new file mode 100644 index 0000000..5d2dd2d --- /dev/null +++ b/src/simple_kernel.asm @@ -0,0 +1,25 @@ +start: + mov ax, cs + mov ds, ax + + mov si, hello_string + call print_string + jmp $ + +print_string: + mov ah, 0Eh + +print_char: + lodsb + + cmp al, 0 + je done + + int 10h + + jmp print_char + +done: + ret + +hello_string db 'MiniOS says "Hello World!"', 0 \ No newline at end of file