diff --git a/boot/Makefile b/boot/Makefile index df574c4..78be18f 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -5,7 +5,7 @@ PROG = boot SRCS = srt0.S gdt.S boot.c 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 +ESRCS = pccon.c sricon.c print.c fmt.c a20.c time.c mem.c cpu.c alloc.c disk.c OBJS += $(ESRCS:.c=.o) include $(SDIR)/Makefile.inc diff --git a/boot/boot.c b/boot/boot.c index 8517d59..5cc4085 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -97,10 +97,16 @@ done: void boot(int bootdev) { + BIOSdisk d = {0,}; + + fmtinstall('D', fmtdisk); print("\n===> Hello world <===\n\t" "Booted on disk 0x%x debug:%d\n\t", bootdev, debug); machdep(); + bdiskget(bootdev, &d); + print("%D\n%D", d,d); + for(;;){ char buf[8192]; diff --git a/boot/dat.h b/boot/dat.h index 8a6ebb5..6344877 100644 --- a/boot/dat.h +++ b/boot/dat.h @@ -56,6 +56,18 @@ typedef struct{ va_list ap; }Op; +// disk.c +typedef struct{ + int n; + u32 ncyl; + u32 nhead; + u32 nsec; + i32 edd; + u32 dev ; + u32 checksum; + u32 flag; +} __attribute__((packed)) BIOSdisk; + // gdt.S extern volatile struct BIOSreg BIOSreg; diff --git a/boot/disk.c b/boot/disk.c new file mode 100644 index 0000000..183b8a9 --- /dev/null +++ b/boot/disk.c @@ -0,0 +1,93 @@ +#include +#include "dat.h" +#include "fn.h" + +// 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 +}; + +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; +} + +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; +} \ No newline at end of file diff --git a/boot/fn.h b/boot/fn.h index bc1c253..83f023f 100644 --- a/boot/fn.h +++ b/boot/fn.h @@ -41,6 +41,10 @@ long getsecs(void); void *alloc(uint); void free(void*); +// disk.c +int bdiskget(int dev, BIOSdisk *d); +int fmtdisk(Op *op); + // util void* memset(void *dst, int v, int l);