Open q3k opened 2 years ago
Messed around with this a bit.
I'll productionize this later once I have an idea of how to assemble real mode x86 code cleanly in our build system.
Here's a nasm snippet:
org 7c00h
start:
jmp main
times 90-($-$$) db 0
; si: string data, null terminated
; di: start offset
writestring:
mov al, [si]
or al, al
jz writestring_done
inc si
mov byte [fs:di], al
add di, 2
jmp writestring
writestring_done:
ret
; si: rle encoded data (high bit == color, lower 7: length)
; di: start offset
writegfx:
mov al, [si]
or al, al
jz writegfx_done
inc si
mov cl, al
and cx, 0b01111111
shr al, 7
writegfx_nextinner:
or al, al
jz writegfx_space
mov byte [fs:di], 'M'
writegfx_space:
add di, 2
sub cx, 1
jz writegfx
jmp writegfx_nextinner
writegfx_done:
ret
main:
xor ax, ax
mov ds, ax
; set mode 3 (text 80x25, 16 color)
mov ax, 0x3
int 0x10
; set up fs segment to point at framebuffer
mov ax, 0xb800
mov fs, ax
mov di, 4
mov si, logo
call writegfx
mov di, 3400
mov si, line1
call writestring
mov di, 3544
mov si, line2
call writestring
end:
jmp end
%include "logo.asm"
line1:
db "Hi there! Didn't see you coming in.", 0
line2:
db "Unfortunately, Metropolis can only boot in UEFI mode.", 0
times 510-($-$$) db 0
db 0x55
db 0xAA
logo.asm
is generated by the following Python snippet (which does some jank RLE):
import sys
from PIL import Image
im = Image.open("logo.png")
assert im.size == (80, 20)
linear = []
for y in range(20):
for x in range(80):
px = im.getpixel((x, y))
linear.append(px)
# RLE
rle = []
while len(linear) > 0:
val = linear[0]
l = 1
for i in range(1, len(linear)):
if linear[i] != val:
break
l += 1
L = l
while l > 0:
block = l
if block > 127:
block = 127
rle.append((val << 7) | block)
l -= block
linear = linear[L:]
rle.append(0)
#assert len(rle) < 128
print("logo: db " + ", ".join([f"0x{r:02x}" for r in rle]))
When a user starts the installer (or Metropolis - but that generally shouldn't happen) without EFI boot, the firmware simply reports the image as not bootable, which can be slightly confusing.
We should add an MBR stub to our generated bootable images that lets the user know they should run with EFI (boot) enabled.