wok-next diff syslinux/stuff/iso2exe/bootlinux.c @ rev 17454
syslinux/iso2exe: create a vfat partition in usb bootkey (DOS case only)
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Thu Dec 18 11:42:27 2014 +0100 (2014-12-18) |
parents | c15bb3c9e12d |
children | 188b82599301 |
line diff
1.1 --- a/syslinux/stuff/iso2exe/bootlinux.c Wed Sep 17 15:21:35 2014 +0200 1.2 +++ b/syslinux/stuff/iso2exe/bootlinux.c Thu Dec 18 11:42:27 2014 +0100 1.3 @@ -2,7 +2,6 @@ 1.4 #include "libdos.h" 1.5 #include "iso9660.h" 1.6 1.7 -static unsigned setup_version; 1.8 #define ELKSSIG 0x1E6 1.9 #define SETUPSECTORS 0x1F1 1.10 #define ROFLAG 0x1F2 1.11 @@ -45,9 +44,9 @@ 1.12 static int vm86(void) 1.13 { 1.14 #asm 1.15 - xor ax, ax 1.16 - cmp ax, _iselks 1.17 - jne fakerealmode // elks may run on a 8086 1.18 + mov ax, _iselks 1.19 + dec ax 1.20 + je fakerealmode // elks may run on a 8086 1.21 smsw ax // 286+ 1.22 and ax, #1 // 0:realmode 1:vm86 1.23 fakerealmode: 1.24 @@ -59,37 +58,51 @@ 1.25 int align; 1.26 } mem = { 0x100000, 0 }; 1.27 1.28 +#ifdef __MSDOS__ 1.29 +#define A20HOLDBUFFER 0x80000 1.30 +static int a20buffer = 0; 1.31 +#endif 1.32 + 1.33 static void movehi(void) 1.34 { 1.35 #asm 1.36 push si 1.37 push di 1.38 1.39 + xor ax, ax 1.40 mov si, #_mem 1.41 cmp word ptr [si+2], #0x10 1.42 +#ifdef __MSDOS__ 1.43 + jne nota20 1.44 + mov ax, #A20HOLDBUFFER/16 1.45 + mov _a20buffer, ax 1.46 + mov di, [si] // mem.base & 0xFFFF 1.47 + jmp mvbuffer 1.48 +nota20: 1.49 +#endif 1.50 jnc movehiz 1.51 - mov ax, [si+1] 1.52 + lodsb 1.53 + xchg ax, di 1.54 + lodsw 1.55 mov cl, #4 1.56 shl ax, cl // 8086 support for elks 1.57 +mvbuffer: 1.58 mov es, ax 1.59 - mov di, #0x00FF 1.60 - and di, [si] 1.61 mov si, #_buffer 1.62 + cld 1.63 mov cx, #BUFFERSZ/2 1.64 - cld 1.65 rep 1.66 movw 1.67 jmp movedone 1.68 -movehiz: 1.69 - xor di, di // 30 1.70 +movehiz: // 30 1.71 mov cx, #9 // 2E..1E 1.72 zero1: 1.73 - push di 1.74 + push ax 1.75 loop zero1 1.76 push dword [si] // 1A mem.base 1.77 push #-1 // 18 1.78 - push di // 16 1.79 - xor eax, eax 1.80 + push ax // 16 1.81 + cwde 1.82 cdq 1.83 mov dx, ds 1.84 shl edx, #4 1.85 @@ -99,7 +112,7 @@ 1.86 push #-1 // 10 1.87 mov cl, #8 // 0E..00 1.88 zero2: 1.89 - push di 1.90 + push #0 1.91 loop zero2 1.92 mov ch, #BUFFERSZ/512 1.93 push ss 1.94 @@ -117,10 +130,6 @@ 1.95 #endasm 1.96 } 1.97 1.98 -#define ZIMAGE_SUPPORT 1.99 -#define FULL_ZIMAGE 1.100 - 1.101 -#ifdef ZIMAGE_SUPPORT 1.102 static unsigned zimage = 0; 1.103 static unsigned getss(void) 1.104 { 1.105 @@ -128,7 +137,6 @@ 1.106 mov ax, ss 1.107 #endasm 1.108 } 1.109 -#endif 1.110 1.111 static unsigned extendedramsizeinkb(void) 1.112 { 1.113 @@ -190,12 +198,13 @@ 1.114 #asm 1.115 push si 1.116 mov es, _setupseg 1.117 + xchg di, _setupofs 1.118 mov si, #_buffer 1.119 - xchg di, _setupofs 1.120 + cld 1.121 mov cx, #BUFFERSZ/2 1.122 rep 1.123 movsw 1.124 - xchg _setupofs, di 1.125 + xchg di, _setupofs 1.126 pop si 1.127 #endasm 1.128 } 1.129 @@ -207,16 +216,25 @@ 1.130 #endasm 1.131 } 1.132 1.133 +#define WORD(x) * (unsigned short *) (x) 1.134 +#define LONG(x) * (unsigned long *) (x) 1.135 +static unsigned setup_version = 0; 1.136 static unsigned long kernel_version = 0; 1.137 unsigned long loadkernel(void) 1.138 { 1.139 - unsigned setup, n = BUFFERSZ; 1.140 + unsigned setup; 1.141 +#define LINUX001_SUPPORT 1.142 +#ifdef LINUX001_SUPPORT 1.143 + unsigned n = 512; 1.144 +#else 1.145 + unsigned n = BUFFERSZ; 1.146 +#endif 1.147 unsigned long syssize = 0; 1.148 1.149 do { 1.150 isoread(buffer, n); 1.151 if (setupofs == 0) { 1.152 - if (* (unsigned short *) (buffer + BOOTFLAG) != 0xAA55) 1.153 + if (WORD(buffer + BOOTFLAG) != 0xAA55) 1.154 die("The kernel is not bootable"); 1.155 #asm 1.156 int 0x12 1.157 @@ -230,16 +248,25 @@ 1.158 mov _setupseg, ax 1.159 has640k: 1.160 #endasm 1.161 + syssize = LONG(buffer + SYSSIZE) << 4; 1.162 + if (!syssize) syssize = 0x7F000; 1.163 setup = (1 + buffer[SETUPSECTORS]) << 9; 1.164 - if (setup == 512) setup = 5 << 9; 1.165 - syssize = * (unsigned long *) (buffer + SYSSIZE) << 4; 1.166 - if (!syssize) syssize = 0x7F000; 1.167 - setup_version = * (unsigned short *) (buffer + VERSION); 1.168 + if (setup == 512) { 1.169 +#ifdef LINUX001_SUPPORT 1.170 + if (WORD(buffer + 0x3F) == 0x3AE8) /* linux 0.01 */ 1.171 + goto linux001; 1.172 +#endif 1.173 + setup = 5 << 9; 1.174 + } 1.175 +#ifdef LINUX001_SUPPORT 1.176 + n = BUFFERSZ; 1.177 + isoread(buffer+512, BUFFERSZ-512); 1.178 +#endif 1.179 #define HDRS 0x53726448 1.180 - if (* (unsigned long *) (buffer + HEADER) != HDRS) 1.181 - setup_version = 0; 1.182 + if (LONG(buffer + HEADER) == HDRS) 1.183 + setup_version = WORD(buffer + VERSION); 1.184 #define ELKS 0x534B4C45 1.185 - if (* (unsigned long *) (buffer + ELKSSIG) == ELKS) 1.186 + if (LONG(buffer + ELKSSIG) == ELKS) 1.187 iselks = 1; 1.188 if (setup_version < 0x204) 1.189 syssize &= 0x000FFFFFUL; 1.190 @@ -256,34 +283,24 @@ 1.191 retf 1.192 end_realmode_switch: 1.193 #endasm 1.194 - * (unsigned short *) (buffer + RMSWOFS) = 1.195 - far_realmode_switch; 1.196 - * (unsigned short *) (buffer + RMSWSEG) = 1.197 - getcs(); 1.198 + WORD(buffer + RMSWOFS) = far_realmode_switch; 1.199 + WORD(buffer + RMSWSEG) = getcs(); 1.200 #endif 1.201 - mem.base = 1.202 - * (unsigned long *) (buffer + SYSTEMCODE); 1.203 - * (unsigned short *) (buffer + HEAPPTR) = 1.204 - 0x9B00; 1.205 + mem.base = LONG(buffer + SYSTEMCODE); 1.206 + WORD(buffer + HEAPPTR) = 0x9B00; 1.207 // buffer[LOADFLAGS] |= 0x80; 1.208 - * (unsigned short *) (buffer + LOADERTYPE) |= 1.209 - 0x80FF; 1.210 + WORD(buffer + LOADERTYPE) |= 0x80FF; 1.211 } 1.212 +#ifdef LINUX001_SUPPORT 1.213 + linux001: 1.214 +#endif 1.215 if (!setup_version || !(buffer[LOADFLAGS] & 1)) { 1.216 -#ifdef ZIMAGE_SUPPORT 1.217 zimage = getss() + 0x1000; 1.218 mem.base = zimage * 16L; 1.219 if (mem.base + syssize > setupseg*16L - 32) { 1.220 -#ifdef FULL_ZIMAGE 1.221 - zimage = 0x11; 1.222 + zimage = 0x9311; 1.223 mem.base = 0x110000L; // 1M + 64K HMA 1.224 -#else 1.225 - die("Out of memory"); 1.226 -#endif 1.227 } 1.228 -#else 1.229 - die("Not a bzImage format"); 1.230 -#endif 1.231 } 1.232 } 1.233 movesetup(); 1.234 @@ -296,25 +313,24 @@ 1.235 mov si, #0x200 1.236 cmp si, _setup_version 1.237 jae noversion 1.238 - push ds 1.239 - mov ds, _setupseg // setup > 2.00 => 386+ 1.240 - xor eax, eax 1.241 - cdq // clear edx 1.242 + mov es, _setupseg 1.243 + seg es 1.244 add si, [si+14] 1.245 - mov cx, #3 1.246 + mov bx, #2 1.247 + mov cl, #4 1.248 +nextnumber: 1.249 + xor ax, ax 1.250 nextdigit: 1.251 - shl al, #4 1.252 - shl ax, #4 1.253 -next: 1.254 + shl al, cl 1.255 + shl ax, cl 1.256 + seg es 1.257 lodsb 1.258 sub al, #0x30 1.259 cmp al, #9 1.260 jbe nextdigit 1.261 - shl eax, #16 1.262 - shld edx, eax, #8 1.263 - loop next 1.264 - pop ds 1.265 - mov _kernel_version, edx 1.266 + mov [bx+_kernel_version], ah 1.267 + dec bx 1.268 + jns nextnumber 1.269 noversion: 1.270 pop si 1.271 #endasm 1.272 @@ -332,52 +348,48 @@ 1.273 { 1.274 dosshutdown(); 1.275 #asm 1.276 + cld 1.277 mov es, _setupseg 1.278 -#endasm 1.279 - if (cmdline) { 1.280 - if (setup_version <= 0x201) { 1.281 -#asm 1.282 + mov ax, _setup_version 1.283 + cmp ax, #0x200 1.284 + jb noinitrd 1.285 + mov di, #0x218 1.286 + mov si, #_initrd_addr 1.287 + movsw 1.288 + movsw 1.289 + mov si, #_initrd_size 1.290 + movsw 1.291 + movsw 1.292 +noinitrd: 1.293 + pop si // return address 1.294 + pop si // .bootlinux.cmdline[bp] 1.295 + or si, si 1.296 + jz nocmdline 1.297 + cmp ax, #0x201 1.298 mov di, #0x0020 1.299 mov ax, #0xA33F 1.300 + mov bx, #CMDLINE_OFFSET 1.301 + push bx 1.302 + jbe oldcmdline 1.303 + mov di, #0x0228 1.304 + mov ax, es 1.305 + mov cl, #12 1.306 + shr ax, cl 1.307 + xchg ax, bx 1.308 +oldcmdline: 1.309 stosw 1.310 - mov ax, #CMDLINE_OFFSET 1.311 + xchg ax, bx 1.312 stosw 1.313 -#endasm 1.314 - } 1.315 - else { 1.316 -#asm 1.317 - mov di, #0x0228 1.318 - mov eax, #SETUP_SEGMENT*16+CMDLINE_OFFSET 1.319 - stosd 1.320 -#endasm 1.321 - } 1.322 -#asm 1.323 - xchg ax, di 1.324 - mov si, .bootlinux.cmdline[bp] 1.325 + pop di 1.326 copy: 1.327 lodsb 1.328 stosb 1.329 or al,al 1.330 jne copy 1.331 -#endasm 1.332 - } 1.333 - if (setup_version >= 0x200) { 1.334 -#asm 1.335 - mov eax, _initrd_addr 1.336 - mov di, #0x218 1.337 - stosd 1.338 - mov eax, _initrd_size 1.339 - stosd 1.340 -#endasm 1.341 - } 1.342 -#asm 1.343 +nocmdline: 1.344 push es 1.345 pop ss 1.346 mov sp, #CMDLINE_OFFSET 1.347 -#endasm 1.348 -#ifdef ZIMAGE_SUPPORT 1.349 -#asm 1.350 - cld 1.351 mov ax, _mem 1.352 mov dx, _mem+2 1.353 mov bx, _zimage 1.354 @@ -395,7 +407,6 @@ 1.355 movsb 1.356 retf 1.357 sysmove: 1.358 -#ifdef FULL_ZIMAGE 1.359 cmp dx, #0x0010 1.360 jb lowsys 1.361 // bx first 64k page, dx:ax last byte+1 1.362 @@ -413,7 +424,7 @@ 1.363 mov [si+0x10], cx // limit = -1 1.364 mov [si+0x18], cx // limit = -1 1.365 mov cx, #0x9300+SYSTEM_SEGMENT/0x1000 1.366 - mov bh, #0x93 1.367 + //mov bh, #0x93 1.368 mvdown: 1.369 mov [si+0x12+2], bx // srce 1.370 mov [si+0x1A+2], cx // dest 1.371 @@ -427,14 +438,12 @@ 1.372 cmp dl, bl 1.373 ja mvdown 1.374 jmp notzimage 1.375 -#endif 1.376 lowsys: 1.377 // bx first segment, dx:ax last byte+1 (paragraph aligned) 1.378 - mov cl, #4 1.379 + mov cl, #4 // elks may run on a 8086 1.380 shr ax, cl 1.381 - mov cl, #12 1.382 shl dx, cl 1.383 - or ax, dx // last segment+1 1.384 + or ah, dl // last segment+1 1.385 mov dx, #SYSTEM_SEGMENT 1.386 sub ax, bx // ax = paragraph count 1.387 sub bx, dx 1.388 @@ -443,44 +452,45 @@ 1.389 dec dx 1.390 sysmovelp: // move ax paragraphs from bx+dx:0 to dx:0 1.391 mov es, dx 1.392 - mov cx, dx 1.393 - add cx, bx 1.394 - mov ds, cx 1.395 - sbb cx, cx // cx = 0 : -1 1.396 + mov si, dx 1.397 + add si, bx 1.398 + mov ds, si 1.399 + sbb si, si // si = 0 : -1 1.400 cmc // C = 1 : 0 1.401 - adc dx, cx 1.402 + adc dx, si 1.403 + mov cl, #8 1.404 xor di, di 1.405 xor si, si 1.406 - mov cx, #8 1.407 rep 1.408 movsw 1.409 dec ax 1.410 jne sysmovelp 1.411 notzimage: 1.412 - or bp, bp 1.413 - jz notelks 1.414 + mov ax, ss 1.415 + mov ds, ax 1.416 + dec bp 1.417 + jnz notelks 1.418 + mov ah, #0x1 1.419 + mov ss, ax 1.420 +notelks: 1.421 push ss 1.422 - pop ds 1.423 - mov cx, #0x100 1.424 - mov es, cx 1.425 - mov ch, #0x78 // do not overload SYSTEM_SEGMENT 1.426 + pop es 1.427 + xor di, di 1.428 xor si, si 1.429 - xor di, di 1.430 - push es 1.431 +#ifdef LINUX001_SUPPORT 1.432 + mov cx, #0x0042 1.433 + cmp word ptr [si+0x3F], #0x3AE8 1.434 + je islinux001 1.435 +#endif 1.436 + mov cx, #0x7800 // do not overload SYSTEM_SEGMENT 1.437 rep 1.438 movsw 1.439 - pop ss 1.440 -notelks: 1.441 -#endasm 1.442 -#endif 1.443 -#asm 1.444 - mov ax, ss 1.445 - mov ds, ax 1.446 - mov es, ax 1.447 - add ax, #0x20 1.448 + push es 1.449 + pop ds 1.450 + xor al, #0x20 1.451 +islinux001: 1.452 push ax 1.453 - xor dx, dx 1.454 - push dx 1.455 + push cx 1.456 retf 1.457 endsysmove: 1.458 #endasm