diff options
Diffstat (limited to 'boot1')
| -rwxr-xr-x | boot1/Makefile | 14 | ||||
| -rw-r--r-- | boot1/boot.com | bin | 0 -> 310 bytes | |||
| -rw-r--r-- | boot1/boot1.asm | 113 | ||||
| -rw-r--r-- | boot1/hardware.asm | 42 | ||||
| -rw-r--r-- | boot1/memory.asm | 3 | ||||
| -rw-r--r-- | boot1/video.asm | 81 |
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 Binary files differnew file mode 100644 index 0000000..663284c --- /dev/null +++ b/boot1/boot.com 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 |
