Skip to content

Commit 8b88a91

Browse files
author
Ian Seyler
committed
Add novideo option
1 parent 75b6f43 commit 8b88a91

File tree

8 files changed

+320
-5
lines changed

8 files changed

+320
-5
lines changed

build.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ mkdir -p bin
44

55
cd src
66

7-
nasm -DBIOS=1 pure64.asm -o ../bin/pure64-bios.sys -l ../bin/pure64-bios-debug.txt
8-
nasm -DUEFI=1 pure64.asm -o ../bin/pure64-uefi.sys -l ../bin/pure64-uefi-debug.txt
7+
nasm -dBIOS=1 -dNOVIDEO=1 pure64.asm -o ../bin/pure64-bios-novideo.sys -l ../bin/pure64-bios-novideo-debug.txt
8+
nasm -dBIOS=1 pure64.asm -o ../bin/pure64-bios.sys -l ../bin/pure64-bios-debug.txt
9+
nasm -dUEFI=1 pure64.asm -o ../bin/pure64-uefi.sys -l ../bin/pure64-uefi-debug.txt
910

1011
cd boot
1112

1213
nasm bios.asm -o ../../bin/bios.sys -l ../../bin/bios-debug.txt
1314
nasm uefi.asm -o ../../bin/uefi.sys -l ../../bin/uefi-debug.txt
1415
nasm bios-floppy.asm -o ../../bin/bios-floppy.sys -l ../../bin/bios-floppy-debug.txt
1516
nasm bios-pxe.asm -o ../../bin/bios-pxe.sys -l ../../bin/bios-pxe-debug.txt
17+
nasm bios-novideo.asm -o ../../bin/bios-novideo.sys -l ../../bin/bios-novideo-debug.txt
1618

1719
cd ../..

src/boot/bios-novideo.asm

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
; =============================================================================
2+
; Pure64 MBR -- a 64-bit OS/software loader written in Assembly for x86-64 systems
3+
; Copyright (C) 2008-2025 Return Infinity -- see LICENSE.TXT
4+
;
5+
; This Master Boot Record will load Pure64 from a pre-defined location on the
6+
; hard drive without making use of the file system.
7+
;
8+
; In this code we are expecting a BMFS-formatted drive. With BMFS the Pure64
9+
; binary is required to start at sector 16 (8192 bytes from the start). A small
10+
; check is made to make sure Pure64 was loaded by comparing a signature.
11+
; =============================================================================
12+
13+
; Default location of the second stage boot loader. This loads
14+
; 32 KiB from sector 16 into memory at 0x8000
15+
%define DAP_SECTORS 64
16+
%define DAP_STARTSECTOR 16
17+
%define DAP_ADDRESS 0x8000
18+
%define DAP_SEGMENT 0x0000
19+
20+
BITS 16
21+
org 0x7C00
22+
23+
entry:
24+
jmp bootcode ; Jump past the BPB data
25+
nop
26+
27+
; BPB (BIOS Parameter Block)
28+
dq 0 ; OEM identifier
29+
dw 0 ; Bytes per sector
30+
db 0 ; Sectors per cluster
31+
dw 0 ; Reserved sectors
32+
db 0 ; Number of FATs
33+
dw 0 ; Number of root directory entries
34+
dw 0 ; The total sectors in the logical volume
35+
db 0 ; Media descriptor type
36+
dw 0 ; Number of sectors per FAT
37+
dw 0 ; Number of sectors per track
38+
dw 0 ; Number of heads or sides on the storage media
39+
dd 0 ; Number of hidden sectors
40+
dd 0 ; Large sector count
41+
42+
; EBPB (Extended Boot Record)
43+
dd 0 ; Sectors per FAT
44+
dw 0 ; Flags
45+
dw 0 ; FAT version number
46+
dd 0 ; The cluster number of the root directory
47+
dw 0 ; The sector number of the FSInfo structure
48+
dw 0 ; The sector number of the backup boot sector
49+
dq 0 ; Reserved
50+
dd 0 ; Reserved
51+
db 0 ; Drive number
52+
db 0 ; Flags in Windows NT
53+
db 0 ; Signature
54+
dd 0 ; Volume ID 'Serial' number
55+
times 11 db 0 ; Volume label string
56+
dq 0 ; System identifier string. Always "FAT32 "
57+
58+
bootcode:
59+
cli ; Disable interrupts
60+
cld ; Clear direction flag
61+
xor eax, eax
62+
mov ss, ax
63+
mov es, ax
64+
mov ds, ax
65+
mov sp, 0x7C00
66+
sti ; Enable interrupts
67+
68+
mov [DriveNumber], dl ; BIOS passes drive number in DL
69+
70+
; Configure first serial port
71+
mov dx, 0 ; Port
72+
mov ax, 0x00E3 ; Init port, 9600bps 8N1
73+
int 0x14
74+
75+
; Output message to serial
76+
mov si, msg_Load
77+
call output_serial
78+
79+
; Get the BIOS E820 Memory Map
80+
; https://wiki.osdev.org/Detecting_Memory_(x86)#BIOS_Function:_INT_0x15,_EAX_=_0xE820
81+
; The code below is from https://wiki.osdev.org/Detecting_Memory_(x86)#Getting_an_E820_Memory_Map
82+
; inputs: es:di -> destination buffer for 24 byte entries
83+
; outputs: bp = entry count, trashes all registers except esi
84+
; The function below creates a memory map at address 0x6000 and the records are:
85+
; 64-bit Base
86+
; 64-bit Length
87+
; 32-bit Type (1 = normal, 2 reserved, ACPI reclaimable)
88+
; 32-bit ACPI
89+
; 64-bit Padding
90+
do_e820:
91+
mov edi, 0x00006000 ; location that memory map will be stored to
92+
xor ebx, ebx ; ebx must be 0 to start
93+
xor bp, bp ; keep an entry count in bp
94+
mov edx, 0x0534D4150 ; Place "SMAP" into edx
95+
mov eax, 0xe820
96+
mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
97+
mov ecx, 24 ; ask for 24 bytes
98+
int 0x15
99+
jc nomemmap ; carry set on first call means "unsupported function"
100+
mov edx, 0x0534D4150 ; Some BIOSes apparently trash this register?
101+
cmp eax, edx ; on success, eax must have been reset to "SMAP"
102+
jne nomemmap
103+
test ebx, ebx ; ebx = 0 implies list is only 1 entry long (worthless)
104+
je nomemmap
105+
jmp jmpin
106+
e820lp:
107+
mov eax, 0xe820 ; eax, ecx get trashed on every int 0x15 call
108+
mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
109+
mov ecx, 24 ; ask for 24 bytes again
110+
int 0x15
111+
jc memmapend ; carry set means "end of list already reached"
112+
mov edx, 0x0534D4150 ; repair potentially trashed register
113+
jmpin:
114+
jcxz skipent ; skip any 0 length entries
115+
cmp cl, 20 ; got a 24 byte ACPI 3.X response?
116+
jbe notext
117+
test byte [es:di + 20], 1 ; if so: is the "ignore this data" bit clear?
118+
je skipent
119+
notext:
120+
mov ecx, [es:di + 8] ; get lower dword of memory region length
121+
test ecx, ecx ; is the qword == 0?
122+
jne goodent
123+
mov ecx, [es:di + 12] ; get upper dword of memory region length
124+
jecxz skipent ; if length qword is 0, skip entry
125+
goodent:
126+
inc bp ; got a good entry: ++count, move to next storage spot
127+
add di, 32 ; Pad to 32 bytes for each record
128+
skipent:
129+
test ebx, ebx ; if ebx resets to 0, list is complete
130+
jne e820lp
131+
nomemmap:
132+
memmapend:
133+
xor eax, eax ; Create a blank record for termination (32 bytes)
134+
mov ecx, 8
135+
rep stosd
136+
137+
; Enable the A20 gate
138+
set_A20:
139+
in al, 0x64
140+
test al, 0x02
141+
jnz set_A20
142+
mov al, 0xD1
143+
out 0x64, al
144+
check_A20:
145+
in al, 0x64
146+
test al, 0x02
147+
jnz check_A20
148+
mov al, 0xDF
149+
out 0x60, al
150+
151+
; Video modes aren't supported in this boot sector
152+
; Clear the video detail memory for Pure64
153+
mov edi, 0x5F00
154+
xor eax, eax
155+
mov ecx, 64
156+
rep stosd
157+
158+
; Read the 2nd stage boot loader into memory.
159+
mov ah, 0x42 ; Extended Read
160+
mov dl, [DriveNumber] ; http://www.ctyme.com/intr/rb-0708.htm
161+
mov si, DAP
162+
int 0x13
163+
jc halt
164+
165+
; Check signature
166+
; mov eax, [0x8000]
167+
; cmp eax, 0x00017EE9 ; Match against the Pure64 binary
168+
; jne halt
169+
170+
; Output message to serial
171+
mov si, msg_Ok
172+
call output_serial
173+
174+
mov bl, 'B' ; 'B' as we booted via BIOS
175+
176+
; At this point we are done with real mode and BIOS interrupts. Jump to 32-bit mode.
177+
cli ; No more interrupts
178+
lgdt [cs:GDTR32] ; Load GDT register
179+
mov eax, cr0
180+
or al, 0x01 ; Set protected mode bit
181+
mov cr0, eax
182+
jmp 8:0x8000 ; Jump to 32-bit protected mode
183+
184+
;magic_fail:
185+
; mov si, msg_Error
186+
; call output_serial
187+
halt:
188+
hlt
189+
jmp halt
190+
;------------------------------------------------------------------------------
191+
192+
193+
;------------------------------------------------------------------------------
194+
; Output a string via serial
195+
; IN: SI - Address of start of string
196+
output_serial: ; Output string via serial
197+
pusha
198+
output_serial_next_char:
199+
mov dx, 0 ; First serial port
200+
mov ah, 0x01 ; SERIAL - WRITE CHARACTER TO PORT
201+
lodsb ; Get char from string
202+
cmp al, 0
203+
je output_serial_done ; If char is zero, end of string
204+
int 0x14 ; Otherwise, output it
205+
jmp short output_serial_next_char
206+
output_serial_done:
207+
popa
208+
ret
209+
;------------------------------------------------------------------------------
210+
211+
msg_Load db "MBR ", 0
212+
msg_Ok db "OK", 0
213+
msg_Error db "Error!", 0
214+
215+
align 16
216+
GDTR32: ; Global Descriptors Table Register
217+
dw gdt32_end - gdt32 - 1 ; limit of GDT (size minus one)
218+
dq gdt32 ; linear address of GDT
219+
220+
align 16
221+
gdt32:
222+
dw 0x0000, 0x0000, 0x0000, 0x0000 ; Null descriptor
223+
dw 0xFFFF, 0x0000, 0x9A00, 0x00CF ; 32-bit code descriptor
224+
dw 0xFFFF, 0x0000, 0x9200, 0x00CF ; 32-bit data descriptor
225+
gdt32_end:
226+
227+
align 4
228+
229+
DAP:
230+
db 0x10
231+
db 0x00
232+
dw DAP_SECTORS
233+
dw DAP_ADDRESS
234+
dw DAP_SEGMENT
235+
dq DAP_STARTSECTOR
236+
237+
DriveNumber db 0x00
238+
239+
times 446-$+$$ db 0
240+
241+
; Partition entries (4x 16-bytes)
242+
243+
times 510-$+$$ db 0
244+
245+
dw 0xAA55 ; Boot signature
246+
247+
248+
; EOF

src/init/acpi.asm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,14 @@ init_smp_acpi_done:
154154

155155
noACPI:
156156
novalidacpi:
157+
%ifndef NOVIDEO
157158
; Set screen to Teal
158159
mov rdi, [0x00005F00] ; Frame buffer base
159160
mov rcx, [0x00005F08] ; Frame buffer size
160161
shr rcx, 2 ; Quick divide by 4
161162
mov eax, 0x0000FFFF ; 0x00RRGGBB
162163
rep stosd
164+
%endif
163165
jmp $
164166

165167

src/init/hpet.asm

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ os_hpet_init_disable_int:
6060

6161
os_hpet_init_error:
6262
ret
63-
; -----------------------------------------------------------------------------
6463

6564

6665
; -----------------------------------------------------------------------------

src/init/pit.asm

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
; =============================================================================
2+
; Pure64 -- a 64-bit OS/software loader written in Assembly for x86-64 systems
3+
; Copyright (C) 2008-2025 Return Infinity -- see LICENSE.TXT
4+
;
5+
; INIT PIT
6+
; =============================================================================
7+
8+
9+
init_pit:
10+
; Enable PIT
11+
; Base rate is 1193182 Hz
12+
mov al, 0x36 ; Channel 0 (7:6), Access Mode lo/hi (5:4), Mode 3 (3:1), Binary (0)
13+
out 0x43, al
14+
mov al, 0x3C ; 60
15+
out 0x40, al ; Set low byte of PIT reload value
16+
mov al, 0x00
17+
out 0x40, al ; Set high byte of PIT reload value
18+
; New rate is 19866 Hz (1193182 / 60)
19+
; 0.050286633812733 milliseconds (ms)
20+
; 50.28663381273300814 microseconds (us)
21+
ret
22+
23+
24+
; =============================================================================
25+
; EOF

src/interrupt.asm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,14 @@ exception_gate_21:
144144
jmp exception_gate_main
145145

146146
exception_gate_main:
147+
%ifndef NOVIDEO
147148
; Set screen to Red
148149
mov rdi, [0x00005F00] ; Frame buffer base
149150
mov rcx, [0x00005F08] ; Frame buffer size
150151
shr rcx, 2 ; Quick divide by 4
151152
mov eax, 0x00FF0000 ; 0x00RRGGBB
152153
rep stosd
154+
%endif
153155
exception_gate_main_hang:
154156
hlt
155157
jmp exception_gate_main_hang ; Hang. User must reset machine at this point

0 commit comments

Comments
 (0)