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@19515
|
21 lseek(m->fd,initrd_state.ofs[m->state],SEEK_SET);
|
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 extern int skip_xmmalloc;
|
pascal@19515
|
63 static void bootiso(char **iso)
|
pascal@19515
|
64 {
|
pascal@19515
|
65 char *init = " rdinit=/init.exe", *mode="menu";
|
pascal@19515
|
66 char *s, c, rootfs[16], fallback[16];
|
pascal@19515
|
67 int restart, isknoppix = 0;
|
pascal@19515
|
68 unsigned long magic;
|
pascal@19515
|
69
|
pascal@19515
|
70 if (!*iso || isoreset(*iso) < 0) return;
|
pascal@19515
|
71 skip_xmmalloc++;
|
pascal@19515
|
72 isoopen("boot") >= 0 ||
|
pascal@19515
|
73 isoopen("live") >= 0 || // debian
|
pascal@19515
|
74 isoopen("casper") >= 0; // ubuntu
|
pascal@19515
|
75 if (iso[1] && !strcmp(mode = iso[1], "text"))
|
pascal@19515
|
76 init = "";
|
pascal@19515
|
77 do {
|
pascal@19515
|
78 if (isoopen(mode) >= 0 || // custom
|
pascal@19515
|
79 isoopen("bzImage") >= 0 || // SliTaz
|
pascal@19515
|
80 isoopen("vmlinuz") >= 0 || // misc
|
pascal@19515
|
81 (isoopen("linux") >= 0 && ++isknoppix)) {
|
pascal@19538
|
82 magic = kver2ul(isokernel());
|
pascal@19515
|
83 break;
|
pascal@19515
|
84 }
|
pascal@19515
|
85 } while (isoopen("isolinux") >= 0); // Knoppix
|
pascal@19515
|
86 fallback[0] = 0;
|
pascal@19515
|
87 for (c = 0, restart = 1; isoreaddir(restart) == 0; restart = 0) {
|
pascal@19515
|
88 if (strstr(isofilename, ".gz"))
|
pascal@19515
|
89 strcpy(fallback, isofilename);
|
pascal@19515
|
90 if (strhead(isofilename, "rootfs")
|
pascal@19515
|
91 || c > isofilename[6]) continue;
|
pascal@19515
|
92 strcpy(rootfs, isofilename);
|
pascal@19515
|
93 c = isofilename[6];
|
pascal@19515
|
94 }
|
pascal@19515
|
95
|
pascal@19515
|
96 strcpy(_cmdline,"rw root=/dev/null autologin bootfrom=");
|
pascal@19515
|
97 strcat(_cmdline,*iso);
|
pascal@19515
|
98 if (magic < 0x20630)
|
pascal@19515
|
99 init = ""; // Does not support multiple initramfs
|
pascal@19515
|
100
|
pascal@19515
|
101 if (magic > 0) {
|
pascal@19515
|
102 char *initrd = fallback;
|
pascal@19515
|
103
|
pascal@19515
|
104 if (rootfs[0]) {
|
pascal@19515
|
105 initrd = rootfs;
|
pascal@19515
|
106 if (rootfs[6] != '.' && isoopen("rootfs.gz") >= 0)
|
pascal@19515
|
107 addinitrd(); // for loram
|
pascal@19515
|
108 }
|
pascal@19515
|
109 if (isoopen(initrd) >= 0) {
|
pascal@19515
|
110 addinitrd();
|
pascal@19515
|
111 }
|
pascal@19538
|
112 if (*init && lseek(isofd, 20L, SEEK_SET) != -1) {
|
pascal@19538
|
113 read(isofd, &isofileofs, 4);
|
pascal@19538
|
114 read(isofd, &magic, 4);
|
pascal@19515
|
115 isofileofs &= 0xFFFFL;
|
pascal@19515
|
116 isofilesize = magic & 0xFFFFL;
|
pascal@19515
|
117 isofileofs -= 0xC0L + isofilesize;
|
pascal@19515
|
118 if (isofilesize) addinitrd();
|
pascal@19515
|
119 else init="";
|
pascal@19515
|
120 }
|
pascal@19515
|
121 load_initrds();
|
pascal@19515
|
122 strcat(_cmdline,init);
|
pascal@19538
|
123 strcatb(_cmdline,"mode=");
|
pascal@19515
|
124 strcat(_cmdline,mode);
|
pascal@19538
|
125 strcatb(_cmdline,"magic=");
|
pascal@19515
|
126 strcat(_cmdline,ultoa(magic));
|
pascal@19515
|
127 }
|
pascal@19515
|
128 if (isknoppix) {
|
pascal@19515
|
129 if (iso[0][1] == ':')
|
pascal@19515
|
130 *iso += 2;
|
pascal@19515
|
131 for (s = *iso; *s; s++)
|
pascal@19515
|
132 if (*s == '\\') *s = '/';
|
pascal@19515
|
133 }
|
pascal@19515
|
134 close(isofd);
|
pascal@19515
|
135 boot_kernel();
|
pascal@19515
|
136 }
|
pascal@19515
|
137
|
pascal@19515
|
138 u16 root_dev;
|
pascal@19515
|
139 u16 vid_mode;
|
pascal@19515
|
140 const char* kernel_name = "bzImage";
|
pascal@19515
|
141 const char* initrd_name;
|
pascal@19515
|
142 int main(int argc, char *argv[])
|
pascal@19515
|
143 {
|
pascal@19515
|
144 char *iso = NULL;
|
pascal@19515
|
145 argv[0] = progname();
|
pascal@19515
|
146 bootiso(argv); // iso ? parsing is /init.exe stuff !
|
pascal@19515
|
147
|
pascal@19515
|
148 if (argc < 2) {
|
pascal@19546
|
149 try_default_args();
|
pascal@19515
|
150 dousage:
|
pascal@19538
|
151 die("Usage: tazboot [[@commands]|[-f][kernel=<bzimage>] \
|
pascal@19538
|
152 [initrd=<rootfs>[,<rootfs2>...]] [bootfrom=<isofile>] ...]\r\n\n\
|
pascal@19538
|
153 Defaults: tazboot kernel=bzImage auto\r\n\n\
|
pascal@19538
|
154 Examples for tazboot.cmd:\r\n\n\
|
pascal@19538
|
155 bootfrom=\\isos\\slitaz-4.0.iso\r\n\
|
pascal@19538
|
156 kernel=boot/bzImage\r\n\
|
pascal@19538
|
157 initrd=boot/rootfs4.gz,boot/rootfs3.gz,boot/rootfs2.gz,boot/rootfs1.gz,\\slitaz\\extrafs.gz\r\n\
|
pascal@19538
|
158 rw root=/dev/null vga=normal autologin\r\n\n\
|
pascal@19538
|
159 kernel=\\slitaz\\elks\r\n\
|
pascal@19538
|
160 root=/dev/bda1 ro\r\n");
|
pascal@19515
|
161 }
|
pascal@19546
|
162 bootiso(argv + 1);
|
pascal@19546
|
163 chdirname(*argv);
|
pascal@19538
|
164 for (int i=0;;) {
|
pascal@19546
|
165 char *s;
|
pascal@19546
|
166 argv++;
|
pascal@19546
|
167 s=*argv;
|
pascal@19538
|
168 i++;
|
pascal@19538
|
169 if (!s) break;
|
pascal@19538
|
170 if (strhead(s,"kernel=") == 0) {
|
pascal@19538
|
171 s += 7;
|
pascal@19538
|
172 set_kernel:
|
pascal@19538
|
173 kernel_name = s;
|
pascal@19538
|
174 }
|
pascal@19538
|
175 else if (strhead(s,"image=") == 0) {
|
pascal@19538
|
176 s += 6;
|
pascal@19538
|
177 goto set_kernel;
|
pascal@19538
|
178 }
|
pascal@19538
|
179 else if (strhead(s,"initrd=") == 0) {
|
pascal@19538
|
180 s += 7;
|
pascal@19538
|
181 initrd_name = s;
|
pascal@19538
|
182 }
|
pascal@19538
|
183 else if (strhead(s,"bootfrom=") == 0) {
|
pascal@19538
|
184 s += 9;
|
pascal@19538
|
185 set_iso:
|
pascal@19538
|
186 iso = s;
|
pascal@19538
|
187 }
|
pascal@19538
|
188 else if (strhead(s,"iso=") == 0) {
|
pascal@19538
|
189 s += 4;
|
pascal@19538
|
190 goto set_iso;
|
pascal@19538
|
191 }
|
pascal@19515
|
192 else if(strhead(s,"vga=") == 0) {
|
pascal@19538
|
193 s += 4;
|
pascal@19538
|
194 vid_mode = strtol(s); // support normal, extended & ask
|
pascal@19515
|
195 }
|
pascal@19538
|
196 else if((*(u16 *)s|0x2002) == 0x662F) { // -F /f
|
pascal@19515
|
197 skip_xmmalloc++;
|
pascal@19515
|
198 }
|
pascal@19538
|
199 else if(i == 1 && fileattr(s) != -1) {
|
pascal@19538
|
200 goto set_kernel;
|
pascal@19538
|
201 }
|
pascal@19515
|
202 else {
|
pascal@19515
|
203 if(strhead(s,"root=") == 0) {
|
pascal@19538
|
204 s += 5;
|
pascal@19538
|
205 root_dev = strtol(s);
|
pascal@19515
|
206 }
|
pascal@19515
|
207 if(strhead(s,"mem=") == 0) {
|
pascal@19538
|
208 s += 4;
|
pascal@19538
|
209 topmem = strtol(s);
|
pascal@19515
|
210 }
|
pascal@19538
|
211 strcatb(_cmdline,*argv);
|
pascal@19515
|
212 }
|
pascal@19515
|
213 }
|
pascal@19515
|
214 if (iso && isoreset(iso) >= 0) {
|
pascal@19515
|
215 char *s = (char *) initrd_name;
|
pascal@19515
|
216 if (isoopen((char *) kernel_name) >= 0) {
|
pascal@19515
|
217 isokernel();
|
pascal@19515
|
218 }
|
pascal@19515
|
219 if (s) {
|
pascal@19515
|
220 while (*s) {
|
pascal@19515
|
221 char *p, c;
|
pascal@19515
|
222 for (p = s; *s && *s != ','; s++);
|
pascal@19515
|
223 c = *s; *s = 0;
|
pascal@19515
|
224 if (isoopen(p) >= 0) {
|
pascal@19515
|
225 addinitrd();
|
pascal@19515
|
226 }
|
pascal@19515
|
227 *s = c;
|
pascal@19515
|
228 if (c) s++;
|
pascal@19515
|
229 }
|
pascal@19515
|
230 load_initrds();
|
pascal@19515
|
231 }
|
pascal@19515
|
232 }
|
pascal@19515
|
233 else {
|
pascal@19515
|
234 load_kernel();
|
pascal@19515
|
235 load_initrd();
|
pascal@19515
|
236 }
|
pascal@19515
|
237 boot_kernel();
|
pascal@19515
|
238 return _AX;
|
pascal@19515
|
239 }
|