6 #include "/sys/src/boot/pc/dosfs.h"
12 #define GSHORT(p) (((p)[1]<<8)|(p)[0])
13 #define GLONG(p) ((GSHORT(p+2)<<16)|GSHORT(p))
16 readdisk(Disk *d, void *buf, vlong off, int len)
18 if(seek(d->fd, off, 0) == -1
19 || read(d->fd, buf, len) != len)
25 addpart(Disk *d, char *name, ulong s, ulong e)
27 print("%s: part %s %lud %lud\n", d->prefix, name, s, e);
28 fprint(d->ctlfd, "part %s %lud %lud\n", name, s, e);
34 return t==FAT12 || t==FAT16 || t==FATHUGE || t==FAT32 || t==FAT32X;
40 return t==EXTEND || t==EXTHUGE || t==LEXTEND;
45 /* build a cdboot partition if there is an embedded boot floppy image */
53 if(readdisk(d, buf, 17*2048, 2048) == -1
54 || strcmp((char*)buf+1, "CD001\x01EL TORITO SPECIFICATION") != 0)
58 a = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
60 if(readdisk(d, buf, a*2048, 2048) == -1
61 || memcmp((char*)buf, "\x01\x00\x00\x00", 4) != 0
62 || memcmp((char*)buf+30, "\x55\xAA", 2) != 0
67 a = p[0]|(p[1]<<8)|(p[2]<<16)|(p[3]<<24);
70 case 1: n = 1200*1024; break;
71 case 2: n = 1440*1024; break;
72 case 3: n = 2880*1024; break;
76 a = a * (uvlong)2048 / d->secsize;
78 addpart(d, "cdboot", a, a+n);
83 p9part(Disk *d, char *name, ulong pstart)
86 char *field[4], *line[Npart+1], *name2;
90 name2 = smprint("%s%s", d->prefix, name);
91 d = opendisk(name2, 1, 0);
93 fprint(2, "%s: %r\n", name2);
99 if(readdisk(d, partbuf, 512, sizeof partbuf) == -1)
101 partbuf[sizeof partbuf - 1] = '\0';
102 if(strncmp(partbuf, "part ", 5) != 0
103 || (n = getfields(partbuf, line, Npart+1, 0, "\n")) == 0)
105 for(i = 0; i < n; i++) {
106 if(strncmp(line[i], "part ", 5) != 0)
108 if(getfields(line[i], field, 4, 0, " ") != 4)
110 start = strtoul(field[2], 0, 0);
111 end = strtoul(field[3], 0, 0);
114 addpart(d, field[1], pstart+start, pstart+end);
125 ulong taboffset, start, end;
126 ulong firstxpart, nxtxpart;
127 int i, nplan9, havedos;
130 if(readdisk(d, mbrbuf, (uvlong)taboffset*512, sizeof mbrbuf) == -1 \
131 || mbrbuf[0x1FE] != 0x55 || mbrbuf[0x1FF] != 0xAA) \
136 dp = (Dospart*)&mbrbuf[0x1BE];
140 /* get the MBR (allowing for DMDDO) */
142 for(i = 0; i < 4; i++) {
143 if(dp[i].type == DMDDO) {
146 i = -1; /* start over */
152 * Read the partitions, first from the MBR and then
153 * from successive extended partition tables.
161 for(i = 0; i < 4; i++) {
162 /* partition offsets are relative to taboffset */
163 start = taboffset+GLONG(dp[i].start);
164 end = start+GLONG(dp[i].len);
165 if(dp[i].type == PLAN9) {
167 strcpy(name, "plan9");
169 sprint(name, "plan9.%d", nplan9);
170 addpart(d, name, start, end);
171 p9part(d, name, start);
175 if(!havedos && isdos(dp[i].type)) {
177 addpart(d, "dos", start, end);
180 /* nxtxpart is relative to firstxpart (or 0), not taboffset */
181 if(isextend(dp[i].type))
182 nxtxpart = start-taboffset+firstxpart;
187 firstxpart = nxtxpart;
188 taboffset = nxtxpart;
190 return nplan9 + havedos;
201 fd = open("#S", OREAD);
203 fprint(2, "No disk\n");
207 while((n = dirread(fd, &ent)) > 0) {
208 for(i = 0; i < n; i++) {
209 if(ent[i].mode & DMDIR) {
210 name = smprint("#S/%s/data", ent[i].name);
211 d = opendisk(name, 1, 0);
213 fprint(2, "%s: %r\n", name);
216 // XXX not safe yet: if(!mbrpart(d) && !cdpart(d) && !p9part(d, "data", 0))
217 if(!mbrpart(d) && !cdpart(d))
218 fprint(2, "%s: no partitions\n", name);
228 main(int argc, char **argv)
232 fmtinstall('r', errfmt);
234 bind("#c", "/dev", MBEFORE);
235 open("/dev/cons", OREAD);
236 open("/dev/cons", OWRITE);
237 open("/dev/cons", OWRITE);
245 exec("/boot/boot2", argv);