# HG changeset patch # User Pascal Bellard # Date 1410946714 -7200 # Node ID 3e7ad70145ce9921284fd7ad85519de040a9e015 # Parent f4afbc4680655d3ddce81d39a674756776f73319 syslinux/iso2exe: full zImage support diff -r f4afbc468065 -r 3e7ad70145ce syslinux/stuff/iso2exe/Makefile --- a/syslinux/stuff/iso2exe/Makefile Tue Sep 16 14:21:09 2014 +0200 +++ b/syslinux/stuff/iso2exe/Makefile Wed Sep 17 11:38:34 2014 +0200 @@ -7,6 +7,7 @@ meminfo.exe: meminfo.S cc -o meminfo.o -Wa,-a=meminfo.lst -c meminfo.S objcopy -O binary meminfo.o meminfo.exe + chmod +x $@ iso2exe: iso2exe.sh boot.com bootiso.bin init win32.exe cp iso2exe.sh $@ @@ -32,6 +33,7 @@ tazboot.exe: boot.com com2exe $< > $@ + chmod +x $@ OBJS = boot.o iso9660.o libdos.o bootlinux.o boot.com: $(OBJS) diff -r f4afbc468065 -r 3e7ad70145ce syslinux/stuff/iso2exe/README --- a/syslinux/stuff/iso2exe/README Tue Sep 16 14:21:09 2014 +0200 +++ b/syslinux/stuff/iso2exe/README Wed Sep 17 11:38:34 2014 +0200 @@ -36,7 +36,7 @@ - text launch SliTaz in RAM with text mode - install SliTaz UMSDOS like installation -If the prognam name includes one of the supported modes, the according mode is +If the program name includes one of the supported modes, the according mode is assumed. Example 'C:\> slitazlive.exe' starts SliTaz in RAM with graphics. diff -r f4afbc468065 -r 3e7ad70145ce syslinux/stuff/iso2exe/a20.c --- a/syslinux/stuff/iso2exe/a20.c Tue Sep 16 14:21:09 2014 +0200 +++ b/syslinux/stuff/iso2exe/a20.c Wed Sep 17 11:38:34 2014 +0200 @@ -1,83 +1,6 @@ #ifndef __A20 #define __A20 -// http://www.win.tue.nl/~aeb/linux/kbd/A20.html -static void a20enable(void) -{ -#asm - call a20test - - in al, 0x92 // fast A20 - test al, #0x2 - jnz no92 - or al, #0x2 // Enable A20 - and al, #0xFE // Do not reset machine - out 0x92, al - call a20test -no92: - call empty_8042 - mov al, #0xD1 // command write - out 0x64, al - call empty_8042 - mov al, #0xDF // Enable A20 - out 0x60, al - call empty_8042 - - mov al, #0xFF // Null command, but UHCI wants it - out 0x64, al - call empty_8042 - call a20test - - mov ax, #0x2401 - int 0x15 - call a20test - - in al, 0xEE // fast enable A20 - jmp a20test - -empty_8042: - mov ah, #-32 -wait_8042: - in al, 0x64 - inc ax // FF 32x : no kbd - jz enabled - dec ax - shr ax, #1 // Bit 0: input data - jc data - shr ax, #1 // Bit 1: buffer empty - jc wait_8042 - ret -data: - in al, 0x60 // read data - jmp wait_8042 -a20test: - push ds - xor cx, cx - xor bx, bx - mov ds, cx // ds = 0000 - dec cx - mov gs, cx // gs = FFFF - cli -a1: - mov ax, [bx] - not ax - mov dx, ax - seg gs - xchg dx, [bx+10] - cmp ax, [bx] - seg gs - mov [bx+10], dx - loopne a1 - pop ds - xchg ax, cx - sti - jne enabled - pop cx // quit a20enable -enabled: - ret // ax != 0 : enabled -#endasm -} - #define A20HOLDBUFFER 0x80000 static int a20buffer = 0; static void movehia20(void) @@ -88,7 +11,7 @@ } a20buffer = 1; #asm - pusha + pusha // more than 1Mb => 286+ push #A20HOLDBUFFER/16 pop es mov di, _mem // mem.base & 0xFFFF @@ -106,9 +29,8 @@ static void realmode_switch_a20(void) { if (!a20buffer) return; - a20enable(); #asm - pusha + pusha // more than 1Mb => 286+ xor di, di // 30 mov cx, #9 // 2E..1E a20z1: diff -r f4afbc468065 -r 3e7ad70145ce syslinux/stuff/iso2exe/bootiso.S --- a/syslinux/stuff/iso2exe/bootiso.S Tue Sep 16 14:21:09 2014 +0200 +++ b/syslinux/stuff/iso2exe/bootiso.S Wed Sep 17 11:38:34 2014 +0200 @@ -127,36 +127,28 @@ exestart: cld movw $0x100, %si - movw -127(%si), %ax + movw -126(%si), %ax cwd // clear dx pushw %dx // dos exit - cmpw $0x2F20, %ax - movw $0x1000+EXESTR(help), %ax - je abort - pushfw // save flags - // bits 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - // flags 0 NT IOPL OF DF IF TF SF ZF 0 AF 0 PF 1 CF - // movb $0x10, %ah - pushw %ax - popfw // < 286 : flags[12..15] are forced 1 - pushfw // = 286 : flags[12..15] are forced 0 - popw %cx // > 286 : only flags[15] is forced 0 - popfw // restore flags - addb %ah, %ch // test F0 and 00 cases - cmpb %ah, %ch - movb $EXESTR(no386), %al - jbe abort // C=8086/80186, Z=80286 + cmpb $0x2F, %al + movw $0x3000+EXESTR(help), %ax + jbe abort + int $0x21 + cmpb $3, %al + movb $EXESTR(noDOS3), %al + jb abort #if 1 - movw (%si), %cx - jcxz is386 + cmpw (%si), %dx // checksum not set + je chked #endif movw $(EXELOC(0x8000))/2, %cx chklp: lodsw addw %ax, %dx loop chklp - movb $EXESTR(chkerr), %al - je is386 // dx == 0 ? +chked: + movw $0x1000+EXESTR(chkerr), %ax + je tst386 // dx == 0 ? abort: puts: movb $0x80, %ah @@ -171,21 +163,37 @@ int $0x10 jmp putslp +tst386: + pushfw // save flags + // bits 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + // flags 0 NT IOPL OF DF IF TF SF ZF 0 AF 0 PF 1 CF + // movb $0x10, %ah + pushw %ax + popfw // < 286 : flags[12..15] are forced 1 + pushfw // = 286 : flags[12..15] are forced 0 + popw %bx // > 286 : only flags[15] is forced 0 + popfw // restore flags + addb %ah, %bh // test F0 and 00 cases + cmpb %ah, %bh + movb $EXESTR(no386), %al +#undef NEED386 +#ifdef NEED386 + jbe abort // C=8086/80186, Z=80286 +#else + jbe is86 // C=8086/80186, Z=80286 +#endif is386: - movl %cr0, %eax + smsww %ax // not privileged andb $1, %al jne tstvcpi + movl %cr0, %eax // privileged incl %eax movb $EXESTR(rmPaging), %al js abort movb $EXESTR(realmodemsg), %al realmode: +is86: call puts - movb $0x30, %ah - int $0x21 - cmpb $3, %al - movb $EXESTR(noDOS3), %al - jb abort movw $0x0100, %di movw comstart-end_header(%di), %si // .com address pushw %di @@ -202,7 +210,7 @@ jmp realmode tstvcpi: pushw %ds - movw %cx, %ds // %cx = 0 + movw %dx, %ds // %dx = 0 movw 0x67*4+2, %ds movw $10, %si lodsl @@ -241,7 +249,7 @@ .ascii "No EMM386/VCPI 4" // No EMM386/VCPI 4.0+ .byte EXESTR(dot0) chkerr: - .ascii "Broken ISO image fil" // Broken ISO image file. + .ascii "Broken ISO9660 fil" // Broken ISO9660 file. .byte EXESTR(eeol) vm86modemsg: .ascii "vm86" // vm86 mode. diff -r f4afbc468065 -r 3e7ad70145ce syslinux/stuff/iso2exe/bootlinux.c --- a/syslinux/stuff/iso2exe/bootlinux.c Tue Sep 16 14:21:09 2014 +0200 +++ b/syslinux/stuff/iso2exe/bootlinux.c Wed Sep 17 11:38:34 2014 +0200 @@ -1,7 +1,9 @@ #include +#include "libdos.h" #include "iso9660.h" static unsigned setup_version; +#define ELKSSIG 0x1E6 #define SETUPSECTORS 0x1F1 #define ROFLAG 0x1F2 #define SYSSIZE 0x1F4 @@ -39,11 +41,16 @@ while (1); } +static int iselks; static int vm86(void) { #asm - smsw ax + xor ax, ax + cmp ax, _iselks + jne fakerealmode // elks may run on a 8086 + smsw ax // 286+ and ax, #1 // 0:realmode 1:vm86 +fakerealmode: #endasm } @@ -55,13 +62,31 @@ static void movehi(void) { #asm - pusha + push si + push di + + mov si, #_mem + cmp word ptr [si+2], #0x10 + jnc movehiz + mov ax, [si+1] + mov cl, #4 + shl ax, cl // 8086 support for elks + mov es, ax + mov di, #0x00FF + and di, [si] + mov si, #_buffer + mov cx, #BUFFERSZ/2 + cld + rep + movw + jmp movedone +movehiz: xor di, di // 30 mov cx, #9 // 2E..1E zero1: push di loop zero1 - push dword [_mem] // 1A mem.base + push dword [si] // 1A mem.base push #-1 // 18 push di // 16 xor eax, eax @@ -86,15 +111,17 @@ xchg [si+0x1F], al // bits 24..31 int 0x15 add sp, #0x30 - popa +movedone: + pop di + pop si #endasm } #define ZIMAGE_SUPPORT +#define FULL_ZIMAGE #ifdef ZIMAGE_SUPPORT static unsigned zimage = 0; -#ifndef FULL_ZIMAGE static unsigned getss(void) { #asm @@ -102,18 +129,6 @@ #endasm } #endif -#endif - -static int versiondos; -static int dosversion(void) -{ -#asm - mov ah, #0x30 - int 0x21 - cbw - mov _versiondos, ax -#endasm -} static unsigned extendedramsizeinkb(void) { @@ -135,10 +150,12 @@ die("Need real mode"); switch (mem.align) { case 0: // kernel +#ifdef __MSDOS__ if ((unsigned) (dosversion() - 3) > 7 - 3) { printf("DOS %d not supported.\nTrying anyway...\n", versiondos); } +#endif mem.align = PAGE_SIZE; break; case PAGE_SIZE: // first initrd : keep 16M..48M for the kernel @@ -165,21 +182,21 @@ mem.base &= - mem.align; } +static unsigned setupseg = SETUP_SEGMENT; static unsigned setupofs = 0; void movesetup(void) { #asm - pusha - push #SETUP_SEGMENT - pop es + push si + mov es, _setupseg mov si, #_buffer - mov di, _setupofs + xchg di, _setupofs mov cx, #BUFFERSZ/2 rep movsw - mov _setupofs, di - popa + xchg _setupofs, di + pop si #endasm } @@ -190,23 +207,40 @@ #endasm } +static unsigned long kernel_version = 0; unsigned long loadkernel(void) { unsigned setup, n = BUFFERSZ; - unsigned long syssize = 0, kernel_version = 0; + unsigned long syssize = 0; do { isoread(buffer, n); if (setupofs == 0) { if (* (unsigned short *) (buffer + BOOTFLAG) != 0xAA55) die("The kernel is not bootable"); +#asm + int 0x12 + jc has640k + dec ax + and al, #0xC0 + mov cl, #6 + shl ax, cl + cmp ax, _setupseg + jnc has640k + mov _setupseg, ax +has640k: +#endasm setup = (1 + buffer[SETUPSECTORS]) << 9; if (setup == 512) setup = 5 << 9; syssize = * (unsigned long *) (buffer + SYSSIZE) << 4; + if (!syssize) syssize = 0x7F000; setup_version = * (unsigned short *) (buffer + VERSION); #define HDRS 0x53726448 if (* (unsigned long *) (buffer + HEADER) != HDRS) setup_version = 0; +#define ELKS 0x534B4C45 + if (* (unsigned long *) (buffer + ELKSSIG) == ELKS) + iselks = 1; if (setup_version < 0x204) syssize &= 0x000FFFFFUL; if (setup_version) { @@ -237,16 +271,16 @@ } if (!setup_version || !(buffer[LOADFLAGS] & 1)) { #ifdef ZIMAGE_SUPPORT -#ifndef FULL_ZIMAGE zimage = getss() + 0x1000; mem.base = zimage * 16L; - if (mem.base + syssize > SETUP_SEGMENT*16L - 32) + if (mem.base + syssize > setupseg*16L - 32) { +#ifdef FULL_ZIMAGE + zimage = 0x11; + mem.base = 0x110000L; // 1M + 64K HMA +#else die("Out of memory"); -#else - zimage = 0x11; - mem.base = 0x110000L; // 1M + 64K HMA - #endif + } #else die("Not a bzImage format"); #endif @@ -258,17 +292,16 @@ } while (setup > 0); #asm + push si + mov si, #0x200 + cmp si, _setup_version + jae noversion push ds - push #SETUP_SEGMENT - pop ds - mov si, #0x200 - mov eax, #0x53726448 // HdrS + mov ds, _setupseg // setup > 2.00 => 386+ + xor eax, eax cdq // clear edx - cmp [si+2], eax - jne noversion add si, [si+14] mov cx, #3 - xor ax, ax nextdigit: shl al, #4 shl ax, #4 @@ -281,10 +314,9 @@ shld edx, eax, #8 loop next pop ds - mov .loadkernel.kernel_version[bp], edx - push ds + mov _kernel_version, edx noversion: - pop ds + pop si #endasm load(syssize); return kernel_version; @@ -292,15 +324,15 @@ void loadinitrd(void) { - if (setup_version && zimage == 0) + if (setup_version) load(isofilesize); } void bootlinux(char *cmdline) { + dosshutdown(); #asm - push #SETUP_SEGMENT - pop es + mov es, _setupseg #endasm if (cmdline) { if (setup_version <= 0x201) { @@ -345,82 +377,111 @@ #endasm #ifdef ZIMAGE_SUPPORT #asm + cld + mov ax, _mem + mov dx, _mem+2 mov bx, _zimage + mov bp, _iselks + mov si, #sysmove + mov di, #SETUP_END + mov cx, #endsysmove-sysmove or bx, bx jz notzimage - mov eax, _mem -#ifndef FULL_ZIMAGE - shr eax, #4 // top - mov dx, #SYSTEM_SEGMENT -#else - dec eax - shr eax, #16 - inc ax - mov dx, #SYSTEM_SEGMENT/0x1000 -#endif push cs pop ds - push ss - pop es push es - mov si, #sysmove - mov di, #SETUP_END push di - mov cx, #endsysmove-sysmove - cld rep movsb retf sysmove: -#ifndef FULL_ZIMAGE - mov ds, bx - mov es, dx - xor di, di - xor si, si - mov cl, #8 - rep - movsw - inc bx +#ifdef FULL_ZIMAGE + cmp dx, #0x0010 + jb lowsys +// bx first 64k page, dx:ax last byte+1 + xchg ax, cx // clear ax + jcxz aligned inc dx - cmp ax, bx - jne sysmove -#else - xchg ax, cx +aligned: mov si, di - push es - pop ds - push cx mov cx, #0x18 rep stosw + push es + pop ds dec cx - mov [si+0x10], cx - mov [si+0x18], cx - pop cx + mov [si+0x10], cx // limit = -1 + mov [si+0x18], cx // limit = -1 + mov cx, #0x9300+SYSTEM_SEGMENT/0x1000 mov bh, #0x93 - mov dh, #0x93 mvdown: mov [si+0x12+2], bx // srce - mov [si+0x1A+2], dx // dest - pusha + mov [si+0x1A+2], cx // dest + pusha // more than 1Mb => 286+ mov cx, #0x8000 mov ah, #0x87 - int 0x15 // catched by himem.sys: may need dos=high,umb + int 0x15 popa inc bx - inc dx - cmp cl, bl + inc cx + cmp dl, bl jne mvdown + jmp notzimage #endif +lowsys: +// bx first segment, dx:ax last byte+1 (paragraph aligned) + mov cl, #4 + shr ax, cl + mov cl, #12 + shl dx, cl + or ax, dx // last segment+1 + mov dx, #SYSTEM_SEGMENT + sub ax, bx // ax = paragraph count + sub bx, dx + jnc sysmovelp + add dx, ax // top down + dec dx +sysmovelp: // move ax paragraphs from bx+dx:0 to dx:0 + mov es, dx + mov cx, dx + add cx, bx + mov ds, cx + sbb cx, cx // cx = 0 : -1 + cmc // C = 1 : 0 + adc dx, cx + xor di, di + xor si, si + mov cx, #8 + rep + movsw + dec ax + jne sysmovelp notzimage: + or bp, bp + jz notelks + push ss + pop ds + mov cx, #0x100 + mov es, cx + mov ch, #0x78 // do not overload SYSTEM_SEGMENT + xor si, si + xor di, di + push es + rep + movsw + pop ss +notelks: #endasm #endif #asm - push ss - pop ds - push ds - pop es - jmpi 0, #0x9020 + mov ax, ss + mov ds, ax + mov es, ax + add ax, #0x20 + push ax + xor dx, dx + push dx + retf endsysmove: #endasm } diff -r f4afbc468065 -r 3e7ad70145ce syslinux/stuff/iso2exe/init --- a/syslinux/stuff/iso2exe/init Tue Sep 16 14:21:09 2014 +0200 +++ b/syslinux/stuff/iso2exe/init Wed Sep 17 11:38:34 2014 +0200 @@ -67,10 +67,10 @@ { echo "Extracting $(basename $1) ..." case $(get 0 $1) in - *35615) zcat $1 ;; - *\ 93) unlzma -c $1 ;; - *) cat $1 ;; - esac | ( cd ${2:-/} ; cpio -idmu > /dev/null 2>&1 ) + *35615) ( zcat || gunzip ) ;; + *\ 93) unlzma ;; + *) cat ;; + esac < $1 | ( cd ${2:-/} ; cpio -idmu > /dev/null 2>&1 ) } getuuid() diff -r f4afbc468065 -r 3e7ad70145ce syslinux/stuff/iso2exe/libdos.c --- a/syslinux/stuff/iso2exe/libdos.c Tue Sep 16 14:21:09 2014 +0200 +++ b/syslinux/stuff/iso2exe/libdos.c Wed Sep 17 11:38:34 2014 +0200 @@ -128,3 +128,58 @@ sbb ax, ax #endasm } + +void dosshutdown(void) +{ +#asm + push bp + push si + push di + push ds + seg cs + mov stack+2, ss + seg cs + mov stack,sp + xor bx, bx + mov ds, bx // ds = 0 + mov [bx+4], #step + mov [bx+6], cs + pushf + pop ax + or ax, #0x100 // set TF + push ax + popf + jmp far [bx+4*0x19] +stack: + .long 0 +stepagain: + iret +step: + push si + push ds + mov si, sp + seg ss + lds si, [si+4] + cmp word ptr [si], #0x19CD + pop ds + pop si + jne stepagain + seg cs + lss sp, stack + pop ds + pop di + pop si + pop bp +#endasm +} + +int versiondos; +int dosversion(void) +{ +#asm + mov ah, #0x30 + int 0x21 + cbw + mov _versiondos, ax +#endasm +} diff -r f4afbc468065 -r 3e7ad70145ce syslinux/stuff/iso2exe/libdos.h --- a/syslinux/stuff/iso2exe/libdos.h Tue Sep 16 14:21:09 2014 +0200 +++ b/syslinux/stuff/iso2exe/libdos.h Wed Sep 17 11:38:34 2014 +0200 @@ -6,8 +6,13 @@ extern char *progname(void); extern int chdir(char *path); extern int chdirname(char *path); +extern void dosshutdown(void); +extern int versiondos; +extern int dosversion(void); # else -#define progname() argv[0] +#define progname() (argv[0]) #define chdirname(x) chdir(dirname(x)) +#define dosshutdown() +#define dosversion() (0) # endif #endif diff -r f4afbc468065 -r 3e7ad70145ce syslinux/stuff/iso2exe/meminfo.S --- a/syslinux/stuff/iso2exe/meminfo.S Tue Sep 16 14:21:09 2014 +0200 +++ b/syslinux/stuff/iso2exe/meminfo.S Wed Sep 17 11:38:34 2014 +0200 @@ -53,6 +53,20 @@ popw %ds pushw %cs popw %es +#if 1 + pushfw // save flags + // bits 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + // flags 0 NT IOPL OF DF IF TF SF ZF 0 AF 0 PF 1 CF + movb $0x10, %ah + pushw %ax + popfw // < 286 : flags[12..15] are forced 1 + pushfw // = 286 : flags[12..15] are forced 0 + popw %bx // > 286 : only flags[15] is forced 0 + popfw // restore flags + addb %ah, %bh // test F0 and 00 cases + cmpb %ah, %bh + jbe fail // C=8086/80186, Z=80286 +#endif xorl %ebx, %ebx e820lp: movl $0xe820, %eax @@ -104,13 +118,15 @@ movw %bx, 24+2(%di) incb %dh movw %dx, 56+2(%di) - shrw $6, %ax // 1K -> 64K + movw %cx, %dx + movb $6, %cl + shrw %cl, %ax // 1K -> 64K jz e801_configured - shrw $6, %cx // 1K -> 64K + shrw %cl, %dx // 1K -> 64K addw $0x10, %ax - addw $0x10, %cx + addw $0x10, %dx movw %ax, 8+2(%di) - movw %cx, 40+2(%di) + movw %dx, 40+2(%di) movw $extended, %si call pute801 call pute801 @@ -133,7 +149,8 @@ popw %di jc fail3 movb $0x10, 0+2(%di) // 1M - shrw $6, %ax // 1K -> 64K + movb $6, %cl + shrw %cl, %ax // 1K -> 64K jz fail3 addw $0x10, %ax movw %ax, 8+2(%di)