import util
type MBTagStub is
int type
int size
endtype
type RawMultibootInfo is packed
int total_size
int _reserved0
function(RawMultibootInfo i, int idx) RawMultibootInfo:get_tag -> MBTagStub does
int curr_tag=0
int curr_off=8
ptr base=i|ptr
while curr_off<i.total_size do
if curr_tag==idx do
return (base:offset(curr_off)|MBTagStub)
done
curr_off+=(base:offset(curr_off)|MBTagStub).size
if (curr_off%8)!=0 do
curr_off+=8-(curr_off%8)
done
curr_tag+=1
done
return 0|ptr|MBTagStub
function(RawMultibootInfo i, int reqtype) RawMultibootInfo:get_type -> MBTagStub does
int idx=0
MBTagStub curr=i:get_tag(0)
while curr.type!=0 do
if curr.type==reqtype do
return curr
done
idx+=1
curr=i:get_tag(idx)
done
return (0|ptr|MBTagStub)
function(RawMultibootInfo i, int reqtype) RawMultibootInfo:has_type -> bool does
int idx=0
MBTagStub curr=i:get_tag(0)
while curr.type!=0 do
if curr.type==reqtype do
return 1|bool
done
idx+=1
curr=i:get_tag(idx)
done
return (0|bool)
function(RawMultibootInfo i) RawMultibootInfo:print -> void does
kterm:print("Total Size: ")
kterm:printi(i.total_size)
kterm:print("\n")
int idx=0
MBTagStub curr=i:get_tag(0)
while curr.type!=0 do
kterm:printi(idx)
kterm:print(" - ")
if curr.type==1 do
kterm:print("Cmdline tag, cmdline=`")
kterm:print((curr|ptr):offset(8)|cstr)
kterm:print("'")
elif curr.type==2 do
kterm:print("Loader tag, name=`")
kterm:print((curr|ptr):offset(8)|cstr)
kterm:print("'")
elif curr.type==3 do
kterm:print("Module tag, args=")
kterm:print((curr|MBModuleTag):get_args())
elif curr.type==4 do
kterm:print("BasicMem tag, lower=")
kterm:printi((curr|MBBasicMemTag).mem_lower)
kterm:print(", upper=")
kterm:printi((curr|MBBasicMemTag).mem_upper)
elif curr.type==5 do
kterm:print("Boot Device tag, dev=")
kterm:dumphex((curr|MBDeviceTag).biosdev, 2)
kterm:print(", p=")
kterm:dumphex((curr|MBDeviceTag).part, 2)
kterm:print(":")
kterm:dumphex((curr|MBDeviceTag).spart, 2)
elif curr.type==6 do
kterm:print("MMAP Tag esz=")
kterm:printi((curr|MBMMAPMemTag).entry_size)
kterm:print(", ev=")
kterm:printi((curr|MBMMAPMemTag).entry_version)
kterm:print(", #=")
kterm:printi(curr.size/(curr|MBMMAPMemTag).entry_size)
(curr|MBMMAPMemTag):print()
elif curr.type==7 do
kterm:print("VBE Info Tag:. Controller info:\n")
((curr|ptr):offset(16)|RawVBEControllerInfo):print()
kterm:print("\nMode info:\n")
((curr|ptr):offset(16+512)|RawVBEModeInfo):print()
elif curr.type==8 do
MBFBMemTag tag = curr|MBFBMemTag
kterm:print("FB Tag addr=")
kterm:dumphexi(tag.address|int)
kterm:print(", pitch=")
kterm:printi(tag.pitch)
kterm:print(", width=")
kterm:printi(tag.width)
kterm:print(", height=")
kterm:printi(tag.height)
kterm:print(", bpp=")
kterm:printi(tag.bpp|int)
kterm:print(", fbtype=")
kterm:printi(tag.fbtype|int)
elif curr.type==10 do
kterm:print("APM Tag (unk.)")
elif curr.type==14 do
kterm:print("RSDP1 Tag, oem=")
(curr|MBRSDP1Tag):printOEM()
elif curr.type==15 do
kterm:print("RSDP2 Tag, oem=")
(curr|MBRSDP1Tag):printOEM()
elif curr.type==16 do
kterm:print("NIC Tag (unk.)")
else do
kterm:print("??? Tag")
done
kterm:print(", type=")
kterm:printi(curr.type)
kterm:print(", sz=")
kterm:printi(curr.size)
kterm:print(", pos=")
kterm:dumphexi(curr|ptr|int)
kterm:print("\n")
idx+=1
curr=i:get_tag(idx)
if curr|ptr|int==0 do
kterm:print("\nMalformed structure, no terminator tag!\n")
return
done
if curr.type==0 do
kterm:print("Reached End Tag\n")
done
done
return
endtype
type MBBasicMemTag is packed
int type
int size
int mem_lower
int mem_upper
endtype
type MBMMAPMemTagEntry is packed
long base_addr
long length
int type
int reserved
endtype
type MBMMAPMemTag is packed
int type
int size
int entry_size
int entry_version
function(MBMMAPMemTag t) MBMMAPMemTag:print -> void does
int count=(t.size-8)/t.entry_size
int idx=0
MBMMAPMemTagEntry entry
while idx<count do
entry=(t|ptr):offset(16+(t.entry_size*idx))|MBMMAPMemTagEntry
kterm:print("\n MMAP Tag ")
kterm:printi(idx)
kterm:print(" - type=")
kterm:printi(entry.type)
kterm:print(", start=")
kterm:dumphexi(entry.base_addr|int)
kterm:print(", len=")
kterm:dumphexi(entry.length|int)
idx+=1
done
return
endtype
type MBFBMemTag is packed
int type
int size
long address
int pitch
int width
int height
byte bpp
byte fbtype
byte reserved
endtype
type MBDeviceTag is packed
int type
int size
int biosdev
int part
int spart
endtype
type MBModuleTag is packed
int type
int size
int start
int end
function(MBModuleTag t) MBModuleTag:get_args -> cstr does
return (t|ptr):offset(@sizeof(MBModuleTag)@)|cstr
function(MBModuleTag t) MBModuleTag:get_addr -> ptr does
return (t.start+base_vma)|ptr
endtype
type MBRSDP1Tag is packed
int type
int size
long sig
byte checksum
byte oem0
byte oem1
byte oem2
byte oem3
byte oem4
byte oem5
function(MBRSDP1Tag t) MBRSDP1Tag:printOEM -> void does
kterm:putchar(t.oem0)
kterm:putchar(t.oem1)
kterm:putchar(t.oem2)
kterm:putchar(t.oem3)
kterm:putchar(t.oem4)
kterm:putchar(t.oem5)
return
endtype
type MultibootModuleInfo is
cstr params
ptr contents
int size
MultibootModuleInfo _next
function(MBModuleTag tag) MultibootModuleInfo::new -> MultibootModuleInfo does
MultibootModuleInfo new = malloc(@sizeof(MultibootModuleInfo)@)|MultibootModuleInfo
new.params=tag:get_args()
new.contents=tag:get_addr()
new.size=tag.end-tag.start
new._next=0|ptr|MultibootModuleInfo
return new
endtype
type MultibootInfo is
ptr mb_phys_addr
RawMultibootInfo mb_raw
bool valid
cstr bootloader
cstr cmdline
bool text_mode
int screen_w
int screen_h
int screen_pitch
int screen_depth
int fb_raw_addr
ptr fb_addr
int boot_device
int module_count
MultibootModuleInfo _firstmodule
function(ptr phys_addr) MultibootInfo::load -> MultibootInfo does
MultibootInfo new = malloc(@sizeof(MultibootInfo)@)|MultibootInfo
new.mb_phys_addr=phys_addr
new.mb_raw=phys_addr:offset(base_vma)|RawMultibootInfo
new.valid=0|bool
if phys_addr|int >= 0x400000 do
return new
done
if new.mb_raw:has_type(1) do
if new.mb_raw:has_type(2) do
if new.mb_raw:has_type(5) do
if new.mb_raw:has_type(8) do
new.valid=1|bool
new.cmdline=(new.mb_raw:get_type(1)|ptr):offset(8)|cstr
new.bootloader=((new.mb_raw:get_type(2)|ptr):offset(8))|cstr
new.boot_device=(new.mb_raw:get_type(5)|MBDeviceTag).biosdev
MBFBMemTag fb = new.mb_raw:get_type(8)|MBFBMemTag
new.text_mode=fb.fbtype==2|byte
new.screen_w=fb.width
new.screen_h=fb.height
new.screen_pitch=fb.pitch
new.screen_depth=fb.bpp|int
new.fb_raw_addr=fb.address|int
new.fb_addr=(fb.address|int|ptr):offset(base_vma)
new.module_count=0
int idx=0
MBTagStub tag=new.mb_raw:get_tag(0)
MultibootModuleInfo tail
while tag.type!=0 do
if tag.type==3 do
if new.module_count==0 do
new._firstmodule=MultibootModuleInfo::new(tag|MBModuleTag)
tail=new._firstmodule
else do
tail._next=MultibootModuleInfo::new(tag|MBModuleTag)
tail=tail._next
done
new.module_count+=1
done
idx+=1
tag=new.mb_raw:get_tag(idx)
done
return new
done
done
done
done
return new
function(MultibootInfo i, cstr args) MultibootInfo:get_mod_by_args -> MultibootModuleInfo does
if i.module_count==0 do
return 0|ptr|MultibootModuleInfo
done
MultibootModuleInfo cur = i._firstmodule
int idx=0
while idx<i.module_count do
if cur.params==args do
return cur
done
idx+=1
cur=cur._next
done
return 0|ptr|MultibootModuleInfo
endtype
type RawVBEControllerInfo is packed
byte sig_0
byte sig_1
byte sig_2
byte sig_3
short version
short oem_string_seg
short oem_string_addr
byte capabilities_0
byte capabilities_1
byte capabilities_2
byte capabilities_3
short vmode_seg
short vmode_addr
short avail_mem
function(RawVBEControllerInfo i) RawVBEControllerInfo:print -> void does
kterm:print(" Signature: ")
kterm:putchar(i.sig_0)
kterm:putchar(i.sig_1)
kterm:putchar(i.sig_2)
kterm:putchar(i.sig_3)
kterm:print("\n Version: ")
kterm:dumphex(i.version|int, 4)
kterm:print("\n OEM String FarPtr: ")
kterm:dumphex(i.oem_string_seg|int, 4)
kterm:print(":")
kterm:dumphex(i.oem_string_addr|int, 4)
kterm:print("\n Capabilities: ")
kterm:dumphex(i.capabilities_0|int, 2)
kterm:print(" ")
kterm:dumphex(i.capabilities_1|int, 2)
kterm:print(" ")
kterm:dumphex(i.capabilities_2|int, 2)
kterm:print(" ")
kterm:dumphex(i.capabilities_3|int, 2)
kterm:print("\n VMode FarPtr: ")
kterm:dumphex(i.vmode_seg|int, 4)
kterm:print(":")
kterm:dumphex(i.vmode_addr|int, 4)
kterm:print("\n Availible Memory (64KB units): ")
kterm:printi(i.avail_mem|int)
return
endtype
type RawVBEModeInfo is packed
short attributes
byte attrsA
byte attrsB
short granularity
short winsize
short segA
short segB
short unk_ptr_seg
short unk_ptr_addr
short pitch
short xres
short yres
byte wchar
byte ychar
byte planes
byte bpp
byte banks
byte memmodel
byte banksize
byte imgpage
byte res0
byte redmask
byte redpos
byte greenmask
byte greenpos
byte bluemask
byte bluepos
byte rsvmask
byte rsvpos
byte directcolor_attrs
int lfb_physaddr
int res1
short res2
function(RawVBEModeInfo i) RawVBEModeInfo:print -> void does
kterm:print(" Attributes:")
kterm:dumpbin(i.attributes|int)
kterm:print(" ")
kterm:dumphex(i.attrsA|int, 2)
kterm:print(":")
kterm:dumphex(i.attrsB|int, 2)
kterm:print("\n Res: ")
kterm:printi(i.xres|int)
kterm:print("x")
kterm:printi(i.yres|int)
kterm:print("x")
kterm:printi(i.bpp|int)
kterm:print("\n Pitch: ")
kterm:dumphex(i.pitch|int, 4)
kterm:print(" PysAddr: ")
kterm:dumphexi(i.lfb_physaddr)
kterm:print("\n")
return
endtype