add disk read

not implementing disk write yet
This commit is contained in:
Hojun-Cho 2024-12-16 23:23:18 +09:00
parent 14fac398c5
commit 06160c1ed3
4 changed files with 117 additions and 3 deletions

View File

@ -10,6 +10,7 @@ void (*probe1[])(void) = {
cpuidprobe, cpuidprobe,
}; };
void (*probe2[])(void) = { void (*probe2[])(void) = {
diskprobe,
}; };
BootProbe probes[] = { BootProbe probes[] = {
@ -102,11 +103,9 @@ boot(int bootdev)
fmtinstall('D', fmtdisk); fmtinstall('D', fmtdisk);
print("\n===> Hello world <===\n\t" print("\n===> Hello world <===\n\t"
"Booted on disk 0x%x debug:%d\n\t", bootdev, debug); "Booted on disk 0x%x debug:%d\n\t", bootdev, debug);
machdep(); machdep();
bdiskget(bootdev, &d); bdiskget(bootdev, &d);
print("%D\n%D", d,d);
for(;;){ for(;;){
char buf[8192]; char buf[8192];

View File

@ -7,6 +7,9 @@
#define BOOT_DEBUG 1 #define BOOT_DEBUG 1
#endif #endif
#define DOSPARTOFF 446
#define NDOSPART 4
enum{ enum{
CON_PC, CON_PC,
CON_SRI, CON_SRI,
@ -57,6 +60,25 @@ typedef struct{
}Op; }Op;
// disk.c // 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{ typedef struct{
int n; int n;
u32 ncyl; u32 ncyl;
@ -68,6 +90,17 @@ typedef struct{
u32 flag; u32 flag;
} __attribute__((packed)) BIOSdisk; } __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;

View File

@ -2,6 +2,14 @@
#include "dat.h" #include "dat.h"
#include "fn.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 // interrupt 41h exension support bitmap
enum{ enum{
Eeda = 0x01, // Extended disk access funcions 42-44,47,48 Eeda = 0x01, // Extended disk access funcions 42-44,47,48
@ -9,6 +17,18 @@ enum{
Eedd = 0x04, // Enhanced disk drive functions 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 static int
ireset(int dev) ireset(int dev)
{ {
@ -81,6 +101,67 @@ bdiskget(int dev, BIOSdisk *d)
return 0; 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 int
fmtdisk(Op *op) fmtdisk(Op *op)
{ {

View File

@ -44,6 +44,7 @@ void free(void*);
// disk.c // disk.c
int bdiskget(int dev, BIOSdisk *d); int bdiskget(int dev, BIOSdisk *d);
int fmtdisk(Op *op); int fmtdisk(Op *op);
void diskprobe(void);
// util // util
void* memset(void *dst, int v, int l); void* memset(void *dst, int v, int l);