wok-next diff syslinux/stuff/iso2exe/bootlinux.c @ rev 17160
syslinux/iso2exe: full zImage support
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Wed Sep 17 11:38:34 2014 +0200 (2014-09-17) |
parents | 3865e09ec026 |
children | c15bb3c9e12d |
line diff
1.1 --- a/syslinux/stuff/iso2exe/bootlinux.c Thu Mar 13 08:22:47 2014 +0000 1.2 +++ b/syslinux/stuff/iso2exe/bootlinux.c Wed Sep 17 11:38:34 2014 +0200 1.3 @@ -1,7 +1,9 @@ 1.4 #include <stdio.h> 1.5 +#include "libdos.h" 1.6 #include "iso9660.h" 1.7 1.8 static unsigned setup_version; 1.9 +#define ELKSSIG 0x1E6 1.10 #define SETUPSECTORS 0x1F1 1.11 #define ROFLAG 0x1F2 1.12 #define SYSSIZE 0x1F4 1.13 @@ -39,11 +41,16 @@ 1.14 while (1); 1.15 } 1.16 1.17 +static int iselks; 1.18 static int vm86(void) 1.19 { 1.20 #asm 1.21 - smsw ax 1.22 + xor ax, ax 1.23 + cmp ax, _iselks 1.24 + jne fakerealmode // elks may run on a 8086 1.25 + smsw ax // 286+ 1.26 and ax, #1 // 0:realmode 1:vm86 1.27 +fakerealmode: 1.28 #endasm 1.29 } 1.30 1.31 @@ -55,13 +62,31 @@ 1.32 static void movehi(void) 1.33 { 1.34 #asm 1.35 - pusha 1.36 + push si 1.37 + push di 1.38 + 1.39 + mov si, #_mem 1.40 + cmp word ptr [si+2], #0x10 1.41 + jnc movehiz 1.42 + mov ax, [si+1] 1.43 + mov cl, #4 1.44 + shl ax, cl // 8086 support for elks 1.45 + mov es, ax 1.46 + mov di, #0x00FF 1.47 + and di, [si] 1.48 + mov si, #_buffer 1.49 + mov cx, #BUFFERSZ/2 1.50 + cld 1.51 + rep 1.52 + movw 1.53 + jmp movedone 1.54 +movehiz: 1.55 xor di, di // 30 1.56 mov cx, #9 // 2E..1E 1.57 zero1: 1.58 push di 1.59 loop zero1 1.60 - push dword [_mem] // 1A mem.base 1.61 + push dword [si] // 1A mem.base 1.62 push #-1 // 18 1.63 push di // 16 1.64 xor eax, eax 1.65 @@ -86,15 +111,17 @@ 1.66 xchg [si+0x1F], al // bits 24..31 1.67 int 0x15 1.68 add sp, #0x30 1.69 - popa 1.70 +movedone: 1.71 + pop di 1.72 + pop si 1.73 #endasm 1.74 } 1.75 1.76 #define ZIMAGE_SUPPORT 1.77 +#define FULL_ZIMAGE 1.78 1.79 #ifdef ZIMAGE_SUPPORT 1.80 static unsigned zimage = 0; 1.81 -#ifndef FULL_ZIMAGE 1.82 static unsigned getss(void) 1.83 { 1.84 #asm 1.85 @@ -102,18 +129,6 @@ 1.86 #endasm 1.87 } 1.88 #endif 1.89 -#endif 1.90 - 1.91 -static int versiondos; 1.92 -static int dosversion(void) 1.93 -{ 1.94 -#asm 1.95 - mov ah, #0x30 1.96 - int 0x21 1.97 - cbw 1.98 - mov _versiondos, ax 1.99 -#endasm 1.100 -} 1.101 1.102 static unsigned extendedramsizeinkb(void) 1.103 { 1.104 @@ -135,10 +150,12 @@ 1.105 die("Need real mode"); 1.106 switch (mem.align) { 1.107 case 0: // kernel 1.108 +#ifdef __MSDOS__ 1.109 if ((unsigned) (dosversion() - 3) > 7 - 3) { 1.110 printf("DOS %d not supported.\nTrying anyway...\n", 1.111 versiondos); 1.112 } 1.113 +#endif 1.114 mem.align = PAGE_SIZE; 1.115 break; 1.116 case PAGE_SIZE: // first initrd : keep 16M..48M for the kernel 1.117 @@ -165,21 +182,21 @@ 1.118 mem.base &= - mem.align; 1.119 } 1.120 1.121 +static unsigned setupseg = SETUP_SEGMENT; 1.122 static unsigned setupofs = 0; 1.123 1.124 void movesetup(void) 1.125 { 1.126 #asm 1.127 - pusha 1.128 - push #SETUP_SEGMENT 1.129 - pop es 1.130 + push si 1.131 + mov es, _setupseg 1.132 mov si, #_buffer 1.133 - mov di, _setupofs 1.134 + xchg di, _setupofs 1.135 mov cx, #BUFFERSZ/2 1.136 rep 1.137 movsw 1.138 - mov _setupofs, di 1.139 - popa 1.140 + xchg _setupofs, di 1.141 + pop si 1.142 #endasm 1.143 } 1.144 1.145 @@ -190,23 +207,40 @@ 1.146 #endasm 1.147 } 1.148 1.149 +static unsigned long kernel_version = 0; 1.150 unsigned long loadkernel(void) 1.151 { 1.152 unsigned setup, n = BUFFERSZ; 1.153 - unsigned long syssize = 0, kernel_version = 0; 1.154 + unsigned long syssize = 0; 1.155 1.156 do { 1.157 isoread(buffer, n); 1.158 if (setupofs == 0) { 1.159 if (* (unsigned short *) (buffer + BOOTFLAG) != 0xAA55) 1.160 die("The kernel is not bootable"); 1.161 +#asm 1.162 + int 0x12 1.163 + jc has640k 1.164 + dec ax 1.165 + and al, #0xC0 1.166 + mov cl, #6 1.167 + shl ax, cl 1.168 + cmp ax, _setupseg 1.169 + jnc has640k 1.170 + mov _setupseg, ax 1.171 +has640k: 1.172 +#endasm 1.173 setup = (1 + buffer[SETUPSECTORS]) << 9; 1.174 if (setup == 512) setup = 5 << 9; 1.175 syssize = * (unsigned long *) (buffer + SYSSIZE) << 4; 1.176 + if (!syssize) syssize = 0x7F000; 1.177 setup_version = * (unsigned short *) (buffer + VERSION); 1.178 #define HDRS 0x53726448 1.179 if (* (unsigned long *) (buffer + HEADER) != HDRS) 1.180 setup_version = 0; 1.181 +#define ELKS 0x534B4C45 1.182 + if (* (unsigned long *) (buffer + ELKSSIG) == ELKS) 1.183 + iselks = 1; 1.184 if (setup_version < 0x204) 1.185 syssize &= 0x000FFFFFUL; 1.186 if (setup_version) { 1.187 @@ -237,16 +271,16 @@ 1.188 } 1.189 if (!setup_version || !(buffer[LOADFLAGS] & 1)) { 1.190 #ifdef ZIMAGE_SUPPORT 1.191 -#ifndef FULL_ZIMAGE 1.192 zimage = getss() + 0x1000; 1.193 mem.base = zimage * 16L; 1.194 - if (mem.base + syssize > SETUP_SEGMENT*16L - 32) 1.195 + if (mem.base + syssize > setupseg*16L - 32) { 1.196 +#ifdef FULL_ZIMAGE 1.197 + zimage = 0x11; 1.198 + mem.base = 0x110000L; // 1M + 64K HMA 1.199 +#else 1.200 die("Out of memory"); 1.201 -#else 1.202 - zimage = 0x11; 1.203 - mem.base = 0x110000L; // 1M + 64K HMA 1.204 - 1.205 #endif 1.206 + } 1.207 #else 1.208 die("Not a bzImage format"); 1.209 #endif 1.210 @@ -258,17 +292,16 @@ 1.211 } while (setup > 0); 1.212 1.213 #asm 1.214 + push si 1.215 + mov si, #0x200 1.216 + cmp si, _setup_version 1.217 + jae noversion 1.218 push ds 1.219 - push #SETUP_SEGMENT 1.220 - pop ds 1.221 - mov si, #0x200 1.222 - mov eax, #0x53726448 // HdrS 1.223 + mov ds, _setupseg // setup > 2.00 => 386+ 1.224 + xor eax, eax 1.225 cdq // clear edx 1.226 - cmp [si+2], eax 1.227 - jne noversion 1.228 add si, [si+14] 1.229 mov cx, #3 1.230 - xor ax, ax 1.231 nextdigit: 1.232 shl al, #4 1.233 shl ax, #4 1.234 @@ -281,10 +314,9 @@ 1.235 shld edx, eax, #8 1.236 loop next 1.237 pop ds 1.238 - mov .loadkernel.kernel_version[bp], edx 1.239 - push ds 1.240 + mov _kernel_version, edx 1.241 noversion: 1.242 - pop ds 1.243 + pop si 1.244 #endasm 1.245 load(syssize); 1.246 return kernel_version; 1.247 @@ -292,15 +324,15 @@ 1.248 1.249 void loadinitrd(void) 1.250 { 1.251 - if (setup_version && zimage == 0) 1.252 + if (setup_version) 1.253 load(isofilesize); 1.254 } 1.255 1.256 void bootlinux(char *cmdline) 1.257 { 1.258 + dosshutdown(); 1.259 #asm 1.260 - push #SETUP_SEGMENT 1.261 - pop es 1.262 + mov es, _setupseg 1.263 #endasm 1.264 if (cmdline) { 1.265 if (setup_version <= 0x201) { 1.266 @@ -345,82 +377,111 @@ 1.267 #endasm 1.268 #ifdef ZIMAGE_SUPPORT 1.269 #asm 1.270 + cld 1.271 + mov ax, _mem 1.272 + mov dx, _mem+2 1.273 mov bx, _zimage 1.274 + mov bp, _iselks 1.275 + mov si, #sysmove 1.276 + mov di, #SETUP_END 1.277 + mov cx, #endsysmove-sysmove 1.278 or bx, bx 1.279 jz notzimage 1.280 - mov eax, _mem 1.281 -#ifndef FULL_ZIMAGE 1.282 - shr eax, #4 // top 1.283 - mov dx, #SYSTEM_SEGMENT 1.284 -#else 1.285 - dec eax 1.286 - shr eax, #16 1.287 - inc ax 1.288 - mov dx, #SYSTEM_SEGMENT/0x1000 1.289 -#endif 1.290 push cs 1.291 pop ds 1.292 - push ss 1.293 - pop es 1.294 push es 1.295 - mov si, #sysmove 1.296 - mov di, #SETUP_END 1.297 push di 1.298 - mov cx, #endsysmove-sysmove 1.299 - cld 1.300 rep 1.301 movsb 1.302 retf 1.303 sysmove: 1.304 -#ifndef FULL_ZIMAGE 1.305 - mov ds, bx 1.306 - mov es, dx 1.307 - xor di, di 1.308 - xor si, si 1.309 - mov cl, #8 1.310 - rep 1.311 - movsw 1.312 - inc bx 1.313 +#ifdef FULL_ZIMAGE 1.314 + cmp dx, #0x0010 1.315 + jb lowsys 1.316 +// bx first 64k page, dx:ax last byte+1 1.317 + xchg ax, cx // clear ax 1.318 + jcxz aligned 1.319 inc dx 1.320 - cmp ax, bx 1.321 - jne sysmove 1.322 -#else 1.323 - xchg ax, cx 1.324 +aligned: 1.325 mov si, di 1.326 - push es 1.327 - pop ds 1.328 - push cx 1.329 mov cx, #0x18 1.330 rep 1.331 stosw 1.332 + push es 1.333 + pop ds 1.334 dec cx 1.335 - mov [si+0x10], cx 1.336 - mov [si+0x18], cx 1.337 - pop cx 1.338 + mov [si+0x10], cx // limit = -1 1.339 + mov [si+0x18], cx // limit = -1 1.340 + mov cx, #0x9300+SYSTEM_SEGMENT/0x1000 1.341 mov bh, #0x93 1.342 - mov dh, #0x93 1.343 mvdown: 1.344 mov [si+0x12+2], bx // srce 1.345 - mov [si+0x1A+2], dx // dest 1.346 - pusha 1.347 + mov [si+0x1A+2], cx // dest 1.348 + pusha // more than 1Mb => 286+ 1.349 mov cx, #0x8000 1.350 mov ah, #0x87 1.351 - int 0x15 // catched by himem.sys: may need dos=high,umb 1.352 + int 0x15 1.353 popa 1.354 inc bx 1.355 - inc dx 1.356 - cmp cl, bl 1.357 + inc cx 1.358 + cmp dl, bl 1.359 jne mvdown 1.360 + jmp notzimage 1.361 #endif 1.362 +lowsys: 1.363 +// bx first segment, dx:ax last byte+1 (paragraph aligned) 1.364 + mov cl, #4 1.365 + shr ax, cl 1.366 + mov cl, #12 1.367 + shl dx, cl 1.368 + or ax, dx // last segment+1 1.369 + mov dx, #SYSTEM_SEGMENT 1.370 + sub ax, bx // ax = paragraph count 1.371 + sub bx, dx 1.372 + jnc sysmovelp 1.373 + add dx, ax // top down 1.374 + dec dx 1.375 +sysmovelp: // move ax paragraphs from bx+dx:0 to dx:0 1.376 + mov es, dx 1.377 + mov cx, dx 1.378 + add cx, bx 1.379 + mov ds, cx 1.380 + sbb cx, cx // cx = 0 : -1 1.381 + cmc // C = 1 : 0 1.382 + adc dx, cx 1.383 + xor di, di 1.384 + xor si, si 1.385 + mov cx, #8 1.386 + rep 1.387 + movsw 1.388 + dec ax 1.389 + jne sysmovelp 1.390 notzimage: 1.391 + or bp, bp 1.392 + jz notelks 1.393 + push ss 1.394 + pop ds 1.395 + mov cx, #0x100 1.396 + mov es, cx 1.397 + mov ch, #0x78 // do not overload SYSTEM_SEGMENT 1.398 + xor si, si 1.399 + xor di, di 1.400 + push es 1.401 + rep 1.402 + movsw 1.403 + pop ss 1.404 +notelks: 1.405 #endasm 1.406 #endif 1.407 #asm 1.408 - push ss 1.409 - pop ds 1.410 - push ds 1.411 - pop es 1.412 - jmpi 0, #0x9020 1.413 + mov ax, ss 1.414 + mov ds, ax 1.415 + mov es, ax 1.416 + add ax, #0x20 1.417 + push ax 1.418 + xor dx, dx 1.419 + push dx 1.420 + retf 1.421 endsysmove: 1.422 #endasm 1.423 }