rev |
line source |
pascal@19515
|
1 // This file is distributed under GPL
|
pascal@19515
|
2 //
|
pascal@19515
|
3 // TAZBOOT main() lives here
|
pascal@19515
|
4
|
pascal@19515
|
5 #include "crtl.h"
|
pascal@19515
|
6 #include "crtlx.h"
|
pascal@19515
|
7 #include "common.h"
|
pascal@19515
|
8 #include "iso9660.h"
|
pascal@19515
|
9
|
pascal@19825
|
10 struct initrd_info {
|
pascal@19825
|
11 u32 ofs;
|
pascal@19825
|
12 u32 size;
|
pascal@19825
|
13 };
|
pascal@19515
|
14 #define MAXINITRD 10
|
pascal@19515
|
15 static struct initrd_state {
|
pascal@19825
|
16 struct initrd_info info[MAXINITRD];
|
pascal@19515
|
17 u16 cnt;
|
pascal@19515
|
18 } initrd_state;
|
pascal@19515
|
19
|
pascal@19515
|
20 static void next_chunk(struct image_himem *m)
|
pascal@19515
|
21 {
|
pascal@21752
|
22 m->chunk_size = 0;
|
pascal@21750
|
23 if (m->state >= initrd_state.cnt) return;
|
pascal@19825
|
24 struct initrd_info *i = &initrd_state.info[m->state];
|
pascal@19825
|
25 m->chunk_size = i->size;
|
pascal@19515
|
26 m->state++;
|
pascal@21750
|
27 lseekset2(m->fd,&i->ofs);
|
pascal@19515
|
28 }
|
pascal@19515
|
29
|
pascal@19538
|
30 static u32 isofilesize4round()
|
pascal@19538
|
31 {
|
pascal@19538
|
32 return (isofilesize+3)&-4;
|
pascal@19538
|
33 }
|
pascal@19538
|
34
|
pascal@19515
|
35 static void addinitrd()
|
pascal@19515
|
36 {
|
pascal@19825
|
37 u16 *pcnt = &initrd_state.cnt;
|
pascal@19825
|
38 if (*pcnt >= MAXINITRD) return;
|
pascal@21750
|
39 struct initrd_info *i = &initrd_state.info[(*pcnt)++];
|
pascal@19825
|
40 i->size = isofilesize;
|
pascal@19825
|
41 i->ofs = isofileofs;
|
pascal@19538
|
42 initrd.size += isofilesize4round();
|
pascal@19515
|
43 }
|
pascal@19515
|
44
|
pascal@19515
|
45 static void load_initrds()
|
pascal@19515
|
46 {
|
pascal@19538
|
47 struct image_himem *m = &initrd;
|
pascal@19538
|
48 if (!m->size) return;
|
pascal@19538
|
49 m->next_chunk = next_chunk;
|
pascal@19538
|
50 m->fd = isofd;
|
pascal@20458
|
51 m->state = 0;
|
pascal@19538
|
52 next_chunk(m);
|
pascal@19515
|
53 load_initrd();
|
pascal@19515
|
54 }
|
pascal@19515
|
55
|
pascal@19538
|
56 static char *isokernel()
|
pascal@19515
|
57 {
|
pascal@19538
|
58 struct image_himem *m = ±
|
pascal@19538
|
59 m->chunk_size = m->size = isofilesize4round();
|
pascal@19538
|
60 m->fd = isofd;
|
pascal@19538
|
61 return load_kernel();
|
pascal@19515
|
62 }
|
pascal@19515
|
63
|
pascal@20486
|
64 static char buf_cmdline[4096];
|
pascal@20486
|
65 const char *cmdline = (const char *) buf_cmdline+1;
|
pascal@19515
|
66 static void bootiso(char **iso)
|
pascal@19515
|
67 {
|
pascal@19825
|
68 const char *init = " rdinit=/init.exe", *mode="menu";
|
pascal@19825
|
69 char c;
|
pascal@19825
|
70 static char rootfs[16], fallback[16], isknoppix, noauto;
|
pascal@19515
|
71 unsigned long magic;
|
pascal@19571
|
72 struct isostate *x=&isostate;
|
pascal@19515
|
73
|
pascal@21628
|
74 if (isoreset(*iso) == -1) return;
|
pascal@19580
|
75 skip_alloc++;
|
pascal@19580
|
76 base_himem = memtop() /2;
|
pascal@20473
|
77 //if (base_himem >= _64m) base_himem = _64m;
|
pascal@21750
|
78 if (* ((char *) &base_himem +3) >= 4) ((short *)&base_himem)[1] = _64m/_64k;
|
pascal@21628
|
79 isoopen("boot") != -1 ||
|
pascal@21628
|
80 isoopen("live") != -1 || // debian
|
pascal@21628
|
81 isoopen("casper") != -1; // ubuntu
|
pascal@19515
|
82 if (iso[1] && !strcmp(mode = iso[1], "text"))
|
pascal@19515
|
83 init = "";
|
pascal@19515
|
84 do {
|
pascal@21628
|
85 if ((isoopen(mode) != -1 && ++noauto != 0) || // custom
|
pascal@21628
|
86 isoopen("bzImage") != -1 || // SliTaz
|
pascal@21628
|
87 isoopen("vmlinuz") != -1 || // misc
|
pascal@21628
|
88 (isoopen("linux") != -1 && ++isknoppix != 0)) {
|
pascal@19538
|
89 magic = kver2ul(isokernel());
|
pascal@19515
|
90 break;
|
pascal@19515
|
91 }
|
pascal@21628
|
92 } while (isoopen("isolinux") != -1); // Knoppix
|
pascal@21576
|
93 for (c = 0, x->curdirsize = 0xFFFF; isoreaddir() != -1;) {
|
pascal@19571
|
94 if (strstr(x->filename, ".gz"))
|
pascal@19571
|
95 strcpy(fallback, x->filename);
|
pascal@21628
|
96 if (strhead(x->filename, "rootfs") == -1
|
pascal@19571
|
97 || c > x->filename[6]) continue;
|
pascal@21750
|
98 c = x->filename[6];
|
pascal@19571
|
99 strcpy(rootfs, x->filename);
|
pascal@19515
|
100 }
|
pascal@19515
|
101
|
pascal@20534
|
102 strcatb(buf_cmdline,"rw root=/dev/null autologin bootfrom=");
|
pascal@20486
|
103 strcat(buf_cmdline,*iso);
|
pascal@19515
|
104 if (magic < 0x20630)
|
pascal@19515
|
105 init = ""; // Does not support multiple initramfs
|
pascal@19515
|
106
|
pascal@19825
|
107 if (noauto) {
|
pascal@19825
|
108 char *s;
|
pascal@20486
|
109 * (int *) buf_cmdline = 0;
|
pascal@19825
|
110 iso++;
|
pascal@19825
|
111 while ((s = *++iso) != NULL) {
|
pascal@21628
|
112 if (strhead(s,"initrd=") == -1)
|
pascal@20486
|
113 strcatb(buf_cmdline,s);
|
pascal@21628
|
114 else if (isoopen(s+7) != -1)
|
pascal@19825
|
115 addinitrd();
|
pascal@19825
|
116 }
|
pascal@19825
|
117 }
|
pascal@21754
|
118 else if (magic != 0) {
|
pascal@19899
|
119 char *initrdfilename = fallback;
|
pascal@19872
|
120 static const unsigned long initrddesc = 18L;
|
pascal@19515
|
121
|
pascal@19515
|
122 if (rootfs[0]) {
|
pascal@19899
|
123 initrdfilename = rootfs;
|
pascal@21628
|
124 if (rootfs[6] != '.' && isoopen("rootfs.gz") != -1)
|
pascal@19515
|
125 addinitrd(); // for loram
|
pascal@19515
|
126 }
|
pascal@21628
|
127 if (isoopen(initrdfilename) != -1) {
|
pascal@19515
|
128 addinitrd();
|
pascal@19515
|
129 }
|
pascal@20528
|
130 if (*init && isolseek(&initrddesc) != 0) {
|
pascal@19872
|
131 read(x->fd, &x->filemod, 10); // + x->fileofs & x->filesize
|
pascal@19872
|
132 magic = x->filemod;
|
pascal@20876
|
133 x->fileofs = 0x7FF0 - (x->filesize &= 0xFFFF);
|
pascal@19825
|
134 if (((short *) &x->fileofs)[1] == 0) addinitrd();
|
pascal@19515
|
135 else init="";
|
pascal@19515
|
136 }
|
pascal@20486
|
137 strcat(buf_cmdline,init);
|
pascal@20486
|
138 strcatb(buf_cmdline,"mode=");
|
pascal@20486
|
139 strcat(buf_cmdline,mode);
|
pascal@20486
|
140 strcatb(buf_cmdline,"magic=");
|
pascal@20528
|
141 strcat(buf_cmdline,(char *)ultoa(magic));
|
pascal@19515
|
142 }
|
pascal@19825
|
143 load_initrds();
|
pascal@19515
|
144 if (isknoppix) {
|
pascal@19825
|
145 char *s = *iso;
|
pascal@19825
|
146 if (s[1] == ':')
|
pascal@19825
|
147 s += 2;
|
pascal@19825
|
148 for (; *s; s++)
|
pascal@19515
|
149 if (*s == '\\') *s = '/';
|
pascal@19515
|
150 }
|
pascal@19571
|
151 close(x->fd);
|
pascal@19515
|
152 boot_kernel();
|
pascal@19515
|
153 }
|
pascal@19515
|
154
|
pascal@20528
|
155 u32 root_dev;
|
pascal@20528
|
156 u32 vid_mode;
|
pascal@20528
|
157 u32 topmem;
|
pascal@21569
|
158 u32 base_himem;
|
pascal@19515
|
159 const char* kernel_name = "bzImage";
|
pascal@19515
|
160 const char* initrd_name;
|
pascal@20528
|
161 char* iso;
|
pascal@20528
|
162
|
pascal@19515
|
163 int main(int argc, char *argv[])
|
pascal@19515
|
164 {
|
pascal@21569
|
165 ((u16*) &base_himem)[1] |= (_1m+_64k)>>16; // base_himem = _1m+_64k
|
pascal@19515
|
166
|
pascal@19515
|
167 if (argc < 2) {
|
pascal@19546
|
168 try_default_args();
|
pascal@19515
|
169 dousage:
|
pascal@20451
|
170 die("Usage: tazboot [[@commands]|[-f][-b base_himem][kernel=<bzImage>] \
|
pascal@21757
|
171 [initrd=<rootfs>[,<rootfs2>...]] [bootfrom=<isofile>] ...]\n\n\
|
pascal@21757
|
172 Defaults: tazboot kernel=bzImage auto\n\n\
|
pascal@21757
|
173 Examples for tazboot.cmd:\n\n\
|
pascal@21757
|
174 bootfrom=\\isos\\slitaz-4.0.iso\n\
|
pascal@21757
|
175 kernel=boot/bzImage\n\
|
pascal@21757
|
176 initrd=boot/rootfs4.gz,boot/rootfs3.gz,boot/rootfs2.gz,boot/rootfs1.gz,\\slitaz\\extrafs.gz\n\
|
pascal@21757
|
177 rw root=/dev/null vga=normal autologin\n\n\
|
pascal@21757
|
178 kernel=\\slitaz\\elks\n\
|
pascal@21757
|
179 root=/dev/bda1 ro\n");
|
pascal@19515
|
180 }
|
pascal@21791
|
181 bootiso(argv + 1); // iso ? parsing is /init.exe stuff !
|
pascal@19538
|
182 for (int i=0;;) {
|
pascal@19546
|
183 char *s;
|
pascal@19580
|
184 next: argv++;
|
pascal@19546
|
185 s=*argv;
|
pascal@19538
|
186 i++;
|
pascal@21791
|
187 if (!s) {
|
pascal@21791
|
188 if (isoreset(iso) != -1) {
|
pascal@21791
|
189 s = (char *) initrd_name;
|
pascal@21791
|
190 if (isoopen((char *) kernel_name) != -1) {
|
pascal@21791
|
191 isokernel();
|
pascal@21791
|
192 }
|
pascal@21791
|
193 if (s) {
|
pascal@21791
|
194 do {
|
pascal@21791
|
195 char *p, c;
|
pascal@21791
|
196 for (p = s; *s && *s != ','; s++);
|
pascal@21791
|
197 c = *s; *s = 0;
|
pascal@21791
|
198 if (isoopen(p) != -1) {
|
pascal@21791
|
199 addinitrd();
|
pascal@21791
|
200 }
|
pascal@21791
|
201 *s = c;
|
pascal@21791
|
202 if (c) s++;
|
pascal@21791
|
203 } while (*s);
|
pascal@21791
|
204 load_initrds();
|
pascal@21791
|
205 }
|
pascal@21791
|
206 }
|
pascal@21791
|
207 else {
|
pascal@21791
|
208 load_kernel();
|
pascal@21791
|
209 load_initrd();
|
pascal@21791
|
210 }
|
pascal@21791
|
211 boot_kernel();
|
pascal@21791
|
212 }
|
pascal@20751
|
213 #ifdef USE_ARGSTR
|
pascal@20751
|
214 if ((*(u16 *)s|0x2002) == 0x662F) { // -F /f
|
pascal@20751
|
215 skip_alloc++;
|
pascal@20751
|
216 goto next;
|
pascal@20751
|
217 }
|
pascal@21576
|
218 if (argstr(s,"kernel/image|initrd|bootfrom/iso",&kernel_name) != -1);
|
pascal@21576
|
219 else if (argnum(s,"root|vga|mem/-e|-b",&root_dev) != -1);
|
pascal@20751
|
220 else if(i == 1 && fileexist(s) != -1) {
|
pascal@20751
|
221 kernel_name = s;
|
pascal@20751
|
222 }
|
pascal@21569
|
223 else strcatb(buf_cmdline,*argv); // FIXME mem ?
|
pascal@20751
|
224 }
|
pascal@20751
|
225 #else
|
pascal@21791
|
226 if (strhead(s,"initrd=") != -1) {
|
pascal@21791
|
227 s += 7;
|
pascal@21791
|
228 initrd_name = s;
|
pascal@21791
|
229 }
|
pascal@21791
|
230 else if (strhead(s,"bootfrom=") != -1) {
|
pascal@21791
|
231 s += 9;
|
pascal@21791
|
232 goto set_iso;
|
pascal@21791
|
233 }
|
pascal@21791
|
234 else if (strhead(s,"iso=") != -1) {
|
pascal@21791
|
235 s += 4;
|
pascal@21791
|
236 set_iso:
|
pascal@21791
|
237 iso = s;
|
pascal@21791
|
238 }
|
pascal@21791
|
239 else if (strhead(s,"image=") != -1) {
|
pascal@21791
|
240 goto set_kernel;
|
pascal@21791
|
241 }
|
pascal@21791
|
242 else if(strhead(s,"vga=") != -1) {
|
pascal@21791
|
243 *(u16*)&vid_mode = (u16)strtol(s+4); // support normal, extended & ask
|
pascal@21791
|
244 }
|
pascal@21791
|
245 else if (strhead(s,"kernel=") != -1) {
|
pascal@19825
|
246 s++;
|
pascal@19538
|
247 set_kernel:
|
pascal@19825
|
248 s += 6;
|
pascal@19898
|
249 set_kernelz:
|
pascal@19538
|
250 kernel_name = s;
|
pascal@19538
|
251 }
|
pascal@19580
|
252 else switch (*(u16 *)s|0x2002) {
|
pascal@19580
|
253 case 0x662F: // -F /f
|
pascal@19580
|
254 skip_alloc++;
|
pascal@19580
|
255 goto next;
|
pascal@19580
|
256 case 0x652F: // -E /e
|
pascal@21569
|
257 s=*++argv;
|
pascal@21569
|
258 goto set_topmem;
|
pascal@19580
|
259 case 0x622F: // -B /b
|
pascal@19580
|
260 argv++;
|
pascal@21569
|
261 ((u16 *)&base_himem)[1] = (u16)(strtol(*argv)>>16);
|
pascal@19580
|
262 goto next;
|
pascal@19580
|
263 default:
|
pascal@20632
|
264 if(i == 1 && fileexist(s) != -1) {
|
pascal@19898
|
265 goto set_kernelz;
|
pascal@19538
|
266 }
|
pascal@19515
|
267 else {
|
pascal@21569
|
268 strcatb(buf_cmdline,*argv);
|
pascal@21628
|
269 if(strhead(s,"root=") != -1) {
|
pascal@21569
|
270 *(u16*)&root_dev = (u16)strtol(s+5);
|
pascal@19515
|
271 }
|
pascal@21628
|
272 if(strhead(s,"mem=") != -1) {
|
pascal@19538
|
273 s += 4;
|
pascal@21569
|
274 set_topmem:
|
pascal@21569
|
275 ((u16 *)&topmem)[1] = (u16)(strtol(s)>>16);
|
pascal@19515
|
276 }
|
pascal@19580
|
277 }}
|
pascal@19515
|
278 }
|
pascal@20751
|
279 #endif
|
pascal@19515
|
280 }
|