]> git.dujemihanovic.xyz Git - nameless-os.git/commitdiff
A new beginning
authorDuje Mihanović <duje.mihanovic@skole.hr>
Tue, 7 Sep 2021 09:25:40 +0000 (11:25 +0200)
committerDuje Mihanović <duje.mihanovic@skole.hr>
Tue, 7 Sep 2021 09:25:40 +0000 (11:25 +0200)
This boots into protected mode, prints a string from assembly and then prints an
A from a minimal C kernel.

.gitignore
Makefile
boot.s
kernel/entry.s [new file with mode: 0644]
kernel/kernel.c [new file with mode: 0644]
print.s [deleted file]

index 12ab2c11bd258a0abd8440e078d4790162de5bd6..735084c8287b5e626272343693f2acb91d2183bc 100644 (file)
@@ -1,2 +1,5 @@
 toolchain/
 boot
+boot.img
+kernel/kernel.bin
+kernel/*.o
index 9d95b1ef97134bcebc837fe4ab4cfab1e6fff45a..7001c99b6359d03cd4b26c934e903e2b0079e473 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,18 +1,26 @@
-AS = yasm # choose yasm or nasm here
-ASFLAGS = -f bin # compile a raw binary
+AS = yasm
+LD = i686-elf-ld
+CC = i686-elf-gcc
 
-boot: boot.s print.s
-       $(AS) $(ASFLAGS) -o $@ boot.s
+all: boot.img
 
-clean:
-       -rm boot
+boot.img: boot kernel/kernel.bin
+       cat boot kernel/kernel.bin > $@
+       truncate -s1440K $@
+
+boot: boot.s
+       $(AS) -f bin boot.s -o $@
+
+kernel/kernel.bin: kernel/entry.o kernel/kernel.o
+       $(LD) -o $@ -Ttext 0x1000 kernel/entry.o kernel/kernel.o --oformat=binary
 
-run:
-       qemu-system-i386 boot
+kernel/entry.o: kernel/entry.s
+       $(AS) -f elf kernel/entry.s -o $@
 
-help:
-       @echo "Run 'make' to compile."
-       @echo "Run 'make clean' to delete compiled objects."
-       @echo "Run 'make run' to run the compiled object. Must have qemu-system-i386 (but x86_64 should work too)."
+kernel/kernel.o: kernel/kernel.c
+       $(CC) -o $@ -ffreestanding -c kernel/kernel.c
+
+clean:
+       rm boot kernel/kernel.bin kernel/entry.o kernel/kernel.o boot.img
 
-.PHONY = clean run help
+.PHONY: all clean
diff --git a/boot.s b/boot.s
index 51be5d92dd8ee19426be4092d2aaed2c1e96f46d..a40b7508781e9dbc59b82587e003f2ccca6a21f8 100644 (file)
--- a/boot.s
+++ b/boot.s
-       bits 16 ; boot sectors run in real mode
-       org 7c00h ; boot sector is loaded at 0x7c00
+       bits 16
+       org 7C00h
 
-_start
-       mov di, printing_numbers
-       call print
+KERNEL_OFFSET equ 1000h
 
-       or bl, 1
-       mov dx, 0DEADh ; number to print
-       call print_word
+       mov [BOOT_DRIVE], dl
+
+       mov bp, 9000h
+       mov sp, bp
+
+       mov di, 0
+
+       xor ax, ax
+       int 13h
+       jc reset_error
+
+       mov ah, 2
+       mov al, 10
+       xor ch, ch
+       mov cl, 2
+       xor dh, dh
+       xor bx, bx
+       mov es, bx
+       mov bx, KERNEL_OFFSET
+       int 13h
+       jc read_error
+       cmp al, 10
+       jl read_error
+       jmp switch_to_pm
+
+reset_error
+       mov bx, 0B800h
+       mov es, bx
+       mov byte [es:di], '1'
+       jmp halt
+
+read_error
+       mov bx, 0B800h
+       mov es, bx
+       mov byte [es:di], '2'
+       jmp halt
+
+       call switch_to_pm
+
+halt
+       jmp $
+
+switch_to_pm
+       mov bx, 0B800h
+       mov es, bx
+       mov byte [es:0], 'L'
+
+       cli
+       xor ax, ax
+       mov ds, ax
+       lgdt [gdt_desc]
        
-       mov di, space
-       call print
+       mov eax, cr0
+       or eax, 1
+       mov cr0, eax
+       jmp CODE_SEG:protected
+
+       bits 32
+protected
+       mov ax, DATA_SEG
+       mov ds, ax
+       mov ss, ax
+       mov es, ax
+       mov fs, ax
+       mov gs, ax
        
-       xor bl, bl
-       mov dx, 0BEEFh
-       call print_word
+       mov ebp, 090000h
+       mov esp, ebp
 
-       mov di, waiting
-       call print
+       mov ebx, pm_success
+       call pmprint
 
-       mov di, keystroke
-       mov bl, 1
+       call KERNEL_OFFSET
 
-.loop
-       mov ah, 0
-       int 16h
-       cmp ah, 1Ch
-       je .enterpressed
-       jmp .continue
-       cmp ah, 0Eh
-       je .backspace
-       jmp .continue
-.enterpressed
+       jmp $
+
+pmprint
        pusha
-       mov ah, 0Eh
-       mov al, 0Dh
-       int 10h
-       mov al, 0Ah
-       int 10h
-       popa
+       mov edx, video_memory
+
+.loop
+       mov al, [ebx]
+       mov ah, 0Fh
+
+       cmp al, 0
+       je .done
+
+       mov [edx], al
+       mov [edx+1], ah
+
+       inc ebx
+       add edx, 2
+
        jmp .loop
-.backspace
-       pusha
-       mov ah, 03h
-       mov bh, 0
-       int 10h
-       dec dl
-       mov ah, 02h
-       int 10h
-       mov ah, 0Eh
-       mov al, ' '
-       int 10h
-       mov ah, 02h
-       int 10h
+
+.done
        popa
-       jmp .loop
-.continue
-       mov [keystroke], al
-       call print
-       jmp .loop
+       ret
+
+pm_success db "Now in protected mode", 0
+video_memory equ 0B8000h
 
-printing_numbers db "Printing some random hex numbers", 0
-waiting db "I await keystrokes", 0
-keystroke db "$", 0
-space db " ", 0
+gdt_start
+null_seg
+       dq 0
+code_seg
+       dw 0FFFFh
+       dw 0
+       db 0
+       db 10011010b
+       db 11001111b
+       db 0
+data_seg
+       dw 0FFFFh
+       dw 0
+       db 0
+       db 10010010b
+       db 11001111b
+       db 0
+gdt_end
+gdt_desc
+       dw gdt_end - gdt_start - 1
+       dd gdt_start
+CODE_SEG equ code_seg - gdt_start
+DATA_SEG equ data_seg - gdt_start
 
-%include "print.s"
+BOOT_DRIVE db 0
 
-       times 510-($-$$) db 0 ; fill with 0 until 0x1fc is reached
-       dw 0AA55h ; BIOS MBR signature
+       times 510-($-$$) db 0
+       dw 0AA55h
diff --git a/kernel/entry.s b/kernel/entry.s
new file mode 100644 (file)
index 0000000..236b81e
--- /dev/null
@@ -0,0 +1,5 @@
+       bits 32
+       extern _start
+
+       call _start
+       jmp $
diff --git a/kernel/kernel.c b/kernel/kernel.c
new file mode 100644 (file)
index 0000000..87fbef9
--- /dev/null
@@ -0,0 +1,5 @@
+void _start(void)
+{
+       char *video_memory = (char *) 0xB8000;
+       *video_memory = 'A';
+}
diff --git a/print.s b/print.s
deleted file mode 100644 (file)
index 3a46c72..0000000
--- a/print.s
+++ /dev/null
@@ -1,136 +0,0 @@
-%define CURRENT_ADDR cs:di
-
-; Prints a null terminated string of your choice.
-; Arguments:
-;     CS:DI - pointer to the string you want to print
-;     BL - 0 prints newline, otherwise no
-print
-       pusha
-       mov ah, 0Eh ; teletype print
-.write2
-       mov al, [CURRENT_ADDR] ; get current char and put it in al
-       cmp al, 0 ; check if al is null (string terminator)
-       je .newline ; if it is, start a new line
-       int 10h ; otherwise write the char
-       inc di ; increment pointer to string
-       jmp .write2 ; jump back to this section
-.newline
-       cmp bl, 1
-       je .done
-       mov al, 0Dh ; carriage return
-       int 10h
-       mov al, 0Ah ; line feed
-       int 10h
-.done
-       popa
-       ret ; return
-
-; Prints a word (16-bit value) in hex format.
-; Arguments:
-;     DX - word to print
-;     BL - 0 will print a newline, 1 won't
-print_word
-       pusha ; push all regs to stack
-       mov di, HEX_OUT+5 ; set destination index to last char in HEX_OUT
-       mov ax, dx ; copy argument to accumulator
-       and al, 00001111b ; extract the low nibble of the low half of the accumulator
-       call .compare ; fill in the string with correct value
-       dec di ; decrement string pointer
-       mov ax, dx ; copy argument to accumulator
-       and al, 11110000b ; extract high nibble of low half of accumulator
-       shr al, 4 ; shift high nibble to low nibble
-       call .compare ; fill in string with correct value
-       dec di
-       mov al, ah ; copy high portion of accumulator to low
-       and al, 00001111b ; 
-       call .compare
-       dec di
-       mov al, ah
-       and al, 11110000b
-       shr al, 4
-       call .compare
-       mov di, HEX_OUT
-       call print ; write string
-       popa
-       ret
-
-.compare
-       cmp al, 0 ; compare al with 0
-       jne .one ; if not equal, compare with 1
-       mov byte [CURRENT_ADDR], '0' ; set character to ASCII 0
-       ret ; return
-.one
-       cmp al, 1
-       jne .two
-       mov byte [CURRENT_ADDR], '1'
-       ret
-.two
-       cmp al, 2
-       jne .three
-       mov byte [CURRENT_ADDR], '2'
-       ret
-.three
-       cmp al, 3
-       jne .four
-       mov byte [CURRENT_ADDR], '3'
-       ret
-.four
-       cmp al, 4
-       jne .five
-       mov byte [CURRENT_ADDR], '4'
-       ret
-.five
-       cmp al, 5
-       jne .six
-       mov byte [CURRENT_ADDR], '5'
-       ret
-.six
-       cmp al, 6
-       jne .seven
-       mov byte [CURRENT_ADDR], '6'
-       ret
-.seven
-       cmp al, 7
-       jne .eight
-       mov byte [CURRENT_ADDR], '7'
-       ret
-.eight
-       cmp al, 8
-       jne .nine
-       mov byte [CURRENT_ADDR], '8'
-       ret
-.nine
-       cmp al, 9
-       jne .ten
-       mov byte [CURRENT_ADDR], '9'
-       ret
-.ten
-       cmp al, 0Ah
-       jne .eleven
-       mov byte [CURRENT_ADDR], 'A'
-       ret
-.eleven
-       cmp al, 0Bh
-       jne .twelve
-       mov byte [CURRENT_ADDR], 'B'
-       ret
-.twelve
-       cmp al, 0Ch
-       jne .thirteen
-       mov byte [CURRENT_ADDR], 'C'
-       ret
-.thirteen
-       cmp al, 0Dh
-       jne .fourteen
-       mov byte [CURRENT_ADDR], 'D'
-       ret
-.fourteen
-       cmp al, 0Eh
-       jne .fifteen
-       mov byte [CURRENT_ADDR], 'E'
-       ret
-.fifteen
-       mov byte [CURRENT_ADDR], 'F'
-       ret
-
-HEX_OUT db "0x0000", 0