]> git.lizzy.rs Git - plan9front.git/blob - sys/src/boot/pc/iso.c
let the kernel set dma mode for ata by default
[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 int
43 read(void *f, void *data, int len)
44 {
45         Extend *ex = f;
46
47         if(ex->len > 0 && ex->rp >= ex->ep)
48                 if(readsect(ex->drive, ex->lba++, ex->rp = ex->buf))
49                         return -1;
50         if(ex->len < len)
51                 len = ex->len;
52         if(len > (ex->ep - ex->rp))
53                 len = ex->ep - ex->rp;
54         memmove(data, ex->rp, len);
55         ex->rp += len;
56         ex->len -= len;
57         return len;
58 }
59
60 void
61 close(void *f)
62 {
63         Extend *ex = f;
64
65         ex->drive = 0;
66         ex->lba = 0;
67         ex->len = 0;
68         ex->rp = ex->ep = ex->buf + Sectsz;
69 }
70
71 static int
72 isowalk(Extend *ex, int drive, char *path)
73 {
74         char name[Maxpath], c, *end;
75         int i;
76         Dir d;
77
78         close(ex);
79         ex->drive = drive;
80
81         /* find pvd */
82         for(i=0x10; i<0x1000; i++){
83                 if(readsect(drive, i, ex->buf))
84                         return -1;
85                 if(*ex->buf == 1)
86                         break;
87         }
88         ex->lba = *((ulong*)(ex->buf + 156 + 2));
89         ex->len = *((ulong*)(ex->buf + 156 + 10));
90
91         for(;;){
92                 if(readn(ex, &d, Dirsz) != Dirsz)
93                         break;
94                 if(d.dirlen == 0)
95                         break;
96                 if(readn(ex, name, d.namelen) != d.namelen)
97                         break;
98                 i = d.dirlen - (Dirsz + d.namelen);
99                 while(i-- > 0)
100                         read(ex, &c, 1);
101                 for(i=0; i<d.namelen; i++){
102                         c = name[i];
103                         if(c >= 'A' && c <= 'Z'){
104                                 c -= 'A';
105                                 c += 'a';
106                         }
107                         name[i] = c;
108                 }
109                 name[i] = 0;
110                 while(*path == '/')
111                         path++;
112                 if((end = strchr(path, '/')) == 0)
113                         end = path + strlen(path);
114                 i = end - path;
115                 if(d.namelen == i && memcmp(name, path, i) == 0){
116                         ex->rp = ex->ep;
117                         ex->lba = *((ulong*)d.lba);
118                         ex->len = *((ulong*)d.len);
119                         if(*end == 0)
120                                 return 0;
121                         else if(d.flags[0] & 2){
122                                 path = end;
123                                 continue;
124                         }
125                         break;
126                 }
127         }
128         close(ex);
129         return -1;
130 }
131
132 void
133 start(void *sp)
134 {
135         char path[Maxpath], *kern;
136         int drive;
137         Extend ex;
138         void *f;
139
140         /* drive passed in DL */
141         drive = ((ushort*)sp)[5] & 0xFF;
142
143         /*
144          * load full bootblock as only the frist 2K get
145          * loaded from bios. the code is specially arranged
146          * to have all the important routines in the first
147          * 2K of the 9bootiso image. (strings have been
148          * placed in l.s to make sure they will be < 2K)
149          */
150         if(isowalk(&ex, drive, bootname)){
151                 print(bootname);
152                 putc('?');
153                 halt();
154         }
155         readn(&ex, origin, ex.len);
156         close(&ex);
157
158         if(isowalk(f = &ex, drive, "/cfg/plan9.ini")){
159                 print("no config\r\n");
160                 f = 0;
161         }
162         for(;;){
163                 kern = configure(f, path); f = 0;
164                 if(isowalk(&ex, drive, kern)){
165                         print("not found\r\n");
166                         continue;
167                 }
168                 print(bootkern(&ex));
169                 print(crnl);
170         }
171 }
172