Compare commits

..

No commits in common. "06160c1ed3e50da5fdf8fe68b3916615221ec165" and "11097add40379da1bfe57f3d47cac87d1f427653" have entirely different histories.

12 changed files with 93 additions and 861 deletions

View File

@ -1,10 +1,6 @@
# FAT16 bootloader # FAT16 bootloader
x86 FAT16 bootloader x86 FAT16 bootloader
# Feature
* [serial console](https://github.com/Hojun-Cho/bootloader/blob/master/boot/sricon.c)
* [prompt](https://github.com/Hojun-Cho/bootloader/blob/98601ac381e30d98b4f3f2c20a733beebf9c2ee3/boot/boot.c#L105)
### How to run ### How to run
1. install image to device 1. install image to device
install to device install to device
@ -36,4 +32,4 @@
1. set Global Descriptor Table 1. set Global Descriptor Table
2. enter protected mode 2. enter protected mode
2. set Interrupt Descriptor Table 2. set Interrupt Descriptor Table
3. call boot function 3. call boot function

View File

@ -5,7 +5,7 @@ PROG = boot
SRCS = srt0.S gdt.S boot.c SRCS = srt0.S gdt.S boot.c
OBJS = srt0.o gdt.o boot.o OBJS = srt0.o gdt.o boot.o
ESRCS = pccon.c sricon.c print.c fmt.c a20.c time.c mem.c cpu.c alloc.c disk.c ESRCS = pccon.c sricon.c print.c a20.c time.c
OBJS += $(ESRCS:.c=.o) OBJS += $(ESRCS:.c=.o)
include $(SDIR)/Makefile.inc include $(SDIR)/Makefile.inc

View File

@ -1,67 +0,0 @@
#include <u.h>
#include "dat.h"
#include "fn.h"
// only for booting
typedef struct FreeList FreeList;
static struct FreeList{
uint size;
FreeList *next;
} *freed;
extern char end[];
static char *top = end;
static void
putfreed(FreeList *p)
{
p->next = nil;
if(freed){
p->next = freed;
freed = p;
}else
freed = p;
}
static FreeList*
getfreed(uint n)
{
for(FreeList *p=freed,*l=freed; p; p=p->next){
if(p->size >= n){
l->next = p->next;
if(p == freed)
freed = nil;
return p;
}
l = p;
}
return nil;
}
void*
alloc(uint n)
{
FreeList *p;
p = getfreed(n);
if(p == nil){
p = (FreeList*)top;
p->size = n;
p->next = nil;
memset(p+sizeof(*p), 0, n);
top += n + sizeof(*p);
}
if(debug) print("alloc %x %ud\n", &p[1], n);
return &p[1];
}
void
free(void *src)
{
FreeList *p;
p = (FreeList*)((char*)src-sizeof(FreeList));
if(debug) print("free %x %ud\n", src, p->size);
putfreed(p);
}

View File

@ -6,11 +6,9 @@ static void coninit(void);
static void machdep(void); static void machdep(void);
void (*probe1[])(void) = { void (*probe1[])(void) = {
a20up, coninit, memprobe, a20up, coninit,
cpuidprobe,
}; };
void (*probe2[])(void) = { void (*probe2[])(void) = {
diskprobe,
}; };
BootProbe probes[] = { BootProbe probes[] = {
@ -33,11 +31,7 @@ ConDev contab[CON_END] = {
.init = cominit, .init = cominit,
}, },
}; };
ConDev *con = &contab[0]; ConDev *con = &contab[0];
BIOSmmap biosmmap[64];
uint cnvmem, extmem;
int debug = BOOT_DEBUG;
static void static void
coninit(void) coninit(void)
@ -98,14 +92,9 @@ done:
void void
boot(int bootdev) boot(int bootdev)
{ {
BIOSdisk d = {0,}; print("\n\n===> Hello world <===\n\tBooted on disk 0x%x\n", bootdev);
machdep();
fmtinstall('D', fmtdisk);
print("\n===> Hello world <===\n\t"
"Booted on disk 0x%x debug:%d\n\t", bootdev, debug);
machdep();
bdiskget(bootdev, &d);
for(;;){ for(;;){
char buf[8192]; char buf[8192];

View File

@ -1,56 +0,0 @@
#include <u.h>
#include "dat.h"
#include "fn.h"
#define EFLAG_ID 0x00200000
#define CPUID(code, a, b, c, d) \
__asm volatile("cpuid" \
: "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
: "a" (code))
void*
memset(void *dst, int v, int l)
{
char *p = dst;
for(int i = 0; i < l; ++i)
*p++ = 0;
return dst;
}
void
cpuidprobe(void)
{
int canuse;
union{
struct{u32 a,b,d,c;};
char arr[16];
}r = {0,};
__asm volatile("pushfl\n\t"
"popl %2\n\t"
"xorl %2, %0\n\t" /* Invert ID sotred in EFLAGS */
"pushl %0\n\t"
"popfl\n\t"
"pushfl\n\t"
"popl %0\n\t"
"xorl %2, %0\n\t"
: "=r" (canuse)
: "0" (EFLAG_ID), "r" (0) /* "EFLAGS_ID" same location "canuse" */
: "cc");
if(canuse != EFLAG_ID){
print("cpuid not available\n");
return;
}
// print vendor
CPUID(0x00, r.a, r.b, r.c, r.d);
print("CPU vender: %s\n", r.arr+4);
// Is running on Hypervisor?
// But nothing to do...
memset(&r, 0,sizeof(r));
CPUID(0x01, r.a, r.b, r.c, r.d);
if(r.c & (1<<31)){
CPUID(1<<30, r.a, r.b, r.c, r.d);
print("Running on Hypervisor: %s\n", r.arr+4);
}
}

View File

@ -2,13 +2,6 @@
// 0x60 Read/Write Data Port // 0x60 Read/Write Data Port
// 0x64 Read Status Register // 0x64 Read Status Register
// 0x64 Write Command Register // 0x64 Write Command Register
#define TABWIDTH 8
#ifndef BOOT_DEBUG
#define BOOT_DEBUG 1
#endif
#define DOSPARTOFF 446
#define NDOSPART 4
enum{ enum{
CON_PC, CON_PC,
@ -43,63 +36,6 @@ struct ConDev{
uint dev; uint dev;
uchar pri; // the higher the better uchar pri; // the higher the better
}; };
typedef struct{
u64 addr; /* Beginning of block */
u64 size; /* Size of block */
u32 type; /* Type of block */
} __attribute__((packed)) BIOSmmap;
// fmt.c
typedef struct{
int ucase;
int padch;
char *p;
char *ep;
int f1, f2, f3;
va_list ap;
}Op;
// disk.c
typedef struct{
u8 flag; /* bootstrap flags */
u8 bhd; /* begin head */
u8 bsec; /* begin sector */
u8 bcyl; /* begin cylinder */
u8 type; /* partition type (see below) */
u8 ehd; /* end head */
u8 esec; /* end sec2r */
u8 ecyl; /* end cylinder */
u32 beg; /* absolute starting sectoff number */
u32 size; /* partition size in sec2rs */
} __attribute__((packed)) DOSpart;
typedef struct{
u8 boot[DOSPARTOFF];
DOSpart parts[NDOSPART];
u16 sign;
} __attribute__((packed)) DOSmbr;
typedef struct{
int n;
u32 ncyl;
u32 nhead;
u32 nsec;
i32 edd;
u32 dev ;
u32 checksum;
u32 flag;
} __attribute__((packed)) BIOSdisk;
typedef struct{
}Disklabel;
typedef struct{
BIOSdisk bdsk; // bios disk info
Disklabel label;
int bootdev, osdev;
}Disk;
// gdt.S // gdt.S
extern volatile struct BIOSreg BIOSreg; extern volatile struct BIOSreg BIOSreg;
@ -108,8 +44,5 @@ extern volatile struct BIOSreg BIOSreg;
extern void (*probe1[])(void); extern void (*probe1[])(void);
extern void (*probe2[])(void); extern void (*probe2[])(void);
extern BootProbe probes[]; extern BootProbe probes[];
extern BIOSmmap biosmmap[64];
extern ConDev contab[CON_END]; extern ConDev contab[CON_END];
extern ConDev *con; extern ConDev *con;
extern uint cnvmem, extmem;
extern int debug;

View File

@ -1,174 +0,0 @@
#include <u.h>
#include "dat.h"
#include "fn.h"
#define BDA_DISK 0x0475 // of hard disk drives detected
#define MAX_DISK_ENTRY 1 // for now
enum{
Bread = 0x4200,
Bwrite = 0x4300,
};
// interrupt 41h exension support bitmap
enum{
Eeda = 0x01, // Extended disk access funcions 42-44,47,48
Erdc = 0x02, // removable drive controller functions 45,46,48,49
Eedd = 0x04, // Enhanced disk drive functions
};
typedef struct{
u8 len;
u8 res1;
u8 nblk;
u8 res2;
u16 off;
u16 seg;
u64 daddr; // starting block
}EDDcb;
Disk disks[MAX_DISK_ENTRY];
static int
ireset(int dev)
{
int rv;
__asm volatile("int $0x33\n\t"
"setc %b0"
: "=a" (rv)
: "0" (0), "d" (dev)
: "%ecx", "%cc");
return (rv&0xff) ? -1 : 0;
}
// Bit(s) Description (Table 00271)
// 0 extended disk access functions (AH=42h-44h,47h,48h) supported
// 1 removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported
// 2 enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported.
// Extended drive parameter table is valid (see #00273,#00278)
// 3-15 reserved (0)
static __inline int
ieddsuport(BIOSdisk *d)
{
int bmap, rv;
__asm volatile("int $0x33\n\t"
"setc %b0"
: "=a" (rv), "=c" (bmap)
: "0" (0x4100), "b" (0x55aa), "d" (d->n)
: "cc");
if(rv&0xff || (BIOSreg.bx&0xffff) != 0xaa55)
return -1;
d->edd = (bmap&0xffff) | ((rv&0xff)<<16);
return 0;
}
static __inline int
bdiskinfo(BIOSdisk *d)
{
int rv;
// CL = maximum sector number (bits 5-0)
// high two bits of maximum cylinder number (bits 7-6)
__asm volatile("int $0x33\n\t"
"setc %b0\n\t"
"movzbl %h1, %1\n\t"
"movzbl %%cl, %3; andb $0x3f, %b3\n\t"
"xchgb %%cl, %%ch; rolb $2, %%ch"
: "=a" (rv), "=d" (d->nhead), "=c" (d->ncyl), "=b" (d->nsec)
: "0" (0x0800), "1" (d->n)
: "cc");
return (rv&0xff) == 0 ? 0 : -1;
}
int
bdiskget(int dev, BIOSdisk *d)
{
if(ireset(dev)){
print("Can't reset disk\n");
return -1;
}
d->n = dev;
if(bdiskinfo(d)){
print("Can't read disk\n");
return -1;
}
if(ieddsuport(d)){
print("edd not supported\n");
return -1;
}
return 0;
}
static int
diskrw(uint rw, int dev, u32 daddr, u32 blk, void *buf)
{
int rv;
volatile EDDcb cb = {0,};
cb.len = sizeof(cb);
cb.nblk = blk;
cb.seg = ((u32)buf>>4 & 0xffff);
cb.off = (u32)buf & 0xf;
cb.daddr = daddr;
if(cb.seg==0 || cb.off==0)
return -1;
BIOSreg.ds = (u32)&cb >> 4;
__asm volatile ("int $0x33\n\t"
"setc %b0\n\t"
: "=a" (rv)
: "0" (rw), "d" (dev), "S" ((int)(&cb)&0xf)
: "%ecx", "cc");
return rv&0xff? -1 : 0;
}
static int
findos(BIOSdisk *bd)
{
DOSmbr mbr = {0,};
if(diskrw(Bread, bd->n, 0, 1, &mbr)){
print("Can't find os disk %d\n", bd->n);
return -1;
}
print("found os disk signature: 0x%x\n", mbr.sign);
return 0;
}
static int
findlabel(BIOSdisk *b, Disklabel *dl)
{
if(b->n & 0x80){
findos(b);
return 0; // for now
}
print("Can't found disk label:%x \n", b->n);
return -1;
}
void
diskprobe(void)
{
int n = MIN((int)*(char*)BDA_DISK, MAX_DISK_ENTRY);
for(int i = 0x80; i < 0x80+n; ++i){
if(bdiskget(i, &disks[i].bdsk))
return;
print("Disnk info: %D\n", disks[i].bdsk);
if(findlabel(&disks[i].bdsk, &disks[i].label)){
}
}
}
int
fmtdisk(Op *op)
{
dofmt(op, "disk:%x cyl:%d head:%d sec:%d edd:%d");
// for skip va_list
USED(va_arg(op->ap, u32));
USED(va_arg(op->ap, u32));
USED(va_arg(op->ap, u32));
return 0;
}

View File

@ -1,304 +0,0 @@
#include <u.h>
#include "dat.h"
#include "fn.h"
#define MAXCON 30
#define IDIGIT 30
enum{
FLONG = (1<<0),
FSHORT = (1<<2),
FUNSIGN = (1<<3),
};
static void put(Op*, int);
static int noconv(Op*);
static int cconv(Op*);
static int dconv(Op*);
static int hconv(Op*);
static int lconv(Op*);
static int sconv(Op*);
static int uconv(Op*);
static int xconv(Op*);
static int Xconv(Op*);
static int percent(Op*);
static int (*fmtconv[MAXCON])(Op*) = {
noconv,
cconv, dconv, hconv, lconv,
sconv, uconv, xconv, Xconv,
percent,
};
int fmtindex[128] = {
['c'] = 1,
['d'] = 2,
['h'] = 3,
['l'] = 4,
['s'] = 5,
['u'] = 6,
['x'] = 7,
['X'] = 8,
['%'] = 9,
};
int convcnt = 11;
int
strlen(char *s)
{
char *p = s;
while(*p)
++p;
return p-s;
}
int
fmtinstall(int c, int (*f)(Op*))
{
c &= 0177;
if(fmtindex[c] == 0){
if(convcnt + 1 >= MAXCON)
return -1;
fmtindex[c] = convcnt++;
}
fmtconv[fmtindex[c]] = f;
return 0;
}
char*
dofmt(Op *op, char *fmt)
{
int sf1, c;
while(1){
c = *fmt++;
if(c != '%'){
if(c == 0){
if(op->p < op->ep)
*op->p = 0;
return op->p;
}
put(op, c);
continue;
}
op->f2 = -1;
op->f1 = op->f3 = 0;
op->padch = sf1 = 0;
c = *fmt++;
if(c == '-'){
sf1 = 1;
c = *fmt++;
}else if(c == '0' || c == ' '){
op->padch = c;
c = *fmt++;
}
while(c >= '0' && c <= '9'){
op->f1 = op->f1*10 + c-'0';
c = *fmt++;
}
if(sf1)
op->f1 = -op->f1;
if(c != '.')
goto conv;
c = *fmt++;
while(c >= '0' && c <= '9'){
if(op->f2 < 0)
op->f2 = 0;
op->f2 = op->f2*10 + c-'0';
c = *fmt++;
}
conv:
if(c == 0)
fmt -= 1;
c = (*fmtconv[fmtindex[c&0177]])(op);
if(c < 0){
op->f3 |= -c;
c = *fmt++;
goto conv;
}
}
}
static void
strconv(char *s, Op *op, int f1, int f2)
{
int n, c;
char *p;
n = strlen(s);
if(f1 >= 0)
while(n < f1){
put(op, op->padch);
n += 1;
}
for(p=s; (c = *p++);)
if(f2){
put(op, c);
f2 -= 1;
}
if(f1 < 0){
f1 = -f1;
while(n < f1){
put(op, ' ');
n += 1;
}
}
}
static void
numconv(Op *op, int base)
{
char b[IDIGIT];
int i,f,n;
long v;
short h;
i = IDIGIT-1;
f = 0;
b[i] = 0;
switch(op->f3 & (FLONG|FSHORT|FUNSIGN)){
case FLONG:
v = va_arg(op->ap, long);
break;
case FUNSIGN|FLONG:
v = va_arg(op->ap, ulong);
break;
case FSHORT:
v = h = va_arg(op->ap, short);
break;
case FUNSIGN|FSHORT:
h = va_arg(op->ap, ushort);
v = (ushort)h;
break;
case FUNSIGN:
v = va_arg(op->ap, unsigned);
break;
default:
v = va_arg(op->ap, int);
break;
}
if((op->f3 & FUNSIGN) && v < 0){
v = -v;
f = 1;
}
while(--i){
n = v % base;
n += '0';
if(n > '9'){
n += 'a' - ('9'+1);
if(op->ucase)
n += 'A'-'a';
}
b[i] = n;
v = (ulong)v / base;
if(i < 2)
break;
if(op->f2 >= 0 && i >= IDIGIT - op->f2)
continue;
if(v <= 0)
break;
}
if(f)
b[--i] = '-';
strconv(b+i, op, op->f1, -1);
}
static int
noconv(Op *op)
{
strconv("***ERROR: noconv***", op, 0, -1);
return 0;
}
static int
cconv(Op *op)
{
char b[2];
b[0] = va_arg(op->ap, char);
b[1] = 0;
strconv(b, op, op->f1, -1);
return 0;
}
static int
dconv(Op *op)
{
numconv(op, 10);
return 0;
}
static int
hconv(Op *op)
{
return -FSHORT;
}
static int
lconv(Op *op)
{
return -FLONG;
}
static int
uconv(Op *op)
{
return -FUNSIGN;
}
static int
sconv(Op *op)
{
char *p;
p = va_arg(op->ap, char*);
strconv(p?p:"<nil>", op, op->f1, op->f2);
return 0;
}
static int
xconv(Op *op)
{
numconv(op, 16);
return 0;
}
static int
Xconv(Op *op)
{
op->ucase = 1;
numconv(op, 16);
op->ucase = 0;
return 0;
}
static int
percent(Op *op)
{
put(op, '%');
return 0;
}
static void
put(Op *op, int c)
{
static int pos;
int opos;
if(c == 0)
return;
if(c == '\t'){
opos = pos;
pos = (opos+TABWIDTH) & (~(TABWIDTH-1));
while(opos++ < pos && op->p < op->ep)
*op->p++ = ' ';
return;
}
if(op->p < op->ep){
*op->p++ = c;
pos++;
}
if(c == '\n')
pos = 0;
}

View File

@ -1,6 +1,3 @@
#define MAX(x, y) ((x)>(y)?(x):(y))
#define MIN(x, y) ((x)<(y)?(x):(y))
// console.c // console.c
void cominit(ConDev *d); void cominit(ConDev *d);
void pcinit(ConDev *d); void pcinit(ConDev *d);
@ -11,44 +8,17 @@ int comprobe(ConDev *d);
int comgetc(int dev); int comgetc(int dev);
void computc(int dev, int c); void computc(int dev, int c);
// fmt.c
char* dofmt(Op *op, char *fmt);
int fmtinstall(int c, int (*f)(Op*));
char *doprint(char *p, char *ep, char *fmt, va_list ap);
int strlen(char *s);
// print.c // print.c
void putchar(int c); void putchar(int c);
void putstr(char *s, int l);
int getchar(void); int getchar(void);
char* doprint(char *p, char *ep, char *fmt, va_list); void print(const char *fmt, ...);
int print(char *fmt, ...);
int snprint(char *buf, int len, char *fmt, ...);
// a20.c // a20.c
void a20up(void); void a20up(void);
// mem.c // long.c
void memprobe(void);
// cpu.c
void cpuidprobe(void);
// time.c
long getsecs(void); long getsecs(void);
// alloc.c
void *alloc(uint);
void free(void*);
// disk.c
int bdiskget(int dev, BIOSdisk *d);
int fmtdisk(Op *op);
void diskprobe(void);
// util
void* memset(void *dst, int v, int l);
static __inline int static __inline int
major(int x) major(int x)
{ {

View File

@ -2,16 +2,6 @@
#include "def.h" #include "def.h"
#define AX 0
#define CX 4
#define DX 8
#define BX 12
#define BP 16
#define SI 20
#define DI 24
#define DS 28
#define ES 32
#define GEN_LABEL(n) X##n #define GEN_LABEL(n) X##n
// idt entry // idt entry
@ -73,12 +63,22 @@
\ \
lidt Idtr; lidt Idtr;
.text
.globl BIOSreg
BIOSreg:
BIOS_AX: .long 0
BIOS_CX: .long 0
BIOS_DX: .long 0
BIOS_BX: .long 0
BIOS_BP: .long 0
BIOS_SI: .long 0
BIOS_DI: .long 0
BIOS_DS: .long 0
BIOS_ES: .long 0
.text .text
.code32 .code32
.globl pmode_init .globl pmode_init
.globl BIOSreg
BIOSreg:
.space 36, 0
// Table // Table
// IDTR offset + 0 : entry 0 // IDTR offset + 0 : entry 0
@ -246,9 +246,11 @@ EMUh: // build stack for real mode
movb %al, intno // save BIOS int vector movb %al, intno // save BIOS int vector
// BIOS_regs is area for saving the contents of registers returned by the BIOS during a BIOS CALL // BIOS_regs is area for saving the contents of registers returned by the BIOS during a BIOS CALL
movl BIOSreg+ES, %eax movl BIOS_ES, %eax
movl $0x00, %eax
mov %eax, 7f mov %eax, 7f
movl BIOSreg+DS, %eax movl BIOS_DS, %eax
movl $0x00, %eax
mov %eax, 6f mov %eax, 6f
prot2real prot2real
@ -298,13 +300,12 @@ intno = . -1;
// movl $Leax, %eax // movl $Leax, %eax
.byte 0xb8 .byte 0xb8
4: .long 0x90909090 4: .long 0x90909090
movl %eax, BIOSreg+BX mov %eax, BIOS_BX
// movl $Leax, %eax // movl $Leax, %eax
.byte 0xb8 .byte 0xb8
3: .long 0x90909090 3: .long 0x90909090
movl %eax, BIOSreg+ES mov %eax, BIOS_ES
// movl $Leax, %eax // movl $Leax, %eax
.byte 0xb8 .byte 0xb8
@ -317,13 +318,13 @@ intno = . -1;
movb %bh, 0xe*4(%esp) // restore eflags movb %bh, 0xe*4(%esp) // restore eflags
// save register into BIOSREG // save register into BIOSREG
movl %eax, BIOSreg+AX .code32
movl %ecx, BIOSreg+CX movl %eax, BIOS_AX
movl %edx, BIOSreg+DX movl %ecx, BIOS_CX
movl %ebp, BIOSreg+BP movl %edx, BIOS_DX
movl %esi, BIOSreg+SI movl %ebp, BIOS_BP
movl %edi, BIOSreg+DI movl %esi, BIOS_SI
movl %edi, BIOS_DI
// clear NT(Nested Task Flag: 14) flag in eflag // clear NT(Nested Task Flag: 14) flag in eflag
// if 1 : interrupting // if 1 : interrupting

View File

@ -1,81 +0,0 @@
#include <u.h>
#include "dat.h"
#include "fn.h"
#define IOMEM_BEGIN 0x0A0000
#define IOMEM_END 0x100000
enum{
MAP_END = 0x00,
MAP_FREE = 0x01,
MAP_RES = 0x02,
MAP_ACPI_RECLAM = 0x03,
MAP_ACPI_NVS = 0x04,
};
static BIOSmmap*
int15_E820(BIOSmmap *m)
{
int rc, sig, off = 0;
do{
BIOSreg.es = ((uint)(m) >> 4);
__asm volatile("int $0x35; setc %b1"
: "=a" (sig), "=d" (rc), "=b" (off)
: "0" (0xE820), "1" (0x534d4150), "b" (off),
"c" (sizeof(*m)), "D" (((uint)m) & 0xf)
: "cc", "memory");
off = BIOSreg.bx;
if(rc &0xff || sig !=0x534d4150){
break;
if(m->type == 0)
m->type = MAP_RES;
}
m++;
}while(off);
return m;
}
static void
dumpmem(BIOSmmap *m)
{
ulong tot = 0;
for(BIOSmmap *p=m; p->type != MAP_END; ++p){
print("MEM % 2ud type %ud size % 10udKB at %08x:%08x\n",
p-m, p->type, (uint)(p->size/1024), (uint)(p->addr>>32), (uint)p->addr);
if(p->type == MAP_FREE)
tot += p->size/1024;
}
print("RAM low:%udKB high:%udKB\n", cnvmem, extmem);
print("Total free memory: %udKB\n", tot);
}
static int
isa20done(void)
{
register char *a = (char *)0x100000;
register char *b = (char *)0x000000;
return *a != *b;
}
void
memprobe(void)
{
BIOSmmap *m;
cnvmem = extmem = 0;
m = int15_E820(biosmmap);
m->type = MAP_END;
for(m = biosmmap; m->type != MAP_END; ++m){
if(m->type != MAP_FREE || m->size <= 0)
continue;
if(m->addr < IOMEM_BEGIN)
cnvmem = MAX(cnvmem, m->addr + m->size)/1024;
if(m->addr >= IOMEM_END)
extmem += m->size/1024;
}
dumpmem(biosmmap);
print("A20:%s\n", isa20done() ? "ok" : "no");
}

View File

@ -2,49 +2,61 @@
#include "dat.h" #include "dat.h"
#include "fn.h" #include "fn.h"
#define BUFSIZE 1024 #define TABWIDTH 4
static void conputc(int); static void conputc(int c);
static int congetc(void); static int congetc(void);
static void doprint(void (*put)(int), const char *fmt, va_list ap);
static void putint(void (*put)(int), int n, const char *sym, int base);
static int pos = 0;
char* void
doprint(char *p, char *ep, char *fmt, va_list ap) print(const char *fmt, ...)
{ {
Op op = { .p = p, .ep = ep, .ap = ap };
return dofmt(&op, fmt);
}
int
print(char *fmt, ...)
{
char buf[BUFSIZE], *p;
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
p = doprint(buf, buf+sizeof(buf), fmt, args); doprint(putchar, fmt, args);
va_end(args); va_end(args);
putstr(buf, p-buf);
return p-buf;
} }
int static void
snprint(char *buf, int len, char *fmt, ...) doprint(void (*put)(int), const char *s, va_list ap)
{ {
char *p; while(*s){
va_list args; if(*s != '%'){
put(*s++);
va_start(args, fmt); continue;
p = doprint(buf, buf+len, fmt, args); }
va_end(args); ++s;
return p-buf; switch(*s){
case 'd':
putint(put, va_arg(ap,int), "0123456789", 10);
break;
case 'x':
putint(put, va_arg(ap,int), "0123456789abcdef", 16);
break;
case 'X':
putint(put, va_arg(ap,int), "0123456789ABCDEF", 16);
break;
case 's':
for(char *p=va_arg(ap,char*); *p; ++p)
put(*p);
break;
default:
return;
}
++s;
}
} }
int int
getchar(void) getchar(void)
{ {
int c; int c;
c = congetc(); c = congetc();
if(c == '\r') if(c == '\r')
c = '\n'; c = '\n';
if((c < ' ' && c != '\n') || c == '\177') if((c < ' ' && c != '\n') || c == '\177')
@ -53,13 +65,6 @@ getchar(void)
return c; return c;
} }
void
putstr(char *s, int l)
{
while(l--)
putchar(*s++);
}
void void
putchar(int c) putchar(int c)
{ {
@ -67,20 +72,24 @@ putchar(int c)
case '\177': case '\177':
conputc('\b'); conputc('\b');
conputc(' '); conputc(' ');
break;
case '\b': case '\b':
conputc('\b'); conputc('\b');
if(pos > 0)
--pos;
break; break;
case '\t': case '\t':
for(int i = 0; i < TABWIDTH; ++i) do{
conputc(' '); conputc(' ');
}while(++pos % TABWIDTH);
break; break;
case '\n': case '\n':
case '\r': case '\r':
conputc(c); conputc(c);
pos = 0;
break; break;
default: default:
conputc(c); conputc(c);
++pos;
break; break;
} }
} }
@ -100,3 +109,19 @@ congetc(void)
{ {
return con->getc(con->dev); return con->getc(con->dev);
} }
static void
putint(void (*put)(int), int n, const char *sym, int base)
{
int i;
char buf[16];
i = 0;
do{
buf[i++] = n%base;
n /= base;
}while(n);
do{
put((int)sym[(int)buf[--i]]);
}while(i);
}