wok annotate linld/stuff/src/TAZBOOT.CPP @ rev 19781

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