2 * ld - DOS boot loader of Plan 9
16 floppyinit, floppyinitdev,
17 floppygetfspart, 0, floppyboot,
22 sdgetfspart, sdaddconf, sdboot,
33 extern SDifc sdataifc;
34 extern SDifc sdmylexifc;
35 extern SDifc sd53c8xxifc;
43 typedef struct Mode Mode;
59 typedef struct Medium Medium;
75 static Medium media[Nmedia];
76 static Medium *curmedium = media;
78 static Mode modes[NMode+1] = {
79 [Mauto] { "auto", Mauto, },
80 [Mlocal] { "local", Mlocal, },
81 [Manual] { "manual", Manual, },
84 char *defaultpartition = "new";
89 parse(char *line, char **file)
95 if(p = strchr(line, '!')) {
101 for(tp = types; tp->type != Tnil; tp++)
102 for(mp = tp->media; mp; mp = mp->next)
103 if(strcmp(mp->name, line) == 0)
109 boot(Medium *mp, char *file)
113 memset(&b, 0, sizeof b);
116 // sprint(BOOTLINE, "%s!%s", mp->name, file);
117 return (*mp->type->boot)(mp->dev, file, &b);
125 if(curmedium >= &media[Nmedia])
128 for(l = &tp->media; *l; l = &(*l)->next)
134 char *parts[] = { "dos", "9fat", "fs", 0 };
137 probe(int type, int flag, int dev)
143 for(tp = types; tp->type != Tnil; tp++){
144 if(type != Tany && type != tp->type)
148 for(mp = tp->media; mp; mp = mp->next){
149 if((flag & mp->flag) && (dev == Dany || dev == mp->dev))
154 if((tp->flag & Fprobe) == 0){
156 tp->mask = (*tp->init)();
159 for(i = 0; tp->mask; i++){
160 if((tp->mask & (1<<i)) == 0)
164 if((mp = allocm(tp)) == 0)
170 (*tp->initdev)(i, mp->name);
172 if((flag & mp->flag) && (dev == Dany || dev == i))
180 extern int loopconst;
186 char def[2*NAMELEN], line[80], *p, *file;
190 memset(m, 0, sizeof(Mach));
198 if((ulong)&end > (KZERO|(640*1024)))
199 panic("i'm too big");
202 * If there were any arguments, MS-DOS leaves a character
203 * count followed by the arguments in the runtime header.
204 * Step over the leading space.
206 p = (char*)0x80080080;
215 * Advance command line to first option, if any
218 while(*p==' ' || *p=='\t')
225 * Probe everything, to collect device names.
227 probe(Tany, Fnone, Dany);
230 if((mp = parse(p, &file)) == nil) {
231 print("bad loadfile syntax: %s\n", p);
239 for(tp = types; tp->type != Tnil; tp++){
240 for(mp = tp->media; mp; mp = mp->next){
243 print("Load devices:");
245 print(" %s", mp->name);
252 if(getstr("load from", line, sizeof(line), nil, 0) >= 0)
253 if(mp = parse(line, &file))
260 getfields(char *lp, char **fields, int n, char sep)
264 for(i = 0; lp && *lp && i < n; i++){
270 while(*lp && *lp != sep){
271 if(*lp == '\\' && *(lp+1) == '\n')
280 cistrcmp(char *a, char *b)
288 if(ac >= 'A' && ac <= 'Z')
289 ac = 'a' + (ac - 'A');
290 if(bc >= 'A' && bc <= 'Z')
291 bc = 'a' + (bc - 'A');
302 cistrncmp(char *a, char *b, int n)
311 if(ac >= 'A' && ac <= 'Z')
312 ac = 'a' + (ac - 'A');
313 if(bc >= 'A' && bc <= 'Z')
314 bc = 'a' + (bc - 'A');
327 ialloc(ulong n, int align)
335 palloc = 3*1024*1024;
347 return memset((void*)(p|KZERO), 0, n);
351 xspanalloc(ulong size, int align, ulong span)
355 a = (ulong)ialloc(size+align+span, 0);
358 v = (a + span) & ~(span-1);
363 v = (v + align) & ~(align-1);
368 static Block *allocbp;
377 for(bp = *lbp; bp; bp = bp->next){
378 if((bp->lim - bp->base) >= size){
385 bp = ialloc(sizeof(Block)+size+64, 0);
387 addr = ROUNDUP(addr + sizeof(Block), 8);
388 bp->base = (uchar*)addr;
389 bp->lim = ((uchar*)bp) + sizeof(Block)+size+64;
393 panic("allocb reuse");
413 Paddr= 0x70, /* address port */
414 Pdata= 0x71, /* data port */
418 nvramread(int offset)
424 void (*etherdetach)(void);
425 void (*floppydetach)(void);
426 void (*sddetach)(void);
434 (*(void(*)(void))(PADDR(entry)))();
449 uartspecial(int, void(*)(int), int(*)(void), int)
454 uartputs(IOQ*, char*, int)