summaryrefslogtreecommitdiff
path: root/boot1
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2016-06-01 19:37:09 -0700
committerScott Gasch <[email protected]>2016-06-01 19:37:09 -0700
commit0a41dae5f406d498b5c9ab1542cb5660e0d982f6 (patch)
tree67ade9fe31cfd0458cc485e95550f7aaf14abdd1 /boot1
Initial checkin of toy OS project.HEADmaster
Diffstat (limited to 'boot1')
-rwxr-xr-xboot1/Makefile14
-rw-r--r--boot1/boot.combin0 -> 310 bytes
-rw-r--r--boot1/boot1.asm113
-rw-r--r--boot1/hardware.asm42
-rw-r--r--boot1/memory.asm3
-rw-r--r--boot1/video.asm81
6 files changed, 253 insertions, 0 deletions
diff --git a/boot1/Makefile b/boot1/Makefile
new file mode 100755
index 0000000..5606866
--- /dev/null
+++ b/boot1/Makefile
@@ -0,0 +1,14 @@
+NASM= nasm
+NASMFLAGS= -f bin -i../inc
+RM= /bin/rm
+TARGET= boot.com
+SOURCES= boot1.asm
+SUPPORT= video.asm hardware.asm
+
+all: $(SOURCES) $(SUPPORT)
+ $(NASM) $(NASMFLAGS) $(SOURCES) -o $(TARGET) ; \
+ mcopy -o $(TARGET) Q:\
+
+clean:
+ $(RM) -f *.log *.core *~ *.gmon \#*\# $(TARGET) ; \
+ mdel Q:\$(TARGET)
diff --git a/boot1/boot.com b/boot1/boot.com
new file mode 100644
index 0000000..663284c
--- /dev/null
+++ b/boot1/boot.com
Binary files differ
diff --git a/boot1/boot1.asm b/boot1/boot1.asm
new file mode 100644
index 0000000..59c0dd0
--- /dev/null
+++ b/boot1/boot1.asm
@@ -0,0 +1,113 @@
+[BITS 16]
+[ORG 0]
+
+START:
+ ;; initialize segments
+ mov ax, BOOT1SEG
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+
+ ;; make sure we are running on a 386+
+
+ ;; while we're still in real mode, detect system hardware via BIOS
+ call PROBE_VIDEO
+ call GET_EQUIPMENT_LIST
+ call GET_MEMORY_SIZE
+ call GET_TIME
+
+ ;; switch the processor into protected mode, keep ints disabled
+ cli
+ lidt [IDT_Pointer]
+ lgdt [GDT_Pointer]
+ call ENABLE_A20
+ mov ax, 0x01
+ lmsw ax
+
+ ;; Jump to 32 bit code, this completes the transition to protected mode
+ db 0x66 ; operand size override prefix
+ db 0xea ; jmp opcode
+ dd (BOOT1SEG<<4) + setup_32 ; want to jump here
+ dw (1<<3) ; ...in the kernel code segment
+
+[BITS 32]
+setup_32:
+ ;; set up data segment registers
+ mov ax, (2<<3)
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ ;; create an initial stack
+ mov esp, KERN_STACK + 4096
+ mov ebp, esp
+
+ ;; create a stack frame, pass ptr to hardware block as param
+ mov eax, (BOOT1SEG<<4)+BIOS_HARDWARE_BLOCK
+ push eax
+ push (BOOT1SEG<<4)+.HANG
+ jmp (1<<3):0x00010000 ; entry point of kernel
+
+.HANG:
+ nop
+ jmp .HANG
+
+
+; Setup data
+; ----------------------------------------------------------------------
+
+BIOS_HARDWARE_BLOCK:
+bDisplayType db 0x00
+bFontSize db 0x00
+wEquipmentBitvector dw 0x0000
+wMemorySize dw 0x0000
+wSystemClock dw 0x0000
+
+NUM_GDT_ENTRIES equ 3 ; number of entries in GDT
+GDT_ENTRY_SZ equ 8 ; size of a single GDT entry
+
+align 8, db 0
+GDT:
+ ; Descriptor 0 is not used
+ dw 0
+ dw 0
+ dw 0
+ dw 0
+
+ ; Descriptor 1: kernel code segment
+ dw 0xFFFF ; bytes 0 and 1 of segment size
+ dw 0x0000 ; bytes 0 and 1 of segment base address
+ db 0x00 ; byte 2 of segment base address
+ db 0x9A ; present, DPL=0, non-system, code, non-conforming,
+ ; readable, not accessed
+ db 0xCF ; granularity=page, 32 bit code, upper nibble of size
+ db 0x00 ; byte 3 of segment base address
+
+ ; Descriptor 2: kernel data and stack segment
+ ; NOTE: what Intel calls an "expand-up" segment
+ ; actually means that the stack will grow DOWN,
+ ; towards lower memory. So, we can use this descriptor
+ ; for both data and stack references.
+ dw 0xFFFF ; bytes 0 and 1 of segment size
+ dw 0x0000 ; bytes 0 and 1 of segment base address
+ db 0x00 ; byte 2 of segment base address
+ db 0x92 ; present, DPL=0, non-system, data, expand-up,
+ ; writable, not accessed
+ db 0xCF ; granularity=page, big, upper nibble of size
+ db 0x00 ; byte 3 of segment base address
+
+GDT_Pointer:
+ dw NUM_GDT_ENTRIES*GDT_ENTRY_SZ ; limit
+ dd (BOOT1SEG<<4) + GDT ; base address
+
+IDT_Pointer:
+ dw 0
+ dd 00
+
+%include "defs.asm"
+%include "hardware.asm"
+%include "video.asm"
+
+ \ No newline at end of file
diff --git a/boot1/hardware.asm b/boot1/hardware.asm
new file mode 100644
index 0000000..b7ac3af
--- /dev/null
+++ b/boot1/hardware.asm
@@ -0,0 +1,42 @@
+[BITS 16]
+;;; Call BIOS to populate equipment bitv in the HARDWARE buffer.
+GET_EQUIPMENT_LIST:
+ xor ax, ax
+ int 0x11
+ mov [wEquipmentBitvector], ax
+ ret
+
+;;; Call BIOS to get the system memory size.
+GET_MEMORY_SIZE:
+ xor ax, ax
+ mov ah, 0x88
+ int 0x15
+ add ax, 1024
+ mov [wMemorySize], ax
+ ret
+
+GET_TIME:
+ xor ax, ax
+ int 0x1a
+ push es
+ push si
+ mov es, cx
+ mov si, dx
+ mov cx, WORD [es:si]
+ mov [wSystemClock], cx
+ pop si
+ pop es
+ ret
+
+; Enable the A20 address line, so we can correctly address
+; memory above 1MB.
+ENABLE_A20:
+ mov al, 0xD1
+ out 0x64, al
+ nop
+ jmp .here
+.here: mov al, 0xDF
+ out 0x60, al
+ nop
+ jmp .there
+.there: ret
diff --git a/boot1/memory.asm b/boot1/memory.asm
new file mode 100644
index 0000000..d834825
--- /dev/null
+++ b/boot1/memory.asm
@@ -0,0 +1,3 @@
+;;;
+SIZE_MEMORY:
+ \ No newline at end of file
diff --git a/boot1/video.asm b/boot1/video.asm
new file mode 100644
index 0000000..61ff153
--- /dev/null
+++ b/boot1/video.asm
@@ -0,0 +1,81 @@
+;;; Display the ASCIIZ string at ds:si via BIOS VIDEO call (real mode only)
+Write:
+ lodsb ; load char to al, increment si
+ or al, al ; see if it's null
+ jz .DONE ; if so, we're finished
+ mov ah, 0x0E ; service 0x0E: output one char
+ mov bh, 0x00 ; display page 0
+ mov bl, 0x07 ; char text attrib (white on black)
+ int 0x10 ; invoke bios
+ jmp Write ; next char
+.DONE:
+ ret
+
+;;; Probe the video system of the machine via BIOS VIDEO calls, populate
+;;; the HARDWARE_INFO buffer (real mode only).
+PROBE_VIDEO:
+ ;; identify the display type
+ call DISP_ID
+ mov [bDisplayType], al
+
+ ;; determine the font size
+ call FONT_SIZE
+ mov [bFontSize], al
+ ret
+
+;;; Determine the font size (width in pixels) of the current display.
+FONT_SIZE:
+ cmp al, 0x0a
+ jl .TRY_OLD
+ mov al, BYTE 16
+ ret
+.TRY_OLD:
+ cmp al, BYTE 1
+ jne .TRY_CGA
+ mov al, BYTE 14
+ ret
+.TRY_CGA:
+ cmp al, BYTE 2
+ jne .TRY_VGA
+ mov al, BYTE 8
+ ret
+.TRY_VGA:
+ mov ah, 0x11
+ mov al, 0x30
+ mov bh, 0
+ int 0x10
+ mov al, cl
+ ret
+
+;;; Determine the video type via BIOS VIDEO call
+DISP_ID:
+ xor ax, ax
+ mov ah, 0x1a
+ int 0x10
+ cmp al, 0x1a
+ jne .TRY_EGA
+ mov al, bl
+ ret
+.TRY_EGA:
+ mov ah, 0x12
+ mov bx, 0x10
+ int 0x10
+ cmp bx, 0x10
+ je .OLD_BOARDS
+ cmp bh, 0
+ je .EGA_COLOR
+ mov al, 5
+ ret
+.EGA_COLOR:
+ mov al, 4
+ ret
+.OLD_BOARDS:
+ int 0x11
+ and al, 0x30
+ cmp al, 0x30
+ jne .CGA
+ mov al, 1
+ ret
+.CGA:
+ mov al, 2
+ ret