wok view linld/stuff/src/TAZBOOT.CPP @ rev 21752

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