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