wok-current diff linld/stuff/src/TAZBOOT.CPP @ rev 19515
linld: multi initrd support
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Tue Nov 22 21:19:01 2016 +0100 (2016-11-22) |
parents | |
children | 7f92b23984dc |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/linld/stuff/src/TAZBOOT.CPP Tue Nov 22 21:19:01 2016 +0100 1.3 @@ -0,0 +1,228 @@ 1.4 +// This file is distributed under GPL 1.5 +// 1.6 +// TAZBOOT main() lives here 1.7 + 1.8 +#include "crtl.h" 1.9 +#include "crtlx.h" 1.10 +#include "common.h" 1.11 +#include "iso9660.h" 1.12 + 1.13 +static void usage() 1.14 +{ 1.15 + puts("Usage: tazboot [[@commands]|[kernel=<bzimage>] \ 1.16 +[initrd=<rootfs>[,<rootfs2>...]] [bootfrom=<isofile>] ...]\r\n\n\ 1.17 +Defaults: tazboot kernel=bzImage auto\r\n\n\ 1.18 +Examples for tazboot.cmd:\r\n\n\ 1.19 + bootfrom=\\isos\\slitaz-4.0.iso\r\n\ 1.20 + kernel=boot/bzImage\r\n\ 1.21 + initrd=boot/rootfs4.gz,boot/rootfs3.gz,boot/rootfs2.gz,boot/rootfs1.gz,\\slitaz\\extrafs.gz\r\n\ 1.22 + rw root=/dev/null vga=normal autologin\r\n\n\ 1.23 + kernel=\\slitaz\\elks\r\n\ 1.24 + root=/dev/bda1 ro\r\n"); 1.25 + exit(1); 1.26 +} 1.27 + 1.28 +#define MAXINITRD 10 1.29 +static struct initrd_state { 1.30 + u32 ofs[MAXINITRD]; 1.31 + u32 size[MAXINITRD]; 1.32 + u16 cnt; 1.33 +} initrd_state; 1.34 + 1.35 +static void next_chunk(struct image_himem *m) 1.36 +{ 1.37 + m->chunk_size = 0; 1.38 + if (m->state >= initrd_state.cnt) return; 1.39 + lseek(m->fd,initrd_state.ofs[m->state],SEEK_SET); 1.40 + m->chunk_size = initrd_state.size[m->state]; 1.41 + m->state++; 1.42 +} 1.43 + 1.44 +static void addinitrd() 1.45 +{ 1.46 + if (initrd_state.cnt >= MAXINITRD) return; 1.47 + initrd_state.size[initrd_state.cnt] = isofilesize; 1.48 + initrd_state.ofs[initrd_state.cnt] = isofileofs; 1.49 + initrd_state.cnt++; 1.50 + initrd.size += (isofilesize+3)&-4; 1.51 +} 1.52 + 1.53 +static void load_initrds() 1.54 +{ 1.55 + if (!initrd.size) return; 1.56 + initrd.next_chunk = next_chunk; 1.57 + initrd.fd = isofd; 1.58 + initrd.state = 0; 1.59 + next_chunk(&initrd); 1.60 + load_initrd(); 1.61 +} 1.62 + 1.63 +static void pm_next_chunk(struct image_himem *m) 1.64 +{ 1.65 + if (!m->state++) m->chunk_size = m->size; 1.66 +} 1.67 + 1.68 +static void isokernel() 1.69 +{ 1.70 + pm.size = (isofilesize+3)&-4; 1.71 + pm.fd = isofd; 1.72 + pm.next_chunk = pm_next_chunk; 1.73 +} 1.74 + 1.75 +char _cmdline[256]; 1.76 +const char *cmdline = (const char *) _cmdline; 1.77 +extern int skip_xmmalloc; 1.78 +static void bootiso(char **iso) 1.79 +{ 1.80 + char *init = " rdinit=/init.exe", *mode="menu"; 1.81 + char *s, c, rootfs[16], fallback[16]; 1.82 + int restart, isknoppix = 0; 1.83 + unsigned long magic; 1.84 + 1.85 + if (!*iso || isoreset(*iso) < 0) return; 1.86 + skip_xmmalloc++; 1.87 + isoopen("boot") >= 0 || 1.88 + isoopen("live") >= 0 || // debian 1.89 + isoopen("casper") >= 0; // ubuntu 1.90 + if (iso[1] && !strcmp(mode = iso[1], "text")) 1.91 + init = ""; 1.92 + do { 1.93 + if (isoopen(mode) >= 0 || // custom 1.94 + isoopen("bzImage") >= 0 || // SliTaz 1.95 + isoopen("vmlinuz") >= 0 || // misc 1.96 + (isoopen("linux") >= 0 && ++isknoppix)) { 1.97 + isokernel(); 1.98 + magic = kver2ul(load_kernel()); 1.99 + break; 1.100 + } 1.101 + } while (isoopen("isolinux") >= 0); // Knoppix 1.102 + fallback[0] = 0; 1.103 + for (c = 0, restart = 1; isoreaddir(restart) == 0; restart = 0) { 1.104 + if (strstr(isofilename, ".gz")) 1.105 + strcpy(fallback, isofilename); 1.106 + if (strhead(isofilename, "rootfs") 1.107 + || c > isofilename[6]) continue; 1.108 + strcpy(rootfs, isofilename); 1.109 + c = isofilename[6]; 1.110 + } 1.111 + 1.112 + strcpy(_cmdline,"rw root=/dev/null autologin bootfrom="); 1.113 + strcat(_cmdline,*iso); 1.114 + if (magic < 0x20630) 1.115 + init = ""; // Does not support multiple initramfs 1.116 + 1.117 + if (magic > 0) { 1.118 + char *initrd = fallback; 1.119 + 1.120 + if (rootfs[0]) { 1.121 + initrd = rootfs; 1.122 + if (rootfs[6] != '.' && isoopen("rootfs.gz") >= 0) 1.123 + addinitrd(); // for loram 1.124 + } 1.125 + if (isoopen(initrd) >= 0) { 1.126 + addinitrd(); 1.127 + } 1.128 + if (*init && lseek(isofd, 20L, SEEK_SET) != -1 && 1.129 + read(isofd, &isofileofs, 4) == 4 && 1.130 + read(isofd, &magic, 4) == 4) { 1.131 + isofileofs &= 0xFFFFL; 1.132 + isofilesize = magic & 0xFFFFL; 1.133 + isofileofs -= 0xC0L + isofilesize; 1.134 + if (isofilesize) addinitrd(); 1.135 + else init=""; 1.136 + } 1.137 + load_initrds(); 1.138 + strcat(_cmdline,init); 1.139 + strcat(_cmdline," mode="); 1.140 + strcat(_cmdline,mode); 1.141 + strcat(_cmdline," magic="); 1.142 + strcat(_cmdline,ultoa(magic)); 1.143 + } 1.144 + if (isknoppix) { 1.145 + if (iso[0][1] == ':') 1.146 + *iso += 2; 1.147 + for (s = *iso; *s; s++) 1.148 + if (*s == '\\') *s = '/'; 1.149 + } 1.150 + close(isofd); 1.151 + boot_kernel(); 1.152 +} 1.153 + 1.154 +u16 root_dev; 1.155 +u16 vid_mode; 1.156 +const char* kernel_name = "bzImage"; 1.157 +const char* initrd_name; 1.158 +int main(int argc, char *argv[]) 1.159 +{ 1.160 + char *iso = NULL; 1.161 + argv[0] = progname(); 1.162 + bootiso(argv); // iso ? parsing is /init.exe stuff ! 1.163 + if (argc >= 2) 1.164 + bootiso(argv + 1); 1.165 + 1.166 + chdirname(*argv); 1.167 + if (argc < 2) { 1.168 +dousage: 1.169 + usage(); 1.170 + } 1.171 + for (int i=1; i < argc; i++) { 1.172 + char *s=argv[i]; 1.173 + if (strhead(s,"kernel=") == 0) 1.174 + kernel_name = s + 7; 1.175 + if (strhead(s,"image=") == 0) 1.176 + kernel_name = s + 6; 1.177 + else if (strhead(s,"initrd=") == 0) 1.178 + initrd_name = s + 7; 1.179 + else if (strhead(s,"bootfrom=") == 0) 1.180 + iso = s + 9; 1.181 + else if (strhead(s,"iso=") == 0) 1.182 + iso = s + 4; 1.183 + else if(strhead(s,"vga=") == 0) { 1.184 + s+=4; 1.185 + const char c = *s|0x20; 1.186 + if (c == 'a') vid_mode = -3; 1.187 + else if (c == 'e') vid_mode = -2; 1.188 + else if (c == 'n') vid_mode = -1; 1.189 + else vid_mode = strtol(s); 1.190 + } 1.191 + else if(strhead(s,"-f") == 0) { 1.192 + skip_xmmalloc++; 1.193 + } 1.194 + else { 1.195 + if(strhead(s,"root=") == 0) { 1.196 + root_dev = strtol(s+5); 1.197 + } 1.198 + if(strhead(s,"mem=") == 0) { 1.199 + topmem = strtol(s+4); 1.200 + } 1.201 + if (_cmdline[0]) strcat(_cmdline," "); 1.202 + strcat(_cmdline,s); 1.203 + } 1.204 + } 1.205 + if (iso && isoreset(iso) >= 0) { 1.206 + char *s = (char *) initrd_name; 1.207 + if (isoopen((char *) kernel_name) >= 0) { 1.208 + isokernel(); 1.209 + load_kernel(); 1.210 + } 1.211 + if (s) { 1.212 + while (*s) { 1.213 + char *p, c; 1.214 + for (p = s; *s && *s != ','; s++); 1.215 + c = *s; *s = 0; 1.216 + if (isoopen(p) >= 0) { 1.217 + addinitrd(); 1.218 + } 1.219 + *s = c; 1.220 + if (c) s++; 1.221 + } 1.222 + load_initrds(); 1.223 + } 1.224 + } 1.225 + else { 1.226 + load_kernel(); 1.227 + load_initrd(); 1.228 + } 1.229 + boot_kernel(); 1.230 + return _AX; 1.231 +}