]> git.lizzy.rs Git - plan9front.git/blob - sys/src/boot/pc/iso.c
9bootfat: rename Extend to File as fat files are not really extends anymore :)
[plan9front.git] / sys / src / boot / pc / iso.c
1 #include <u.h>
2 #include "fns.h"
3
4 enum {
5         Sectsz = 0x800,
6         Maxpath = 256,
7         Dirsz = 33,
8 };
9
10 typedef struct Extend Extend;
11 typedef struct Dir Dir;
12
13 struct Extend
14 {
15         int drive;
16         ulong lba;
17         ulong len;
18         uchar *rp;
19         uchar *ep;
20         uchar buf[Sectsz];
21 };
22
23 struct Dir
24 {
25         uchar dirlen;
26         uchar extlen;
27
28         uchar lba[8];
29         uchar len[8];
30
31         uchar date[7];
32
33         uchar flags[3];
34
35         uchar seq[4];
36
37         uchar namelen;
38 };
39
40 int readsect(ulong drive, ulong lba, void *buf);
41
42 void
43 unload(void)
44 {
45 }
46
47 int
48 read(void *f, void *data, int len)
49 {
50         Extend *ex = f;
51
52         if(ex->len > 0 && ex->rp >= ex->ep)
53                 if(readsect(ex->drive, ex->lba++, ex->rp = ex->buf))
54                         return -1;
55         if(ex->len < len)
56                 len = ex->len;
57         if(len > (ex->ep - ex->rp))
58                 len = ex->ep - ex->rp;
59         memmove(data, ex->rp, len);
60         ex->rp += len;
61         ex->len -= len;
62         return len;
63 }
64
65 void
66 close(void *f)
67 {
68         Extend *ex = f;
69
70         ex->drive = 0;
71         ex->lba = 0;
72         ex->len = 0;
73         ex->rp = ex->ep = ex->buf + Sectsz;
74 }
75
76 static int
77 isowalk(Extend *ex, int drive, char *path)
78 {
79         char name[Maxpath], c, *end;
80         int i;
81         Dir d;
82
83         close(ex);
84         ex->drive = drive;
85
86         /* find pvd */
87         for(i=0x10; i<0x1000; i++){
88                 if(readsect(drive, i, ex->buf))
89                         return -1;
90                 if(*ex->buf == 1)
91                         break;
92         }
93         ex->lba = *((ulong*)(ex->buf + 156 + 2));
94         ex->len = *((ulong*)(ex->buf + 156 + 10));
95
96         for(;;){
97                 if(readn(ex, &d, Dirsz) != Dirsz)
98                         break;
99                 if(d.dirlen == 0)
100                         break;
101                 if(readn(ex, name, d.namelen) != d.namelen)
102                         break;
103                 i = d.dirlen - (Dirsz + d.namelen);
104                 while(i-- > 0)
105                         read(ex, &c, 1);
106                 for(i=0; i<d.namelen; i++){
107                         c = name[i];
108                         if(c >= 'A' && c <= 'Z'){
109                                 c -= 'A';
110                                 c += 'a';
111                         }
112                         name[i] = c;
113                 }
114                 name[i] = 0;
115                 while(*path == '/')
116                         path++;
117                 if((end = strchr(path, '/')) == 0)
118                         end = path + strlen(path);
119                 i = end - path;
120                 if(d.namelen == i && memcmp(name, path, i) == 0){
121                         ex->rp = ex->ep;
122                         ex->lba = *((ulong*)d.lba);
123                         ex->len = *((ulong*)d.len);
124                         if(*end == 0)
125                                 return 0;
126                         else if(d.flags[0] & 2){
127                                 path = end;
128                                 continue;
129                         }
130                         break;
131                 }
132         }
133         close(ex);
134         return -1;
135 }
136
137 void
138 start(void *sp)
139 {
140         char path[Maxpath], *kern;
141         int drive;
142         Extend ex;
143         void *f;
144
145         /* drive passed in DL */
146         drive = ((ushort*)sp)[5] & 0xFF;
147
148         /*
149          * load full bootblock as only the frist 2K get
150          * loaded from bios. the code is specially arranged
151          * to have all the important routines in the first
152          * 2K of the 9bootiso image. (strings have been
153          * placed in l.s to make sure they will be < 2K)
154          */
155         if(isowalk(&ex, drive, bootname)){
156                 print(bootname);
157                 putc('?');
158                 halt();
159         }
160         readn(&ex, origin, ex.len);
161         close(&ex);
162
163         if(isowalk(f = &ex, drive, "/cfg/plan9.ini")){
164                 print("no config\r\n");
165                 f = 0;
166         }
167         for(;;){
168                 kern = configure(f, path); f = 0;
169                 if(isowalk(&ex, drive, kern)){
170                         print("not found\r\n");
171                         continue;
172                 }
173                 print(bootkern(&ex));
174                 print(crnl);
175         }
176 }
177