summaryrefslogtreecommitdiff
path: root/boot/mbr.asm
diff options
context:
space:
mode:
authorMichal Idziorek <m.i@gmx.at>2014-06-24 13:53:31 +0200
committerMichal Idziorek <m.i@gmx.at>2014-06-24 13:53:31 +0200
commita99ca43066ba246475809a0e805bf52e8195debd (patch)
tree1883030e358c15231599160ff1ce027b0cc20d22 /boot/mbr.asm
Initial commit of FoolOS
FoolOS - the most useless OS in history.
Diffstat (limited to 'boot/mbr.asm')
-rw-r--r--boot/mbr.asm255
1 files changed, 255 insertions, 0 deletions
diff --git a/boot/mbr.asm b/boot/mbr.asm
new file mode 100644
index 0000000..41568c4
--- /dev/null
+++ b/boot/mbr.asm
@@ -0,0 +1,255 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; FoolOS Boot Loader
+;
+; Copyright 2014 M.Idziorek <m.i@gmx.at>
+;
+; we have just been loaded by the BIOS and are in 16-bits real mode!
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;we want 16-bit instructions, before we switch to 32-bit protected mode.
+[bits 16]
+
+;define origin of boot record in memory: 0x7c00
+;this is where the BIOS per definition will put the first
+;512 bytes of data from the boot device
+;The Boot record is identified by the last 2 magic bytes: 0xaa55 (?)
+[org 0x7c00]
+
+;define where we will load our kernel into memory
+KERNEL_OFFSET equ 0x1000
+
+jmp boot_16 ;start boot process
+
+;Global Data
+INT_COUNT:
+ db 0
+STR_VERSION:
+ db "_<-Fool-Loader~0.0.8~",0
+STR_PROT:
+ db "Entered 32-bit Protected Mode.",0
+STR_LOADED:
+ db "FoolOS Kernel Loaded.",0
+BOOT_DRIVE:
+ db 0
+
+[bits 32]
+; default interrupt handler
+interrupt:
+
+ mov al, 0xA0 ; set bit 4 of OCW 2
+ out 0xA0, al ; write to primary PIC command register
+
+ mov al, 0x20 ; set bit 4 of OCW 2
+ out 0x20, al ; write to primary PIC command register
+
+ iret
+
+;handle keyboard interrupt
+interrupt2:
+
+
+; mov eax,[INT_COUNT]
+; inc eax
+; mov [INT_COUNT],eax
+
+ in al,0x60
+ mov [INT_COUNT],al
+
+; call KERNEL_OFFSET+(idt_end-idt_start)+1 ;jump into our Kernel it
+
+ ; will follow our
+ ; interrupt table
+
+ ; out 0x60,al
+
+
+ mov al, 0x20 ; set bit 4 of OCW 2
+ out 0x20, al ; write to primary PIC command register
+
+ iret
+
+;lets put our temporary GDT (Global Descriptor Table) here
+%include "boot/GDT.asm"
+
+;include 16-bit real mode routines (print_string, print_hex, disk_load)
+%include "boot/common.asm"
+
+;include 32-bit Protected Mode routines (print_string_pm,print_hex_pm)
+%include "boot/common_pm.asm"
+
+;include our routines for switching to 32-bit protected mode
+%include "boot/pm.asm"
+
+;;;;;;;; BOOT 16-bit real ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;lets start
+[bits 16]
+boot_16:
+
+ ;setup the stack
+ mov bp,0x8000
+ mov sp,bp
+
+ ;remember BOOT_DRIVE (as was set by BIOS)
+ mov [BOOT_DRIVE],dl
+
+ ;print FoolOS version info
+ mov bx, STR_VERSION
+ call print_string
+
+ ;Load the KERNEL
+ mov bx,KERNEL_OFFSET
+ mov dh, 15
+ mov dl, [BOOT_DRIVE]
+ call disk_load
+
+ mov bx, STR_LOADED
+ call print_string
+
+ ;lets enter Protected mode!
+ call switch_to_pm
+
+;;;;;;;; BOOT 32-bit protected mode;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+[bits 32]
+boot_32_pm:
+
+ mov ecx,160
+ mov ebx,STR_PROT
+ call print_string_pm
+
+ ;enable A20
+ ;http://www.brokenthorn.com/Resources/OSDev9.html
+ ;Method 3.1: Enables A20 through keyboard controller
+ mov al, 0xdd ; command 0xdd: enable a20
+ out 0x64, al ; send command to controller
+
+ lidt [idt_descriptor] ;load descriptor table!
+
+ ;pollkb example
+; pollkb:
+; mov cx,320
+; mov ax,0
+; in al,0x60
+; mov dx,ax
+; call print_hex_pm
+; jmp pollkb
+;
+ ;mov al,11111101b
+ ;out 0x61, al
+
+
+ sti ;enable interrupts
+
+;************************************************************************
+; Map the 8259A PIC to use interrupts 32-47 within our interrupt table
+;************************************************************************
+
+%define ICW_1 0x11 ; 00010001 binary. Enables initialization mode and we are sending ICW 4
+
+%define PIC_1_CTRL 0x20 ; Primary PIC control register
+%define PIC_2_CTRL 0xA0 ; Secondary PIC control register
+
+%define PIC_1_DATA 0x21 ; Primary PIC data register
+%define PIC_2_DATA 0xA1 ; Secondary PIC data register
+
+%define IRQ_0 0x20 ; IRQs 0-7 mapped to use interrupts 0x20-0x27
+%define IRQ_8 0x28 ; IRQs 8-15 mapped to use interrupts 0x28-0x36
+
+MapPIC:
+
+; Send ICW 1 - Begin initialization -------------------------
+
+ ; Setup to initialize the primary PIC. Send ICW 1
+
+ mov al, ICW_1
+ out PIC_1_CTRL, al
+
+; Send ICW 2 - Map IRQ base interrupt numbers ---------------
+
+ ; Remember that we have 2 PICs. Because we are cascading with this second PIC, send ICW 1 to second PIC command register
+
+ out PIC_2_CTRL, al
+
+ ; send ICW 2 to primary PIC
+
+ mov al, IRQ_0
+ out PIC_1_DATA, al
+
+ ; send ICW 2 to secondary controller
+
+ mov al, IRQ_8
+ out PIC_2_DATA, al
+
+; Send ICW 3 - Set the IR line to connect both PICs ---------
+
+ ; Send ICW 3 to primary PIC
+
+ mov al, 0x4 ; 0x04 => 0100, second bit (IR line 2)
+ out PIC_1_DATA, al ; write to data register of primary PIC
+
+ ; Send ICW 3 to secondary PIC
+
+ mov al, 0x2 ; 010=> IR line 2
+ out PIC_2_DATA, al ; write to data register of secondary PIC
+
+; Send ICW 4 - Set x86 mode --------------------------------
+
+ mov al, 1 ; bit 0 enables 80x86 mode
+
+ ; send ICW 4 to both primary and secondary PICs
+
+ out PIC_1_DATA, al
+ out PIC_2_DATA, al
+
+; All done. Null out the data registers
+
+ mov al, 0
+ out PIC_1_DATA, al
+ out PIC_2_DATA, al
+
+ ;mask
+in al, 0x21 ; read in the primary PIC Interrupt Mask Register (IMR)
+and al, 0x00 ; 0xEF => 11101111b. This sets the IRQ4 bit (Bit 5) in AL
+out 0x21, al ; write the value back into IMR
+
+
+in al, 0xA1 ; read in the primary PIC Interrupt Mask Register (IMR)
+and al, 0x00 ; 0xEF => 11101111b. This sets the IRQ4 bit (Bit 5) in AL
+out 0xA1, al ; write the value back into IMR
+
+
+
+ call KERNEL_OFFSET+(idt_end-idt_start) ;jump into our Kernel it
+ ; will follow our
+ ; interrupt table
+
+idt_descriptor:
+ dw idt_end-idt_start-1
+ dd KERNEL_OFFSET
+
+
+;;;; DEBUGGING STUFF
+times 8 db '@'
+dw interrupt
+db '@'
+dw interrupt2
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;so we get identified as MBR
+times 510-($-$$) db 0
+dw 0xaa55
+
+;interrupt descriptor table (hardcoded address of interrupts:)
+idt_start:
+times 33 db 0x50,0x7c,0x08,0x00,0x00,10001110b,0x0,0x0
+db 0x59,0x7c,0x08,0x00,0x00,10001110b,0x0,0x0
+times 253 db 0x50,0x7c,0x08,0x00,0x00,10001110b,0x0,0x0
+idt_end:
+
+
+
+