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

linld: add 'linld <kernel> <cmdline>' syntax
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Dec 02 12:37:59 2016 +0100 (2016-12-02)
parents bb42796dcd3b
children 31c5cbbd9380
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 #define MAXINITRD 10
11 static struct initrd_state {
12 u32 ofs[MAXINITRD];
13 u32 size[MAXINITRD];
14 u16 cnt;
15 } initrd_state;
17 static void next_chunk(struct image_himem *m)
18 {
19 m->chunk_size = 0;
20 if (m->state >= initrd_state.cnt) return;
21 lseek(m->fd,initrd_state.ofs[m->state],SEEK_SET);
22 m->chunk_size = initrd_state.size[m->state];
23 m->state++;
24 }
26 static u32 isofilesize4round()
27 {
28 return (isofilesize+3)&-4;
29 }
31 static void addinitrd()
32 {
33 struct initrd_state *p = &initrd_state;
34 if (p->cnt >= MAXINITRD) return;
35 p->size[p->cnt] = isofilesize;
36 p->ofs[p->cnt] = isofileofs;
37 p->cnt++;
38 initrd.size += isofilesize4round();
39 }
41 static void load_initrds()
42 {
43 struct image_himem *m = &initrd;
44 if (!m->size) return;
45 m->next_chunk = next_chunk;
46 m->fd = isofd;
47 m->state = 0;
48 next_chunk(m);
49 load_initrd();
50 }
52 static char *isokernel()
53 {
54 struct image_himem *m = &pm;
55 m->chunk_size = m->size = isofilesize4round();
56 m->fd = isofd;
57 return load_kernel();
58 }
60 char _cmdline[256];
61 const char *cmdline = (const char *) _cmdline;
62 extern int skip_xmmalloc;
63 static void bootiso(char **iso)
64 {
65 char *init = " rdinit=/init.exe", *mode="menu";
66 char *s, c, rootfs[16], fallback[16];
67 int restart, isknoppix = 0;
68 unsigned long magic;
70 if (!*iso || isoreset(*iso) < 0) return;
71 skip_xmmalloc++;
72 isoopen("boot") >= 0 ||
73 isoopen("live") >= 0 || // debian
74 isoopen("casper") >= 0; // ubuntu
75 if (iso[1] && !strcmp(mode = iso[1], "text"))
76 init = "";
77 do {
78 if (isoopen(mode) >= 0 || // custom
79 isoopen("bzImage") >= 0 || // SliTaz
80 isoopen("vmlinuz") >= 0 || // misc
81 (isoopen("linux") >= 0 && ++isknoppix)) {
82 magic = kver2ul(isokernel());
83 break;
84 }
85 } while (isoopen("isolinux") >= 0); // Knoppix
86 fallback[0] = 0;
87 for (c = 0, restart = 1; isoreaddir(restart) == 0; restart = 0) {
88 if (strstr(isofilename, ".gz"))
89 strcpy(fallback, isofilename);
90 if (strhead(isofilename, "rootfs")
91 || c > isofilename[6]) continue;
92 strcpy(rootfs, isofilename);
93 c = isofilename[6];
94 }
96 strcpy(_cmdline,"rw root=/dev/null autologin bootfrom=");
97 strcat(_cmdline,*iso);
98 if (magic < 0x20630)
99 init = ""; // Does not support multiple initramfs
101 if (magic > 0) {
102 char *initrd = fallback;
104 if (rootfs[0]) {
105 initrd = rootfs;
106 if (rootfs[6] != '.' && isoopen("rootfs.gz") >= 0)
107 addinitrd(); // for loram
108 }
109 if (isoopen(initrd) >= 0) {
110 addinitrd();
111 }
112 if (*init && lseek(isofd, 20L, SEEK_SET) != -1) {
113 read(isofd, &isofileofs, 4);
114 read(isofd, &magic, 4);
115 isofileofs &= 0xFFFFL;
116 isofilesize = magic & 0xFFFFL;
117 isofileofs -= 0xC0L + isofilesize;
118 if (isofilesize) addinitrd();
119 else init="";
120 }
121 load_initrds();
122 strcat(_cmdline,init);
123 strcatb(_cmdline,"mode=");
124 strcat(_cmdline,mode);
125 strcatb(_cmdline,"magic=");
126 strcat(_cmdline,ultoa(magic));
127 }
128 if (isknoppix) {
129 if (iso[0][1] == ':')
130 *iso += 2;
131 for (s = *iso; *s; s++)
132 if (*s == '\\') *s = '/';
133 }
134 close(isofd);
135 boot_kernel();
136 }
138 u16 root_dev;
139 u16 vid_mode;
140 const char* kernel_name = "bzImage";
141 const char* initrd_name;
142 int main(int argc, char *argv[])
143 {
144 char *iso = NULL;
145 argv[0] = progname();
146 bootiso(argv); // iso ? parsing is /init.exe stuff !
147 if (argc >= 2)
148 bootiso(argv + 1);
150 chdirname(*argv);
151 if (argc < 2) {
152 dousage:
153 die("Usage: tazboot [[@commands]|[-f][kernel=<bzimage>] \
154 [initrd=<rootfs>[,<rootfs2>...]] [bootfrom=<isofile>] ...]\r\n\n\
155 Defaults: tazboot kernel=bzImage auto\r\n\n\
156 Examples for tazboot.cmd:\r\n\n\
157 bootfrom=\\isos\\slitaz-4.0.iso\r\n\
158 kernel=boot/bzImage\r\n\
159 initrd=boot/rootfs4.gz,boot/rootfs3.gz,boot/rootfs2.gz,boot/rootfs1.gz,\\slitaz\\extrafs.gz\r\n\
160 rw root=/dev/null vga=normal autologin\r\n\n\
161 kernel=\\slitaz\\elks\r\n\
162 root=/dev/bda1 ro\r\n");
163 }
164 for (int i=0;;) {
165 char *s=*++argv;
166 i++;
167 if (!s) break;
168 if (strhead(s,"kernel=") == 0) {
169 s += 7;
170 set_kernel:
171 kernel_name = s;
172 }
173 else if (strhead(s,"image=") == 0) {
174 s += 6;
175 goto set_kernel;
176 }
177 else if (strhead(s,"initrd=") == 0) {
178 s += 7;
179 initrd_name = s;
180 }
181 else if (strhead(s,"bootfrom=") == 0) {
182 s += 9;
183 set_iso:
184 iso = s;
185 }
186 else if (strhead(s,"iso=") == 0) {
187 s += 4;
188 goto set_iso;
189 }
190 else if(strhead(s,"vga=") == 0) {
191 s += 4;
192 vid_mode = strtol(s); // support normal, extended & ask
193 }
194 else if((*(u16 *)s|0x2002) == 0x662F) { // -F /f
195 skip_xmmalloc++;
196 }
197 else if(i == 1 && fileattr(s) != -1) {
198 goto set_kernel;
199 }
200 else {
201 if(strhead(s,"root=") == 0) {
202 s += 5;
203 root_dev = strtol(s);
204 }
205 if(strhead(s,"mem=") == 0) {
206 s += 4;
207 topmem = strtol(s);
208 }
209 strcatb(_cmdline,*argv);
210 }
211 }
212 if (iso && isoreset(iso) >= 0) {
213 char *s = (char *) initrd_name;
214 if (isoopen((char *) kernel_name) >= 0) {
215 isokernel();
216 }
217 if (s) {
218 while (*s) {
219 char *p, c;
220 for (p = s; *s && *s != ','; s++);
221 c = *s; *s = 0;
222 if (isoopen(p) >= 0) {
223 addinitrd();
224 }
225 *s = c;
226 if (c) s++;
227 }
228 load_initrds();
229 }
230 }
231 else {
232 load_kernel();
233 load_initrd();
234 }
235 boot_kernel();
236 return _AX;
237 }