wok diff syslinux/stuff/iso2exe/bootlinux.c @ rev 16022
syslinux/iso2exe: add zimage support
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Thu Mar 06 19:57:41 2014 +0000 (2014-03-06) |
parents | 825165c08d25 |
children | d814ca840c3c |
line diff
1.1 --- a/syslinux/stuff/iso2exe/bootlinux.c Tue Mar 04 16:29:56 2014 +0000 1.2 +++ b/syslinux/stuff/iso2exe/bootlinux.c Thu Mar 06 19:57:41 2014 +0000 1.3 @@ -1,7 +1,7 @@ 1.4 #include <stdio.h> 1.5 #include "iso9660.h" 1.6 1.7 -static unsigned version; 1.8 +static unsigned setup_version; 1.9 #define SETUPSECTORS 0x1F1 1.10 #define ROFLAG 0x1F2 1.11 #define SYSSIZE 0x1F4 1.12 @@ -24,9 +24,9 @@ 1.13 1.14 #define PAGE_BITS 12 1.15 #define PAGE_SIZE 4096 1.16 -#define BUFFERSZ PAGE_SIZE 1.17 +#define BUFFERSZ 2048 // lower than mix setup 1.18 static char buffer[BUFFERSZ]; 1.19 -static unsigned long initrd_addr, initrd_size; 1.20 +static unsigned long initrd_addr = 0, initrd_size; 1.21 1.22 static int may_exit_dos = 1; 1.23 static void die(char *msg) 1.24 @@ -45,12 +45,10 @@ 1.25 #endasm 1.26 } 1.27 1.28 -static struct mem { 1.29 +static struct { 1.30 unsigned long base; 1.31 int align; 1.32 -} kernelmem = { 0x100000, 0 }; 1.33 - 1.34 -#define initrdmem kernelmem 1.35 +} mem = { 0x100000, 0 }; 1.36 1.37 static void movehi(void) 1.38 { 1.39 @@ -61,7 +59,7 @@ 1.40 zero1: 1.41 push di 1.42 loop zero1 1.43 - push dword [_kernelmem] // 1A p->base 1.44 + push dword [_mem] // 1A mem.base 1.45 push #-1 // 18 1.46 push di // 16 1.47 xor eax, eax 1.48 @@ -90,7 +88,18 @@ 1.49 #endasm 1.50 } 1.51 1.52 -#undef ZIMAGE_SUPPORT /* Does not work... */ 1.53 +#define ZIMAGE_SUPPORT 1.54 + 1.55 +#ifdef ZIMAGE_SUPPORT 1.56 +static int zimage = 0; 1.57 +static unsigned zimage_base; 1.58 +static unsigned getss(void) 1.59 +{ 1.60 +#asm 1.61 + mov ax, ss 1.62 +#endasm 1.63 +} 1.64 +#endif 1.65 1.66 static int versiondos; 1.67 static int dosversion(void) 1.68 @@ -114,11 +123,11 @@ 1.69 #endasm 1.70 } 1.71 1.72 -static void load(struct mem *p, unsigned long size) 1.73 +static void load(unsigned long size) 1.74 { 1.75 if (vm86()) 1.76 die("Need real mode"); 1.77 - switch (p->align) { 1.78 + switch (mem.align) { 1.79 case 0: // kernel 1.80 switch (dosversion()) { 1.81 case 3: case 4: case 6: case 7: break; 1.82 @@ -126,29 +135,27 @@ 1.83 printf("DOS %d not supported.\nTrying anyway...\n", 1.84 versiondos); 1.85 } 1.86 - p->align = PAGE_SIZE; 1.87 + mem.align = PAGE_SIZE; 1.88 break; 1.89 case PAGE_SIZE: // first initrd : keep 16M..48M for the kernel 1.90 - if (extendedramsizeinkb() > 0xF000U && p->base < 0x3000000) 1.91 - p->base = 0x3000000; 1.92 - initrd_addr = p->base; 1.93 - p->align = 4; 1.94 + if (extendedramsizeinkb() > 0xF000U && mem.base < 0x3000000) 1.95 + mem.base = 0x3000000; 1.96 + initrd_addr = mem.base; 1.97 + mem.align = 4; 1.98 } 1.99 while (size) { 1.100 int n, s = sizeof(buffer); 1.101 for (n = 0; n < s; n++) buffer[n] = 0; 1.102 if (s > size) s = size; 1.103 - n = isoread(buffer, s); 1.104 + if ((n = isoread(buffer, s)) < 0) break; 1.105 movehi(); 1.106 - if (n != -1) { 1.107 - p->base += n; 1.108 - size -= n; 1.109 - } 1.110 - if (s != n) break; 1.111 + mem.base += n; 1.112 + size -= n; 1.113 + if (s != n) break; // end of file 1.114 } 1.115 - initrd_size = p->base - initrd_addr; 1.116 - p->base += p->align - 1; 1.117 - p->base &= - p->align; 1.118 + initrd_size = mem.base - initrd_addr; 1.119 + mem.base += mem.align - 1; 1.120 + mem.base &= - mem.align; 1.121 } 1.122 1.123 static unsigned setupofs = 0; 1.124 @@ -189,13 +196,13 @@ 1.125 setup = (1 + buffer[SETUPSECTORS]) << 9; 1.126 if (setup == 512) setup = 5 << 9; 1.127 syssize = * (unsigned long *) (buffer + SYSSIZE) << 4; 1.128 - version = * (unsigned short *) (buffer + VERSION); 1.129 + setup_version = * (unsigned short *) (buffer + VERSION); 1.130 #define HDRS 0x53726448 1.131 if (* (unsigned long *) (buffer + HEADER) != HDRS) 1.132 - version = 0; 1.133 - if (version < 0x204) 1.134 + setup_version = 0; 1.135 + if (setup_version < 0x204) 1.136 syssize &= 0x000FFFFFUL; 1.137 - if (version) { 1.138 + if (setup_version) { 1.139 #ifdef REALMODE_SWITCH 1.140 extern int far_realmode_switch(); 1.141 #asm 1.142 @@ -213,7 +220,7 @@ 1.143 * (unsigned short *) (buffer + RMSWSEG) = 1.144 getcs(); 1.145 #endif 1.146 - kernelmem.base = 1.147 + mem.base = 1.148 * (unsigned long *) (buffer + SYSTEMCODE); 1.149 * (unsigned short *) (buffer + HEAPPTR) = 1.150 0x9B00; 1.151 @@ -221,34 +228,16 @@ 1.152 * (unsigned short *) (buffer + LOADERTYPE) |= 1.153 0x80FF; 1.154 } 1.155 - if (!version || !(buffer[LOADFLAGS] & 1)) { 1.156 + if (!setup_version || !(buffer[LOADFLAGS] & 1)) { 1.157 #ifdef ZIMAGE_SUPPORT 1.158 -#asm 1.159 - pusha 1.160 - mov cx, #0x8000 1.161 - mov es, cx 1.162 - xor si, si 1.163 - xor di, di 1.164 - rep 1.165 - movsw // move 64K data 1.166 - push es 1.167 - pop ds 1.168 - push es 1.169 - pop ss 1.170 - mov ch, #0x70 1.171 - mov es, cx 1.172 - mov ch, #0x80 1.173 - rep 1.174 - seg cs 1.175 - movsw // move 64K code 1.176 - popa 1.177 - jmpi relocated, #0x7000 1.178 -relocated: 1.179 -#endasm 1.180 - kernelmem.base = 0x10000; 1.181 - if (syssize > 0x60000) /* 384K max */ 1.182 + zimage = 1; 1.183 + zimage_base = getss() + 0x1000L; 1.184 + mem.base = zimage_base * 16L; 1.185 + if (mem.base + syssize > SETUP_SEGMENT*16L - 32) 1.186 + die("Out of memory"); 1.187 +#else 1.188 + die("Not a bzImage format"); 1.189 #endif 1.190 - die("Not a bzImage format"); 1.191 } 1.192 } 1.193 movesetup(); 1.194 @@ -281,16 +270,18 @@ 1.195 loop next 1.196 pop ds 1.197 mov .loadkernel.kernel_version[bp], edx 1.198 + push ds 1.199 noversion: 1.200 + pop ds 1.201 #endasm 1.202 - load(&kernelmem, syssize); 1.203 + load(syssize); 1.204 return kernel_version; 1.205 } 1.206 1.207 void loadinitrd(void) 1.208 { 1.209 - if (version) 1.210 - load(&initrdmem, isofilesize); 1.211 + if (setup_version && zimage == 0) 1.212 + load(isofilesize); 1.213 } 1.214 1.215 void bootlinux(char *cmdline) 1.216 @@ -298,6 +289,9 @@ 1.217 #asm 1.218 push #SETUP_SEGMENT 1.219 pop es 1.220 + push es 1.221 + pop ss 1.222 + mov sp, #CMDLINE_OFFSET 1.223 mov eax, _initrd_addr 1.224 or eax, eax 1.225 jz no_initrd 1.226 @@ -308,7 +302,7 @@ 1.227 no_initrd: 1.228 #endasm 1.229 if (cmdline) { 1.230 - if (version <= 0x201) { 1.231 + if (setup_version <= 0x201) { 1.232 #asm 1.233 mov di, #0x0020 1.234 mov ax, #0xA33F 1.235 @@ -334,12 +328,45 @@ 1.236 jne copy 1.237 #endasm 1.238 } 1.239 +#ifdef ZIMAGE_SUPPORT 1.240 + if (zimage) { 1.241 #asm 1.242 - push es 1.243 + mov eax, _mem 1.244 + shr eax, #4 // top 1.245 + mov bx, _zimage_base 1.246 + mov dx, #0x1000 1.247 + push cs 1.248 + pop ds 1.249 + mov es, ax 1.250 + push es 1.251 + mov si, #sysmove 1.252 + xor di, di 1.253 + push di 1.254 + mov cx, #endsysmove-sysmove 1.255 + rep 1.256 + movsb 1.257 + retf 1.258 +sysmove: 1.259 + mov ds, bx 1.260 + mov es, dx 1.261 + xor di, di 1.262 + xor si, si 1.263 + mov cl, #8 1.264 + rep 1.265 + movsw 1.266 + inc bx 1.267 + inc dx 1.268 + cmp ax,bx 1.269 + jne sysmove 1.270 +#endasm 1.271 + } 1.272 +#endif 1.273 +#asm 1.274 + push ss 1.275 pop ds 1.276 push ds 1.277 - pop ss 1.278 - mov sp, #CMDLINE_OFFSET 1.279 + pop es 1.280 jmpi 0, #0x9020 1.281 +endsysmove: 1.282 #endasm 1.283 }