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