diff options
author | cinap_lenrek <cinap_lenrek@localhost> | 2011-07-20 08:57:00 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@localhost> | 2011-07-20 08:57:00 +0200 |
commit | 76c321438945be7bb9eca6a954a9040ce92e2ddf (patch) | |
tree | 3435ff7f7ed20f3f47ed076062bc0f05490c8e77 /sys/src/boot | |
parent | 5be936a1926529abc8c9a0aa2cdca81d8e6583ec (diff) |
9bootfat: handle extended partitions
Diffstat (limited to 'sys/src/boot')
-rw-r--r-- | sys/src/boot/pc/fat.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/sys/src/boot/pc/fat.c b/sys/src/boot/pc/fat.c index d313c6f0f..0c32e04dc 100644 --- a/sys/src/boot/pc/fat.c +++ b/sys/src/boot/pc/fat.c @@ -314,7 +314,7 @@ conffat(Fat *fat, void *buf) } static int -findfat(Fat *fat, int drive) +findfat(Fat *fat, int drive, ulong xbase, ulong lba) { struct { uchar status; @@ -327,21 +327,35 @@ findfat(Fat *fat, int drive) uchar buf[Sectsz]; int i; - if(readsect(drive, 0, buf)) + if(xbase == 0) + xbase = lba; + if(readsect(drive, lba, buf)) return -1; if(buf[0x1fe] != 0x55 || buf[0x1ff] != 0xAA) return -1; p = (void*)&buf[0x1be]; for(i=0; i<4; i++){ - if(p[i].status != 0x80) - continue; - fat->drive = drive; - fat->partlba = *((ulong*)p[i].lba); - if(readsect(drive, fat->partlba, buf)) - continue; - if(conffat(fat, buf)) + switch(p[i].typ){ + case 0x05: + case 0x0f: + case 0x85: + /* extended partitions */ + if(!findfat(fat, drive, xbase, xbase + GETLONG(p[i].lba))) + return 0; + /* no break */ + case 0x00: continue; - return 0; + default: + if(p[i].status != 0x80) + continue; + fat->drive = drive; + fat->partlba = lba + GETLONG(p[i].lba); + if(readsect(drive, fat->partlba, buf)) + continue; + if(conffat(fat, buf)) + continue; + return 0; + } } return -1; } @@ -358,7 +372,7 @@ start(void *sp) /* drive passed in DL */ drive = ((ushort*)sp)[5] & 0xFF; - if(findfat(&fat, drive)){ + if(findfat(&fat, drive, 0, 0)){ print("no fat\r\n"); halt(); } |