2 * Linux As Bootloader main entry point
4 * Authors: Andrew Zabolotny <zap@homelink.ru>
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive for
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/version.h>
17 #include <linux/syscalls.h>
18 #include <linux/lab/lab.h>
19 #include <linux/lab/commands.h>
21 void lab_runfile(char *source
, char *sourcefile
);
24 EXPORT_SYMBOL (globfail
);
26 static int cmdline
= 0;
28 static int __init
forcecli_setup(char *__unused
)
30 printk ("lab: Skipping autoboot due to forcecli parameter.\n");
34 __setup("forcecli", forcecli_setup
);
36 static void print_version (void)
38 lab_puts ("LAB - Linux As Bootloader, " UTS_RELEASE
"\r\n");
41 static void print_banner (void)
44 lab_puts ("Contact: bootldr@handhelds.org\r\n\r\n");
46 lab_puts ("Copyright (c) 2003-2004 Joshua Wise, Andrew Zabolotny and others.\r\n");
47 lab_puts ("Based on Linux kernel, which is copyright (c) Linus Torvalds and others.\r\n");
48 lab_puts ("Partially based on OHH bootldr, which is copyright (c) COMPAQ Computer Corporation.\r\n");
49 lab_puts ("This program is provided with NO WARRANTY under the terms of the\r\nGNU General Public License.\r\n");
59 static void parseargs (char *argstr
, int *argc_p
, char **argv
, char **resid
)
63 enum ParseState lastState
= PS_WHITESPACE
;
64 enum ParseState stackedState
= PS_WHITESPACE
;
66 /* tokenize the argstr */
67 while ((c
= *argstr
) != 0) {
68 enum ParseState newState
;
70 if ((c
== ';' || c
== '\n') && lastState
!= PS_STRING
&& lastState
!= PS_ESCAPE
)
73 if (lastState
== PS_ESCAPE
) {
74 newState
= stackedState
;
75 } else if (lastState
== PS_STRING
) {
77 newState
= PS_WHITESPACE
;
82 } else if ((c
== ' ') || (c
== '\t')) {
83 /* whitespace character */
85 newState
= PS_WHITESPACE
;
86 } else if (c
== '"') {
89 argv
[argc
++] = argstr
+ 1;
90 } else if (c
== '\\') {
91 stackedState
= lastState
;
95 if (lastState
== PS_WHITESPACE
) {
96 argv
[argc
++] = argstr
;
101 lastState
= newState
;
109 if (*argstr
== ';' || *argstr
== '\n')
116 // Commented out until we find a use for it -- zap
118 // this is getting more compliacated, this function will averride any of the
119 // args in argstr with tthe args from argv. this will allow you to override the
120 // param linuxargs from the commandline. e.g. init=/myRC will override
121 // init=linuxRC from the params.
122 static void unparseargs(char *argstr
, int argc
, const char **argv
)
131 for (i
= 0; i
< argc
; i
++) {
132 if (argv
[i
] != NULL
) {
133 // we have an a=b arg
134 if ((paramEnd
= strchr(argv
[i
],'='))) {
135 int argstrlen
= strlen(argstr
);
139 lab_puts("haystack = <");
143 needlelen
= (int)(paramEnd
- argv
[i
]);
144 strncpy(needle
, argv
[i
], needlelen
);
145 needle
[needlelen
] = 0;
146 lab_puts("needle = <");
147 putnstr(needle
,needlelen
);
150 if ((cutStart
= (char *)strstr(argstr
, needle
)) != NULL
){
152 if (!(cutEnd
= strchr(cutStart
,' '))) {
153 cutEnd
= argstr
+ argstrlen
;
155 cutEnd
++; // skip the space
157 delta
= (int)(cutEnd
- cutStart
);
158 for (j
=(int) (cutEnd
- argstr
); j
< argstrlen
; j
++)
159 argstr
[j
-delta
] = argstr
[j
];
161 argstr
[argstrlen
- delta
] = '\0';
166 strcat(argstr
, argv
[i
]);
172 void lab_exec_string (char *buf
)
179 memset (argv
, 0, sizeof (argv
));
180 parseargs (buf
, &argc
, argv
, &resid
);
182 lab_execcommand (argc
, (char**) argv
);
184 lab_exec_string ("help");
188 EXPORT_SYMBOL (lab_exec_string
);
190 static char *blockdevs
[] = {
191 "/dev/mmcblk0p1", "ext2", "root=/dev/mmcblk0p1",
192 "/dev/mmcblk0p2", "ext2", "root=/dev/mmcblk0p2",
193 "/dev/mmcblk0p3", "ext2", "root=/dev/mmcblk0p3",
194 "/dev/mmcblk0p4", "ext2", "root=/dev/mmcblk0p4",
195 "/dev/hda1", "ext2", "root=/dev/hda1 rootdelay=5",
196 "/dev/hda2", "ext2", "root=/dev/hda2 rootdelay=5",
197 "/dev/hda3", "ext2", "root=/dev/hda3 rootdelay=5",
198 "/dev/hda4", "ext2", "root=/dev/hda4 rootdelay=5",
199 "/dev/hda5", "ext2", "root=/dev/hda5 rootdelay=5",
200 "/dev/hda6", "ext2", "root=/dev/hda6 rootdelay=5",
201 "/dev/hda7", "ext2", "root=/dev/hda7 rootdelay=5",
202 "/dev/mtdblock3", "jffs2", "root=/dev/mtdblock3 rootfstype=jffs2",
207 void lab_main (int cmdline
)
214 unsigned char *contents
;
217 for (tleft
= 3; tleft
> 0; tleft
--)
219 lab_printf("\r>> LAB autoboot starting in %d seconds - press a key to abort", tleft
);
221 if (lab_getc_seconds(NULL
, 1))
223 lab_printf("\r\n>> Autoboot aborted\r\n");
227 if (lab_initconsole())
229 lab_printf("\r>> LAB autoboot delayed due to new console\n");
230 tleft
= 5+1; // give the user time to open a console and hit a key
234 ">> Booting now.\r\n");
235 sys_mkdir("/mnt", 0000);
236 sys_mount("/dev", "/dev", "devfs", 0, "");
237 lab_puts (">> Looking for filesystems...\r\n");
238 blockdev
= blockdevs
;
243 lab_printf(" >> Trying \"%s\"... ", blockdev
[0]);
244 if (sys_mount(blockdev
[0], "/mnt", blockdev
[1],
245 MS_RDONLY
, "") < 0) {
247 lab_printf("failed\r\n");
254 if (sys_newstat("/mnt/boot/labrun", &sstat
) >= 0) {
256 lab_printf(">> Executing labrun... ");
257 lab_runfile("fs", "/mnt/boot/labrun");
258 lab_printf("done\r\n");
261 lab_printf("; no labrun");
263 if (sys_newstat("/mnt/boot/zImage", &sstat
) >= 0) {
264 lab_printf("; found zImage\r\n");
265 lab_printf(">> Copying zImage... ");
266 lab_copy("fs", "/mnt/boot/zImage", "fs", "/zImage");
267 lab_printf("done\r\n>> Unmounting filesystem... ");
268 sys_oldumount("/mnt");
269 lab_printf("done\r\n>> Booting kernel.\r\n");
270 lab_armboot("fs", "/zImage", blockdev
[2]);
273 lab_printf(", no zImage.\r\n");
274 sys_oldumount("/mnt");
279 lab_printf(">> No bootable filesystems found!\r\n");
285 lab_readline (cmdbuff
, sizeof cmdbuff
);
288 lab_exec_string (cmdbuff
);
292 extern void lab_cmd_showlogo(int argc
,const char** argv
);
298 #ifdef CONFIG_LAB_BOOTLOGO
299 lab_cmd_showlogo(0, NULL
);
302 printk (KERN_INFO
"lab: Starting LAB [Linux As Bootloader]\n");
303 err
= sys_mount ("none", "/root", "ramfs", 0, "");
305 printk (KERN_ERR
"lab: Failed to mount ramfs! err=%d, halting\n", err
);
309 err
= sys_chdir ("/root");
311 printk (KERN_ERR
"lab: chdir /root failed for some reason, halting\n");
317 printk (KERN_INFO
"lab: running.\n");