rev |
line source |
pascal@13691
|
1 #include <asm/limits.h>
|
pascal@13691
|
2 #include <sys/types.h>
|
pascal@13691
|
3 #include <unistd.h>
|
pascal@13691
|
4 #include <fcntl.h>
|
pascal@13691
|
5 #include <stdio.h>
|
pascal@13691
|
6 #include "iso9660.h"
|
pascal@13691
|
7 #include "bootlinux.h"
|
pascal@13691
|
8 #include "libdos.h"
|
pascal@13691
|
9
|
pascal@13691
|
10 static void usage(char *iso)
|
pascal@13691
|
11 {
|
pascal@13691
|
12 printf("Usage: %s [[@commands]|[kernel=<bzimage>] \
|
pascal@17489
|
13 [initrd=<rootfs>[,<rootfs2>...]] [bootfrom=<isofile>] ...]\n\n\
|
pascal@13691
|
14 Defaults: %s @tazboot.cmd or %s kernel=bzImage auto\n\n\
|
pascal@13691
|
15 Examples for tazboot.cmd:\n\n\
|
pascal@17489
|
16 bootfrom=\\isos\\slitaz-4.0.iso\n\
|
pascal@13691
|
17 kernel=boot/bzImage\n\
|
pascal@16012
|
18 initrd=boot/rootfs4.gz,boot/rootfs3.gz,boot/rootfs2.gz,boot/rootfs1.gz,\\slitaz\\extrafs.gz\n\
|
pascal@23890
|
19 root=/dev/null vga=normal autologin\n\n\
|
pascal@17491
|
20 kernel=\\slitaz\\elks\n\
|
pascal@17491
|
21 root=/dev/bda1 ro\n",iso,iso,iso);
|
pascal@13691
|
22 exit(1);
|
pascal@13691
|
23 }
|
pascal@13691
|
24
|
pascal@13691
|
25 static void bootiso(char **iso)
|
pascal@13691
|
26 {
|
pascal@16025
|
27 char *init = " rdinit=/init.exe", *mode="menu", *fmt="";
|
pascal@17489
|
28 char *s, c, rootfs[16], fallback[16], cmdline[256];
|
pascal@17489
|
29 int restart, isknoppix = 0;
|
pascal@13691
|
30 unsigned long magic;
|
pascal@13691
|
31
|
pascal@17489
|
32 if (isoreset(*iso)) return;
|
pascal@17489
|
33 !isoopen("boot") ||
|
pascal@17489
|
34 !isoopen("live") || // debian
|
pascal@17489
|
35 !isoopen("casper") || // ubuntu
|
pascal@17489
|
36 !isoopen("isolinux"); // zeroshell
|
pascal@13691
|
37 if (iso[1] && !strcmp(mode = iso[1], "text"))
|
pascal@13691
|
38 init = "";
|
pascal@17489
|
39 do {
|
pascal@17489
|
40 if (!isoopen(mode) || // custom
|
pascal@17489
|
41 !isoopen("bzImage") || // SliTaz
|
pascal@17489
|
42 !isoopen("vmlinuz") || // misc
|
pascal@17489
|
43 (!isoopen("linux") && ++isknoppix)) {
|
pascal@17489
|
44 magic = loadkernel();
|
pascal@17489
|
45 break;
|
pascal@17489
|
46 }
|
pascal@17489
|
47 } while (!isoopen("isolinux")); // Knoppix
|
pascal@17489
|
48 fallback[0] = 0;
|
pascal@13691
|
49 for (c = 0, restart = 1; isoreaddir(restart) == 0; restart = 0) {
|
pascal@17489
|
50 if (strstr(isofilename, ".gz"))
|
pascal@17489
|
51 strcpy(fallback, isofilename);
|
pascal@16002
|
52 if (strncmp(isofilename, "rootfs", 6)
|
pascal@16002
|
53 || c > isofilename[6]) continue;
|
pascal@13691
|
54 strcpy(rootfs, isofilename);
|
pascal@16002
|
55 c = isofilename[6];
|
pascal@13691
|
56 }
|
pascal@17489
|
57
|
pascal@16025
|
58 if (magic < 0x20630)
|
pascal@14257
|
59 init = ""; // Does not support multiple initramfs
|
pascal@17489
|
60
|
pascal@16025
|
61 if (magic > 0) {
|
pascal@17489
|
62 char *initrd = fallback;
|
pascal@17489
|
63
|
pascal@23890
|
64 fmt = "root=/dev/null bootfrom=%s%s magic=%lu mode=%s autologin";
|
pascal@17489
|
65 if (rootfs[0]) {
|
pascal@17489
|
66 initrd = rootfs;
|
pascal@17489
|
67 if (rootfs[6] != '.' && !isoopen("rootfs.gz"))
|
pascal@17489
|
68 loadinitrd(); // for loram
|
pascal@17489
|
69 }
|
pascal@17489
|
70 if (!isoopen(initrd)) {
|
pascal@17489
|
71 loadinitrd();
|
pascal@17489
|
72 }
|
pascal@16025
|
73 if (*init) {
|
pascal@17492
|
74 lseek(isofd, 20L, SEEK_SET);
|
pascal@17492
|
75 read(isofd, &isofileofs, 4);
|
pascal@17492
|
76 isofileofs &= 0xFFFFL;
|
pascal@16025
|
77 read(isofd, &magic, 4);
|
pascal@16025
|
78 isofilesize = magic & 0xFFFFL;
|
pascal@17492
|
79 isofileofs -= 0xC0L + isofilesize;
|
pascal@16025
|
80 if (isofilesize) loadinitrd();
|
pascal@16025
|
81 else init="";
|
pascal@16025
|
82 }
|
pascal@16025
|
83 }
|
pascal@17489
|
84 if (isknoppix) {
|
pascal@17489
|
85 if (iso[0][1] == ':')
|
pascal@17489
|
86 *iso += 2;
|
pascal@17489
|
87 for (s = *iso; *s; s++)
|
pascal@17489
|
88 if (*s == '\\') *s = '/';
|
pascal@17489
|
89 }
|
pascal@17489
|
90 sprintf(cmdline, fmt, *iso, init, magic, mode);
|
pascal@13691
|
91 close(isofd);
|
pascal@13691
|
92 bootlinux(cmdline);
|
pascal@13691
|
93 }
|
pascal@13691
|
94
|
pascal@13691
|
95 static int stricmp(char *ref, char *s)
|
pascal@13691
|
96 {
|
pascal@13691
|
97 char c;
|
pascal@13691
|
98 while (*ref) {
|
pascal@13691
|
99 c = *s++;
|
pascal@13691
|
100 if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
|
pascal@13691
|
101 c -= *ref++;
|
pascal@13691
|
102 if (c) return c;
|
pascal@13691
|
103 }
|
pascal@13691
|
104 return 0;
|
pascal@13691
|
105 }
|
pascal@13691
|
106
|
pascal@16022
|
107 static int chkstatus(int status, char *name)
|
pascal@16022
|
108 {
|
pascal@16022
|
109 if (status == -1)
|
pascal@16022
|
110 printf("%s not found.\n",name);
|
pascal@16022
|
111 return status;
|
pascal@16022
|
112 }
|
pascal@16022
|
113
|
pascal@13691
|
114 static char *iso;
|
pascal@13691
|
115 static int fakeopen(char *file)
|
pascal@13691
|
116 {
|
pascal@16002
|
117 if (file) {
|
pascal@16002
|
118 char *s = file;
|
pascal@16002
|
119 while (*s && *s != '\r' && *s != '\n') s++;
|
pascal@16002
|
120 *s = 0;
|
pascal@16002
|
121 }
|
pascal@16012
|
122 if (*file == '\\') {
|
pascal@16012
|
123 static fd = -1;
|
pascal@16012
|
124 if (fd >= 0) close(fd);
|
pascal@16022
|
125 fd = chkstatus(open(file, O_RDONLY), file);
|
pascal@16022
|
126 return fd;
|
pascal@16012
|
127 }
|
pascal@13691
|
128 if (iso) {
|
pascal@16022
|
129 chkstatus(isoreset(iso), iso);
|
pascal@16022
|
130 return chkstatus(isoopen(file), file);
|
pascal@13691
|
131 }
|
pascal@13691
|
132 close(isofd);
|
pascal@16022
|
133 isofd = chkstatus(open(file, O_RDONLY), file);
|
pascal@13691
|
134 if (isofd != -1) {
|
pascal@13691
|
135 isofileofs = 0;
|
pascal@13691
|
136 isofilesize = LONG_MAX;
|
pascal@13691
|
137 }
|
pascal@13691
|
138 return isofd;
|
pascal@13691
|
139 }
|
pascal@13691
|
140
|
pascal@13691
|
141 static char args[2048];
|
pascal@13691
|
142 int main(int argc, char *argv[])
|
pascal@13691
|
143 {
|
pascal@13691
|
144 char *kernel, *initrd, *cmdline, *cmdfile, *s;
|
pascal@13691
|
145
|
pascal@13691
|
146 argv[0] = progname();
|
pascal@14268
|
147 bootiso(argv); // iso ? parsing is /init.exe stuff !
|
pascal@16022
|
148 if (argc >= 2)
|
pascal@14268
|
149 bootiso(argv + 1);
|
pascal@13691
|
150
|
pascal@13691
|
151 chdirname(*argv);
|
pascal@13691
|
152 cmdfile = "tazboot.cmd";
|
pascal@13691
|
153 kernel = "bzImage";
|
pascal@13691
|
154 initrd = NULL;
|
pascal@13691
|
155 cmdline = "auto";
|
pascal@13691
|
156 if (argc > 1) {
|
pascal@19435
|
157 switch (argv[1][0]) {
|
pascal@19435
|
158 case '-' : case '/' : case '?' :
|
pascal@19435
|
159 usage(argv[0]); break;
|
pascal@19435
|
160 case '@' :
|
pascal@19435
|
161 cmdfile = argv[1] + 1; break;
|
pascal@19435
|
162 default :
|
pascal@13691
|
163 cmdfile = NULL;
|
pascal@17562
|
164 copycmdline(args);
|
pascal@13691
|
165 }
|
pascal@13691
|
166 }
|
pascal@13691
|
167 if (cmdfile) {
|
pascal@13691
|
168 int fd;
|
pascal@16025
|
169 fd = chkstatus(open(cmdfile, O_RDONLY), cmdfile);
|
pascal@13691
|
170 if (fd != -1) {
|
pascal@13691
|
171 read(fd, args, sizeof(args));
|
pascal@13691
|
172 close(fd);
|
pascal@13691
|
173 for (s = args; s < args + sizeof(args) -1; s++) {
|
pascal@13691
|
174 if (*s == '\r') *s++ = ' ';
|
pascal@13691
|
175 if (*s == '\n') *s = ' ';
|
pascal@13691
|
176 }
|
pascal@13691
|
177 }
|
pascal@13691
|
178 }
|
pascal@13691
|
179 for (s = args; s < args + sizeof(args); s++) {
|
pascal@13691
|
180 if (*s == ' ') continue;
|
pascal@13691
|
181 if (stricmp("kernel=", s) == 0)
|
pascal@13691
|
182 kernel = s + 7;
|
pascal@13691
|
183 else if (stricmp("initrd=", s) == 0)
|
pascal@13691
|
184 initrd = s + 7;
|
pascal@17489
|
185 else if (stricmp("bootfrom=", s) == 0)
|
pascal@13691
|
186 iso = s + 4;
|
pascal@13691
|
187 else {
|
pascal@13691
|
188 cmdline = s;
|
pascal@13691
|
189 break;
|
pascal@13691
|
190 }
|
pascal@13691
|
191 while (*s && *s != ' ') s++;
|
pascal@13691
|
192 *s = 0;
|
pascal@13691
|
193 }
|
pascal@16002
|
194 if (cmdline) {
|
pascal@16002
|
195 char *last;
|
pascal@19403
|
196 for (s = last = cmdline; *s && *s != '\r' && *s != '\n'; s++)
|
pascal@16002
|
197 if (*s != ' ') last = s;
|
pascal@16002
|
198 *++last = 0;
|
pascal@16002
|
199 }
|
pascal@13691
|
200 if (fakeopen(kernel) == -1)
|
pascal@13691
|
201 usage(argv[0]);
|
pascal@13691
|
202 loadkernel();
|
pascal@13691
|
203 if (initrd) {
|
pascal@13691
|
204 char *p, *q = initrd;
|
pascal@13691
|
205 while (1) {
|
pascal@13691
|
206 char c;
|
pascal@13691
|
207 for (p = q; *p && *p != ','; p++);
|
pascal@13691
|
208 c = *p;
|
pascal@13691
|
209 *p = 0;
|
pascal@13691
|
210 if (fakeopen(q) != -1)
|
pascal@13691
|
211 loadinitrd();
|
pascal@13691
|
212 if (c == 0)
|
pascal@13691
|
213 break;
|
pascal@13691
|
214 q = ++p;
|
pascal@13691
|
215 }
|
pascal@13691
|
216 }
|
pascal@13691
|
217 bootlinux(cmdline);
|
pascal@13691
|
218 }
|