diff --git a/Comp Arch.pdf b/Comp Arch.pdf new file mode 100644 index 0000000..a3e5bd4 Binary files /dev/null and b/Comp Arch.pdf differ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d300f8f --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +all: run +kernel.bin: kernelEntry.o kernel.o + i386-elf-ld -o $@ -Ttext 0x1000 $^ --oformat binary + +kernelEntry.o: kernelEntry.asm + nasm $< -f elf -o $@ + +kernel.o: kernel.c + i386-elf-gcc -ffreestanding -c $< -o $@ + +bootSector.bin: bootSector.asm + nasm $< -f bin -o $@ + +final.bin: bootSector.bin kernel.bin + cat $^ > final.bin + +run: final.bin + qemu-system-i386 -fda $< + +clean: + rm -rf *.bin *.o + diff --git a/Project_Proposal.pdf b/Project_Proposal.pdf new file mode 100644 index 0000000..8e2289a Binary files /dev/null and b/Project_Proposal.pdf differ diff --git a/Project_Proposal_Revised.pdf b/Project_Proposal_Revised.pdf new file mode 100644 index 0000000..cedba91 Binary files /dev/null and b/Project_Proposal_Revised.pdf differ diff --git a/Screen Shot 2017-12-12 at 12.43.31 AM.png b/Screen Shot 2017-12-12 at 12.43.31 AM.png new file mode 100644 index 0000000..c32eaf3 Binary files /dev/null and b/Screen Shot 2017-12-12 at 12.43.31 AM.png differ diff --git a/Work_Plan.pdf b/Work_Plan.pdf new file mode 100644 index 0000000..88c9d9e Binary files /dev/null and b/Work_Plan.pdf differ diff --git a/boot.asm b/boot.asm new file mode 100644 index 0000000..bf1bac5 --- /dev/null +++ b/boot.asm @@ -0,0 +1,4 @@ +loop: + jmp loop +times 510-($-$$) db 0 +dw 0xaa55 diff --git a/bootSector.asm b/bootSector.asm new file mode 100644 index 0000000..2b6c1b5 --- /dev/null +++ b/bootSector.asm @@ -0,0 +1,48 @@ +[org 0x7c00] + +KERNEL_OFFSET equ 0x1000 + + mov [BOOT_DRIVE], dl ; BIOS sets boot drive + mov bp, 0x9000 + mov sp, bp + + mov bx, REAL_MODE + call print + call print_nl ; Print + + call load_kernel ; Read kernel from disk + call switch_pmode ; Begin protected mode + jmp $ ; Never run but holds + +%include "bootSectorPrint.asm" +%include "bootSectorPrintHex.asm" +%include "bootSectorDisk.asm" +%include "gdt.asm" +%include "print.asm" +%include "enter32.asm" + +[bits 16] +load_kernel: + mov bx, LOAD_KERNEL + call print + call print_nl + mov bx, KERNEL_OFFSET ; Read from disk + mov dh, 2 + mov dl, [BOOT_DRIVE] + call disk_load + ret + +[bits 32] +BEGIN_PMODE: + mov ebx, PROTECTED_MODE + call print_pmode ; Print + call KERNEL_OFFSET ; Give kernel control + jmp $ ; Gain control from Kernel + +BOOT_DRIVE db 0 +REAL_MODE db "Real Mode", 0 +PROTECTED_MODE db "Protected Mode", 0 +LOAD_KERNEL db "Loading Kernel into Memory", 0 + +times 510 - ($-$$) db 0 ; Padding +dw 0xaa55 diff --git a/bootSectorDisk.asm b/bootSectorDisk.asm new file mode 100644 index 0000000..7991f00 --- /dev/null +++ b/bootSectorDisk.asm @@ -0,0 +1,33 @@ +disk_load: + pusha ; Push all general purpose registers onto the stack + push dx ; Save dx + mov ah, 0x02 ; Read + mov al, dh ; Number of sectors to read + mov cl, 0x02 ; Sector + mov ch, 0x00 ; Cylinder + mov dh, 0x00 ; Head + int 0x13 ; Interrupt vector (Low Level Disk Services) + jc disk_error ; Jump + pop dx ; Load dx from stack + cmp al, dh ; Compare with BIOS + jne sector_error ; Jump + popa ; Pop all general purpose registers off the stack + ret + +disk_error: + mov bx, DISK_ERROR ; Get string to print + call print ; Print error + call print_nl ; Print new line + mov dh, ah ; Error code and disk + call print_hex ; Call function + jmp disk_loop ; Jump + +sector_error: + mov bx, SECTOR_ERROR + call print ; Print + +disk_loop: + jmp $ + +DISK_ERROR: db "ERROR: Could not read disk.", 0 +SECTOR_ERROR: db "ERROR: Incorrect number of sectors.", 0 diff --git a/bootSectorPrint.asm b/bootSectorPrint.asm new file mode 100644 index 0000000..fde3acc --- /dev/null +++ b/bootSectorPrint.asm @@ -0,0 +1,25 @@ +print: + pusha ; Push all general purpose registers onto the stack + +start: + mov al, [bx] ; Base address of the string + cmp al, 0 ; If '0' we are at end of string + je done ; Break loop + mov ah, 0x0e ; BIOS interrupt + int 0x10 ; Interrupt vector (Video Services) + add bx, 1 ; Add 1 + jmp start ; Loop + +done: + popa ; Pop all general purpose registers off the stack + ret + +print_nl: + pusha + mov ah, 0x0e + mov al, 0x0a ; Newline + int 0x10 + mov al, 0x0d ; Return + int 0x10 + popa + ret diff --git a/bootSectorPrintHex.asm b/bootSectorPrintHex.asm new file mode 100644 index 0000000..317b9c3 --- /dev/null +++ b/bootSectorPrintHex.asm @@ -0,0 +1,31 @@ +print_hex: + pusha ; Push all general purpose registers onto the stack + mov cx, 0 ; Index + +hex_loop: + cmp cx, 4 ; Loop four times + je end ; Break loop + + mov ax, dx ; Last char of 'dx' + and ax, 0x000f ; Get least signifigant + add al, 0x30 ; Convert 0-9 to ASCII + cmp al, 0x39 ; Check if A-F + jle pos ; Jump if 'al' =< 0x39 + add al, 7 ; Convert A-F to ASCII + +pos: + mov bx, HEX + 5 ; Base address + length + sub bx, cx ; Subtract index + mov [bx], al ; Move char to position [bx] + ror dx, 4 ; Rotate 4 bits to right + add cx, 1 ; Index + 1 + jmp hex_loop ; Loop + +end: + mov bx, HEX + call print ; Print + popa ; Pop all general purpose registers off the stack + ret + +HEX: + db '0x0000',0 ; Reserve memory diff --git a/enter32.asm b/enter32.asm new file mode 100644 index 0000000..57c43aa --- /dev/null +++ b/enter32.asm @@ -0,0 +1,24 @@ +[bits 16] ; 16-bit Real Mode + +switch_pmode: + cli ; Disable interrupts + lgdt [gdt_desc] ; Load GDT + mov eax, cr0 + or eax, 0x1 ; Set 32-bit mode bit high + mov cr0, eax + jmp CODE_SEGMENT:init_pmode + +[bits 32] ; 32-bit Protected Mode + +init_pmode: + mov ax, DATA_SEGMENT ; Set data segment registers + mov ds, ax + mov ss, ax + mov es, ax + mov fs, ax + mov gs, ax + + mov ebp, 0x90000 + mov esp, ebp + + call BEGIN_PMODE diff --git a/gdt.asm b/gdt.asm new file mode 100644 index 0000000..b278f03 --- /dev/null +++ b/gdt.asm @@ -0,0 +1,28 @@ +gdt_init: + dd 0x0 ; 4 byte + dd 0x0 ; 4 byte + +gdt_info: + dw 0xffff ; Segment length + dw 0x0 ; Segment base + db 0x0 ; Segment base + db 10011010b ; Flags + db 11001111b ; Flags & segment length + db 0x0 ; Segment base + +gdt_data: + dw 0xffff + dw 0x0 + db 0x0 + db 10010010b + db 11001111b + db 0x0 + +gdt_end: + +gdt_desc: + dw gdt_end - gdt_init - 1 + dd gdt_init + +CODE_SEGMENT equ gdt_info - gdt_init +DATA_SEGMENT equ gdt_data - gdt_init diff --git a/kernel.c b/kernel.c new file mode 100644 index 0000000..08cd42c --- /dev/null +++ b/kernel.c @@ -0,0 +1,36 @@ +void main(void) +{ + // Message we want to print + const char *string = "Welcome Kernel!"; + + // Pointer to start of video memory + char *videoMemory = (char*)0xb8000; + + // Loop index + unsigned int i = 0; + unsigned int j = 0; + + // Clear screen + while(j < 80 * 2) { + videoMemory[j] = ' '; + + // Color + videoMemory[j+1] = 0x07; + j = j + 2; + } + + + // Reset Counter + j = 0; + + // Print string to screen + while(string[j] != '\0') { + videoMemory[i] = string[j]; + + // Color + videoMemory[i+1] = 0x0f; + ++j; + i = i + 2; + } + return; +} diff --git a/kernelEntry.asm b/kernelEntry.asm new file mode 100644 index 0000000..9bfdbe0 --- /dev/null +++ b/kernelEntry.asm @@ -0,0 +1,4 @@ +[bits 32] +[extern main] ; Calling point +call main ; Call 'main' in Kernel.c +jmp $ diff --git a/print.asm b/print.asm new file mode 100644 index 0000000..3988849 --- /dev/null +++ b/print.asm @@ -0,0 +1,24 @@ +[bits 32] ; 32-bit protected mode + +VIDEO_MEMORY equ 0xb8000 ; Video memory address +COLOR equ 0x0f ; Text color + +print_pmode: + pusha ; Push all general purpose registers onto the stack + mov edx, VIDEO_MEMORY ; Set initial address + +print_pmode_loop: + mov al, [ebx] ; Move color address + mov ah, COLOR + + cmp al, 0 ; End of string + je print_pmode_end ; Jump + + mov [edx], ax ; Store char and color + add ebx, 1 ; Next char + add edx, 2 ; Next video memory address position + jmp print_pmode_loop ; Jump + +print_pmode_end: + popa ; Pop all general purpose registers off the stack + ret