jehanne/sys/src/kern/amd64/multiboot.c

157 lines
3.3 KiB
C

#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
typedef struct Mbi Mbi;
struct Mbi {
uint32_t flags;
uint32_t memlower;
uint32_t memupper;
uint32_t bootdevice;
uint32_t cmdline;
uint32_t modscount;
uint32_t modsaddr;
uint32_t syms[4];
uint32_t mmaplength;
uint32_t mmapaddr;
uint32_t driveslength;
uint32_t drivesaddr;
uint32_t configtable;
uint32_t bootloadername;
uint32_t apmtable;
uint32_t vbe[6];
};
enum { /* flags */
Fmem = 0x00000001, /* mem* valid */
Fbootdevice = 0x00000002, /* bootdevice valid */
Fcmdline = 0x00000004, /* cmdline valid */
Fmods = 0x00000008, /* mod* valid */
Fsyms = 0x00000010, /* syms[] has a.out info */
Felf = 0x00000020, /* syms[] has ELF info */
Fmmap = 0x00000040, /* mmap* valid */
Fdrives = 0x00000080, /* drives* valid */
Fconfigtable = 0x00000100, /* configtable* valid */
Fbootloadername = 0x00000200, /* bootloadername* valid */
Fapmtable = 0x00000400, /* apmtable* valid */
Fvbe = 0x00000800, /* vbe[] valid */
};
typedef struct Mod Mod;
struct Mod {
uint32_t modstart;
uint32_t modend;
uint32_t string;
uint32_t reserved;
};
typedef struct MMap MMap;
struct MMap {
uint32_t size;
uint32_t base[2];
uint32_t length[2];
uint32_t type;
};
int
multiboot(uint32_t magic, uint32_t pmbi, int vflag)
{
char *p, *modname;
int i, n;
Mbi *mbi;
Mod *mod;
MMap *mmap;
uint64_t addr, len;
if(vflag)
print("magic %#ux pmbi %#ux\n", magic, pmbi);
if(magic != 0x2badb002){
//return -1;
print("wrong magic in multiboot\n");
}
mbi = KADDR(pmbi);
if(vflag)
print("flags %#ux\n", mbi->flags);
if(mbi->flags & Fcmdline){
p = KADDR(mbi->cmdline);
if(vflag)
print("cmdline <%s>\n", p);
else
optionsinit(p);
}
if(mbi->flags & Fmods){
for(i = 0; i < mbi->modscount; i++){
mod = KADDR(mbi->modsaddr + i*16);
if(mod->string != 0)
p = KADDR(mod->string);
else
p = "";
if(vflag)
print("mod %#ux %#ux <%s>\n",
mod->modstart, mod->modend, p);
else {
asmmodinit(mod->modstart, mod->modend, p);
modname = strrchr(p, '/');
if(modname == nil)
modname = p;
if(*modname == '/')
++modname;
addbootfile(modname, KADDR(mod->modstart), mod->modend - mod->modstart);
}
}
}
if(mbi->flags & Fmmap){
mmap = KADDR(mbi->mmapaddr);
n = 0;
while(n < mbi->mmaplength){
addr = (((uint64_t)mmap->base[1])<<32)|mmap->base[0];
len = (((uint64_t)mmap->length[1])<<32)|mmap->length[0];
switch(mmap->type){
default:
if(vflag)
print("type %ud", mmap->type);
break;
case 1:
if(vflag)
print("Memory");
else
asmmapinit(addr, len, mmap->type);
break;
case 2:
if(vflag)
print("reserved");
else
asmmapinit(addr, len, mmap->type);
break;
case 3:
if(vflag)
print("ACPI Reclaim Memory");
else
asmmapinit(addr, len, mmap->type);
break;
case 4:
if(vflag)
print("ACPI NVS Memory");
else
asmmapinit(addr, len, mmap->type);
break;
}
if(vflag)
print("\n\t%#16.16llux %#16.16llux (%llud)\n",
addr, addr+len, len);
n += mmap->size+sizeof(mmap->size);
mmap = KADDR(mbi->mmapaddr+n);
}
}
if(vflag && (mbi->flags & Fbootloadername)){
p = KADDR(mbi->bootloadername);
print("bootloadername <%s>\n", p);
}
return 0;
}