summaryrefslogtreecommitdiff
path: root/sys/src/boot
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@localhost>2011-07-20 08:57:00 +0200
committercinap_lenrek <cinap_lenrek@localhost>2011-07-20 08:57:00 +0200
commit76c321438945be7bb9eca6a954a9040ce92e2ddf (patch)
tree3435ff7f7ed20f3f47ed076062bc0f05490c8e77 /sys/src/boot
parent5be936a1926529abc8c9a0aa2cdca81d8e6583ec (diff)
9bootfat: handle extended partitions
Diffstat (limited to 'sys/src/boot')
-rw-r--r--sys/src/boot/pc/fat.c36
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();
}