wok rev 19465

linld: add zImage support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Mon Oct 24 15:20:54 2016 +0200 (2016-10-24)
parents ff2dbaab9ad7
children f83bd64e1765
files linld/receipt linld/stuff/a20.u linld/stuff/jump.u linld/stuff/load.u linld/stuff/memcpy32.u slitaz-i18n/receipt
line diff
     1.1 --- a/linld/receipt	Mon Oct 24 11:39:42 2016 +0000
     1.2 +++ b/linld/receipt	Mon Oct 24 15:20:54 2016 +0200
     1.3 @@ -21,6 +21,8 @@
     1.4  	cd $src
     1.5  	patch -p0 < $stuff/load.u
     1.6  	patch -p0 < $stuff/jump.u
     1.7 +	patch -p0 < $stuff/a20.u
     1.8 +	patch -p0 < $stuff/memcpy32.u
     1.9  	sed -i 's/^@pause/rem &/;s|^tasm|& /l|' LINLD$SUFFIX/*.BAT
    1.10  	unix2dos > MAKE.BAT <<EOT
    1.11  d:
    1.12 @@ -43,5 +45,5 @@
    1.13  {
    1.14  	mkdir -p $fs/usr/share/boot $fs/usr/bin
    1.15  	cp $src/linld.com $stuff/linld.txt $fs/usr/share/boot/
    1.16 -	cp $src/tobzimage $fs/usr/bin
    1.17 +	#cp $src/tobzimage $fs/usr/bin
    1.18  }
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/linld/stuff/a20.u	Mon Oct 24 15:20:54 2016 +0200
     2.3 @@ -0,0 +1,20 @@
     2.4 +--- LINLD097/A20.ASM
     2.5 ++++ LINLD097/A20.ASM
     2.6 +@@ -93,12 +93,15 @@
     2.7 + 
     2.8 +                 push    bp
     2.9 +                 mov     bp,sp
    2.10 +-                push    ax bx
    2.11 ++                push    ax
    2.12 ++                push    bx
    2.13 +                 mov     ah,03h          ;global enable a20
    2.14 +                 call    [drv]           ;
    2.15 +                 mov     ah,05h          ;local enable a20
    2.16 +                 call    [drv]           ;
    2.17 +-                pop     bx ax
    2.18 ++                pop     bx
    2.19 ++                pop     ax
    2.20 ++                pop     bp
    2.21 +                 ret
    2.22 +         endp    _enable_a20_xmm
    2.23 + 
     3.1 --- a/linld/stuff/jump.u	Mon Oct 24 11:39:42 2016 +0000
     3.2 +++ b/linld/stuff/jump.u	Mon Oct 24 15:20:54 2016 +0200
     3.3 @@ -1,9 +1,32 @@
     3.4  --- LINLD097/JUMP.ASM
     3.5  +++ LINLD097/JUMP.ASM
     3.6 -@@ -24,33 +24,22 @@
     3.7 -                         jmpseg  :word,  \
     3.8 -                         jmpofs  :word   = PARAM_SIZE
     3.9 +@@ -7,9 +7,16 @@
    3.10 +                 %nomacs
    3.11 +                 p386
    3.12   
    3.13 +-        group   DGROUP  _TEXT
    3.14 ++        group   DGROUP  _TEXT,_DATA
    3.15 +         assume  cs:DGROUP,ds:DGROUP
    3.16 + 
    3.17 ++        segment _DATA byte public use16 'DATA'
    3.18 ++
    3.19 ++        global  _saved15:dword
    3.20 ++	global	_first1k:word
    3.21 ++
    3.22 ++        ends    _DATA
    3.23 ++
    3.24 +         segment _TEXT byte public use16 'CODE'
    3.25 + 
    3.26 + ;***************************************************************
    3.27 +@@ -19,38 +26,102 @@
    3.28 +         global  _set_sregs_jump_seg_ofs:near
    3.29 +         proc    _set_sregs_jump_seg_ofs near
    3.30 + 
    3.31 +-                arg     sreg    :word,  \
    3.32 +-                        stk     :word,  \
    3.33 +-                        jmpseg  :word,  \
    3.34 +-                        jmpofs  :word   = PARAM_SIZE
    3.35 +-
    3.36  -                push    bp      ;TODO: kinda useless, isn't it?
    3.37  -		mov	bp,sp
    3.38  -
    3.39 @@ -21,27 +44,108 @@
    3.40  -                mov     ss,ax
    3.41  -                mov     fs,ax
    3.42  -                mov     gs,ax
    3.43 -+		pop	bx		;caller return address
    3.44 -+		pop	bx		; sreg
    3.45 ++		mov	bx, 202h
    3.46 ++		add	bx,[_first1k]
    3.47 ++		cmp	[dword bx],'SrdH'	; head version >= 2 ?
    3.48 ++		jne	oldzimage
    3.49 ++		test	[byte bx+0Fh],1		; load high ? (clear C)
    3.50 ++		jne	isbzimage
    3.51 ++oldzimage:
    3.52 ++		; finish loading
    3.53 ++		extrn   @last_ditch$qv
    3.54 ++		push	cs
    3.55 ++		call	near @last_ditch$qv
    3.56 ++		; self move
    3.57 ++		cld
    3.58 ++		push	9820h			; 512 bytes for cmdline
    3.59 ++		pop	es
    3.60 ++		xor	di,di
    3.61 ++		mov	si,di
    3.62 ++		extrn	_bss_end
    3.63 ++		mov	cx,offset _bss_end
    3.64 ++		rep
    3.65 ++		  movsb
    3.66 ++		push	es
    3.67 ++		call	near doretf
    3.68 ++		stc
    3.69 ++isbzimage:
    3.70 ++		pop	ax		;caller return address
    3.71 ++		pop	dx		; jmpseg
    3.72 ++		pop	bx		; jmpofs
    3.73  +		pop	ax		; stk
    3.74 -+		pop	dx		; jmpseg
    3.75 -+		pop	cx		; jmpofs
    3.76 -+                mov     ds,bx
    3.77 -+                mov     es,bx
    3.78 -+                mov     fs,bx
    3.79 -+                mov     gs,bx
    3.80 -+                mov     ss,bx
    3.81 ++		pop	ss		; sseg
    3.82  +                xchg	sp,ax
    3.83 ++                push    dx bx
    3.84 ++		jnc	nomove
    3.85 ++		; DOS shutdown
    3.86 ++		xor	si,si
    3.87 ++		mov	ds,si
    3.88 ++		push	[dword si+4]
    3.89 ++		mov	[word cs:loadsp19+1],sp
    3.90 ++		;cmp	[byte si+7],0F0h
    3.91 ++		;jnc	notdos
    3.92 ++		mov	[word si+4],offset step19
    3.93 ++		mov	[si+6],cs
    3.94 ++		pushf
    3.95 ++		pop	ax
    3.96 ++		inc	ah
    3.97 ++		push	ax
    3.98 ++		popf
    3.99 ++		jmp	small [dword si+4*19h]
   3.100 ++doiret:
   3.101 ++		iret
   3.102 ++step19:
   3.103 ++		push	si
   3.104 ++		push	ds
   3.105 ++		mov	si,sp
   3.106 ++		lds	si,[dword ss:si+4]
   3.107 ++		cmp	[word si],19CDh
   3.108 ++		pop	ds
   3.109 ++		pop	si
   3.110 ++		jne	doiret
   3.111 ++		xor	si,si
   3.112 ++		mov	ds,si
   3.113 ++notdos:
   3.114 ++loadsp19:
   3.115 ++		mov	sp,0
   3.116 ++		pop	[dword si+4]
   3.117 ++		; move zImage system
   3.118 ++		; memcpy32(dstseg=0, dstofs=10000h, srcseg=0, srcofs=100000h, size=80000h)
   3.119 ++		push	cs
   3.120 ++		pop	ds
   3.121 ++		push	8
   3.122 ++		push	si		; size
   3.123 ++		push	10h		; src
   3.124 ++		push	si		;    ofs
   3.125 ++		push	si		; srcseg
   3.126 ++		push	1		; dst
   3.127 ++		push	si		;    ofs
   3.128 ++		push	si		; dstseg
   3.129 ++		extrn   _memcpy32
   3.130 ++		call	near _memcpy32
   3.131 ++		add	sp,16
   3.132 ++nomove:
   3.133 ++		push	ss
   3.134 ++		pop	ds
   3.135 ++		push	ss
   3.136 ++		pop	es
   3.137 ++		push	ss
   3.138 ++		pop	fs
   3.139 ++		push	ss
   3.140 ++		pop	gs
   3.141   		assume	nothing
   3.142   		assume	cs:DGROUP
   3.143   
   3.144  -              ;;jmp     [dword ofs2]
   3.145  -
   3.146 -                 push    dx cx
   3.147 +-                push    dx cx
   3.148 ++doretf:
   3.149                   retf
   3.150  -; Data
   3.151  -;;ofs2            dw      ?
   3.152  -;;seg2            dw      ?
   3.153 ++		
   3.154 ++movedend:
   3.155           endp    _set_sregs_jump_seg_ofs
   3.156   
   3.157           ends    _TEXT
     4.1 --- a/linld/stuff/load.u	Mon Oct 24 11:39:42 2016 +0000
     4.2 +++ b/linld/stuff/load.u	Mon Oct 24 15:20:54 2016 +0200
     4.3 @@ -1,6 +1,135 @@
     4.4  --- LINLD097/LOAD.CPP
     4.5  +++ LINLD097/LOAD.CPP
     4.6 -@@ -400,10 +400,8 @@
     4.7 +@@ -10,12 +10,21 @@
     4.8 +     if(cnt != size) die(msg);
     4.9 + }
    4.10 + 
    4.11 +-static char* read_cmdline_or_die(const char* fn, u16 maxsz, const char* msg) {
    4.12 +-    int fd = open(fn, O_RDONLY|O_BINARY);
    4.13 +-    if(fd == -1) die(msg);
    4.14 +-    u32 size = lseek(fd,0,SEEK_END);
    4.15 +-    if(s32(size)==-1L) die(msg);
    4.16 ++static int openimage(const char *name, const char *failmsg, u32 *size) {
    4.17 ++    int fd = open(name, O_RDONLY|O_BINARY);
    4.18 ++    if(fd != -1) {
    4.19 ++        *size = lseek(fd,0,SEEK_END);
    4.20 ++        if(s32(*size)!=-1L) goto gotimage;
    4.21 ++    }
    4.22 ++    die(failmsg);
    4.23 ++  gotimage:
    4.24 +     lseek(fd,0,SEEK_SET);
    4.25 ++    return fd;
    4.26 ++}
    4.27 ++
    4.28 ++static char* read_cmdline_or_die(const char* fn, u16 maxsz, const char* msg) {
    4.29 ++    u32 size;
    4.30 ++    int fd = openimage(fn, msg, &size);
    4.31 +     if(size>=maxsz) die(msg);
    4.32 +     char *buf = malloc_or_die(size+1, msg); // +1 for '\0'
    4.33 +     read_or_die(fd, buf, size, msg);
    4.34 +@@ -188,7 +197,7 @@
    4.35 +     u8      pad30[0x400-0x22c]; // 022C
    4.36 +                             // 02D0 up to 32 20-byte mem info structs from
    4.37 +                             // int 0x15 fn 0xe820
    4.38 +-}; //__attribute((packed));
    4.39 ++} *first1k; //__attribute((packed));
    4.40 + 
    4.41 + #if sizeof(first1k_t)!=0x400
    4.42 + #error BUG: Bad first1k
    4.43 +@@ -219,7 +228,7 @@
    4.44 + 
    4.45 + // Called from inside kernel just before rm->pm
    4.46 + // _loadds _saveregs: done by hand
    4.47 +-static void far last_ditch() {
    4.48 ++void far last_ditch() {
    4.49 +     cli();  // we start doing *really* destructive things to DOS/BIOS
    4.50 +             // it means: do not even try to enable ints
    4.51 +             // or call BIOS services after this
    4.52 +@@ -296,6 +305,11 @@
    4.53 +         "\tvga=0" NL
    4.54 +         "Use quotes: \"cl=...\" if you need spaces in cmdline" NL
    4.55 +         "Use cl=@filename to take cmdline from file"
    4.56 ++#if 0
    4.57 ++        NL NL "Example" NL
    4.58 ++        "\tcopy/b rootfs4.gz+rootfs3.gz+rootfs2.gz+rootfs1.gz rootfs.gz" NL
    4.59 ++        "\tlinld initrd=rootfs.gz \"cl=rw root=/dev/null video=-32\""
    4.60 ++#endif
    4.61 +     );
    4.62 + }
    4.63 + 
    4.64 +@@ -331,7 +345,10 @@
    4.65 + 
    4.66 +     // Parse command line
    4.67 + 
    4.68 +-    if(argc<2) syntax();
    4.69 ++    if(argc<2) {
    4.70 ++dosyntax:
    4.71 ++        syntax();
    4.72 ++    }
    4.73 + #define STRNCMP(a,b) strncmp((a),(b),sizeof(b)-1)
    4.74 +     {for(int i=1;i<argc;i++) {
    4.75 +         if(STRNCMP(argv[i],"image=") == 0) {
    4.76 +@@ -340,28 +357,23 @@
    4.77 +         else if(STRNCMP(argv[i],"initrd=") == 0) {
    4.78 +             initrd_name=argv[i]+7;
    4.79 +         }
    4.80 +-        else if(STRNCMP(argv[i],"cl=@") == 0) {
    4.81 +-            cmdline=read_cmdline_or_die(argv[i]+4,PAGE_SIZE-1,"Error reading cl=@file");
    4.82 +-            puts("Kernel command line:");
    4.83 +-            puts(cmdline);
    4.84 +-        }
    4.85 +         else if(STRNCMP(argv[i],"cl=") == 0) {
    4.86 +             cmdline=argv[i]+3;
    4.87 ++            if (cmdline[0] == '@') {
    4.88 ++                cmdline=read_cmdline_or_die(argv[i]+4,PAGE_SIZE-1,"Error reading cl=@file");
    4.89 ++                puts("Kernel command line:");
    4.90 ++                puts(cmdline);
    4.91 ++            }
    4.92 +         }
    4.93 +-        else if(strcmp(argv[i],"vga=ask") == 0) {
    4.94 +-            vid_mode = -3;
    4.95 +-        }
    4.96 +-        else if(strcmp(argv[i],"vga=extended") == 0) {
    4.97 +-            vid_mode = -2;
    4.98 +-        }
    4.99 +-        else if(strcmp(argv[i],"vga=normal") == 0) {
   4.100 +-            vid_mode = -1;
   4.101 +-        }
   4.102 +         else if(STRNCMP(argv[i],"vga=") == 0) {
   4.103 +-            vid_mode = strtoul(argv[i]+4);
   4.104 ++	    const char *s=argv[i]+4;
   4.105 ++            if (*s == 'a') vid_mode = -3;
   4.106 ++            else if (*s == 'e') vid_mode = -2;
   4.107 ++            else if (*s == 'n') vid_mode = -1;
   4.108 ++            else vid_mode = strtoul(s);
   4.109 +         }
   4.110 +         else
   4.111 +-            syntax();
   4.112 ++            goto dosyntax;
   4.113 +     }}
   4.114 + #undef STRNCMP
   4.115 + 
   4.116 +@@ -384,15 +396,12 @@
   4.117 + 
   4.118 +     rm_buf = malloc_or_die(_32k, "Can't allocate rm buf");
   4.119 +     // Do not use malloc below until heap_top adjustment (see <*>)
   4.120 +-    int fd = open(kernel_name, O_RDONLY|O_BINARY);
   4.121 +-    if(fd == -1) die("Can't open kernel file");
   4.122 +-    u32 image_size = lseek(fd,0,SEEK_END);
   4.123 +-    if(s32(image_size)==-1L) die("Can't seek kernel file");
   4.124 +-    lseek(fd,0,SEEK_SET);
   4.125 ++    u32 image_size;
   4.126 ++    int fd = openimage(kernel_name, "Can't use kernel file", &image_size);
   4.127 +     read_or_die(fd, rm_buf, 0x400, "Can't read first kb");
   4.128 + 
   4.129 +-    struct first1k_t* first1k = (first1k_t*)rm_buf;
   4.130 +-    // new kernels never need: if(!first1k->setup_sects) first1k->setup_sects=4;
   4.131 ++    first1k = (first1k_t*)rm_buf;
   4.132 ++    if(!first1k->setup_sects) first1k->setup_sects=4;
   4.133 +     rm_size = 0x200*(first1k->setup_sects+1); // 0th sector is not counted there
   4.134 +     if(rm_size>_32k)
   4.135 +         die("rm_size is too big");
   4.136 +@@ -400,33 +409,46 @@
   4.137   
   4.138       if(first1k->boot_flag != 0xAA55)
   4.139           die("No boot signature (55,AA). It's not a kernel");
   4.140 @@ -8,37 +137,89 @@
   4.141  -        die("No 'HdrS' signature (kernel is too old)");
   4.142  -    if(first1k->version < 0x202)
   4.143  -        die("Loader protocol version is less than 2.02 (kernel is too old)");
   4.144 -+    if(first1k->header != HdrS) // starting linux 1.3.73
   4.145 -+        die("No 'HdrS' signature (kernel is too old, try /usr/bin/tobzimage)");
   4.146 -     if(!(first1k->loadflags & 0x01))
   4.147 -         die("I can't load bzImages low");
   4.148 +-    if(!(first1k->loadflags & 0x01))
   4.149 +-        die("I can't load bzImages low");
   4.150   
   4.151 -@@ -414,15 +412,23 @@
   4.152 +-    // Read remaining rm loader
   4.153 +-
   4.154 +-    read_or_die(fd, rm_buf+0x400, rm_size-0x400, "Can't read rm loader");
   4.155 +-
   4.156       // Tell rm loader some info
   4.157   
   4.158       first1k->vid_mode = vid_mode;
   4.159  -    first1k->cmd_line_ptr = 0x98000;
   4.160 -+    if(first1k->version >= 0x202) { // starting linux 2.4.0-test3-pre3
   4.161 -+        first1k->cmd_line_ptr = 0x98000;
   4.162 -+    }
   4.163 -+    else {
   4.164 -+        first1k->cl_magic = 0xA33F;
   4.165 -+        first1k->cl_ofs   = 0x8000;
   4.166 -+    }
   4.167 -     first1k->type_of_loader = 0xff; // kernel do not know us (yet :-)
   4.168 -     // * will be called just before rm -> pm
   4.169 -     first1k->realmode_switch_ofs = ofs(last_ditch);
   4.170 -     first1k->realmode_switch_seg = seg(last_ditch);
   4.171 +-    first1k->type_of_loader = 0xff; // kernel do not know us (yet :-)
   4.172 +-    // * will be called just before rm -> pm
   4.173 +-    first1k->realmode_switch_ofs = ofs(last_ditch);
   4.174 +-    first1k->realmode_switch_seg = seg(last_ditch);
   4.175  -    // * offset limit of the setup heap
   4.176  -    //   heap_end_ptr appears to be relative to the start of setup (ofs 0x0200)
   4.177  -    first1k->heap_end_ptr = _32k-0x0200;
   4.178  -    first1k->loadflags |= 0x80; // says to rm loader it's ok to use heap
   4.179 -+    if(first1k->version >= 0x201) {
   4.180 -+        // * offset limit of the setup heap
   4.181 -+        //   heap_end_ptr appears to be relative to the start of setup (ofs 0x0200)
   4.182 -+        first1k->heap_end_ptr = _32k-0x0200;
   4.183 -+        first1k->loadflags |= 0x80; // says to rm loader it's ok to use heap
   4.184 +-    // * if we will ever stop moving ourself to 0x90000
   4.185 +-    //   we must say setup.S how much to move
   4.186 +-    //first1k->setup_move_size = _32k;
   4.187 ++#if 1
   4.188 ++    if(first1k->header == HdrS) { // starting linux 1.3.73
   4.189 ++	if(first1k->loadflags & 1) {
   4.190 ++#else
   4.191 ++    if((first1k->header != HdrS) || (first1k->loadflags & 1) == 0)
   4.192 ++        die("I can't load bzImage low");
   4.193 ++    {
   4.194 ++        {
   4.195 ++#endif
   4.196 ++            first1k->realmode_switch_ofs = ofs(last_ditch);
   4.197 ++            first1k->realmode_switch_seg = seg(last_ditch);
   4.198 ++        }
   4.199 ++        first1k->type_of_loader = 0xff; // kernel do not know us (yet :-)
   4.200 ++        // * will be called just before rm -> pm
   4.201 ++        if(first1k->version >= 0x201) {
   4.202 ++            // * offset limit of the setup heap
   4.203 ++            //   heap_end_ptr appears to be relative to the start of setup (ofs 0x0200)
   4.204 ++            first1k->heap_end_ptr = _32k-0x0200;
   4.205 ++            first1k->loadflags |= 0x80; // says to rm loader it's ok to use heap
   4.206 ++        }
   4.207 ++        // * if we will ever stop moving ourself to 0x90000
   4.208 ++        //   we must say setup.S how much to move
   4.209 ++        //first1k->setup_move_size = _32k;
   4.210 ++        if(first1k->version >= 0x202) { // starting linux 2.4.0-test3-pre3
   4.211 ++            first1k->cmd_line_ptr = 0x98000;
   4.212 ++            goto cmd_line_ok;
   4.213 ++        }
   4.214  +    }
   4.215 -     // * if we will ever stop moving ourself to 0x90000
   4.216 -     //   we must say setup.S how much to move
   4.217 -     //first1k->setup_move_size = _32k;
   4.218 ++    first1k->cl_magic = 0xA33F;
   4.219 ++    first1k->cl_ofs   = 0x8000;
   4.220 + 
   4.221 ++cmd_line_ok:
   4.222 ++    // Read remaining rm loader
   4.223 ++
   4.224 ++    read_or_die(fd, rm_buf+0x400, rm_size-0x400, "Can't read rm loader");
   4.225 ++
   4.226 +     // Read remaining kernel (pm part)
   4.227 +     // Try to load kernel high, maybe even blindly storing it
   4.228 +     // in unallocated memory as a last resort
   4.229 +@@ -449,11 +471,7 @@
   4.230 +     // Read initrd if needed
   4.231 + 
   4.232 +     if(initrd_name) {
   4.233 +-        int fd = open(initrd_name, O_RDONLY|O_BINARY);
   4.234 +-        if(fd == -1) die("Can't open initrd file");
   4.235 +-        initrd_size = lseek(fd,0,SEEK_END);
   4.236 +-        if(s32(initrd_size)==-1L) die("Can't seek initrd file");
   4.237 +-        lseek(fd,0,SEEK_SET);
   4.238 ++        int fd = openimage(initrd_name, "Can't use initrd file", &initrd_size);
   4.239 +         initrd_target_addr = (memtop()-initrd_size) & (~PAGE_MASK);
   4.240 +       //not needed: kernel detects this and drops initrd
   4.241 +       //// assume 2:1 decompression ratio
   4.242 +@@ -520,9 +538,9 @@
   4.243 + 
   4.244 +     // Jump to kernel rm code
   4.245 +     set_sregs_jump_seg_ofs(
   4.246 +-        0x9000,     //sregs
   4.247 ++        0x9020,0,   //cs,ip
   4.248 +         0xA000,     //sp
   4.249 +-        0x9020,0    //cs,ip
   4.250 ++        0x9000      //sregs
   4.251 +     );
   4.252 + 
   4.253 +     // Let compiler be happy
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/linld/stuff/memcpy32.u	Mon Oct 24 15:20:54 2016 +0200
     5.3 @@ -0,0 +1,117 @@
     5.4 +--- LINLD097/MEMCPY32.ASM
     5.5 ++++ LINLD097/MEMCPY32.ASM
     5.6 +@@ -22,70 +22,34 @@
     5.7 +         global  _is_rm32:near
     5.8 +         proc    _is_rm32 near
     5.9 + 
    5.10 +-                pushf
    5.11 +-                cli
    5.12 ++		pushf
    5.13 ++                push    dx
    5.14 + ; Check for oldies
    5.15 +-                push    sp
    5.16 +-                pop     ax
    5.17 +-                cmp     ax,sp
    5.18 +-                jne     @@bad   ;it is a 86/186, not a 286+
    5.19 ++		mov	ax, 0F000h
    5.20 ++		push	ax		; < 286 : flags[12..15] are forced 1
    5.21 ++		popf			; = 286 : flags[12..15] are forced 0
    5.22 ++		pushf			; > 286 : only flags[15] is forced 0
    5.23 ++		pop	dx
    5.24 ++		add	dh,ah		; NS=386+, NC=286
    5.25 ++		stc
    5.26 ++                js     @@bad   		;it is a 86/186/286, not a 386+
    5.27 + ; Check for vm
    5.28 +                 smsw    ax      ;SMSW cannot be trapped! :-)
    5.29 +                 test    al,1	;MSW_PE
    5.30 +-
    5.31 +-; We're in vm, this is 386+ (there is no vm in 286)
    5.32 ++; We're in vm
    5.33 +                 jnz     check_vcpi
    5.34 + 
    5.35 +-; We're in rm, chk for 386+
    5.36 +-                push    ds dx
    5.37 +-                push    0
    5.38 +-                pop     ds
    5.39 +-                mov     ax,offset excp6
    5.40 +-		mov	dx,cs
    5.41 +-                xchg    [06h*4  ],ax
    5.42 +-                xchg    [06h*4+2],dx
    5.43 +-               ;cmp     sp,sp           ;sets ZF - already done
    5.44 +-                xchg    eax,eax         ;triggers excp6 on 286 - clears ZF
    5.45 +-                mov     [06h*4  ],ax
    5.46 +-                mov     [06h*4+2],dx
    5.47 +-                pop     dx ds
    5.48 +-                jnz     @@bad   ;it's a 286
    5.49 +-
    5.50 + ; It's a 386 in real mode, chk for paging (crazy but possible)
    5.51 +-                push    eax
    5.52 +                 mov     eax,cr0
    5.53 +                 shl     eax,1   ;CR0_PG to CF
    5.54 +-                pop     eax
    5.55 +-                jc      @@bad   ;CR0_PG was set - real mode paging
    5.56 +-@@386rm:
    5.57 +-                mov     ax,1
    5.58 +-                popf
    5.59 +-                ret
    5.60 +-@@bad:          xor     ax,ax
    5.61 +-                popf
    5.62 +-                ret
    5.63 ++@@bad:		sbb	ax,ax	; ax=0h+!CF
    5.64 ++		inc	ax
    5.65 ++		jmp	@@end
    5.66 + 
    5.67 + ;***************************************************************
    5.68 +-;****** Helper int 6 handler: clears ZF, moves IP by 2 bytes
    5.69 +-;***************************************************************
    5.70 +-label   excp6 near
    5.71 +-@@oldFlags      =       (word bp+6)
    5.72 +-@@oldCS         =       (word bp+4)
    5.73 +-@@oldIP         =       (word bp+2)
    5.74 +-@@oldBP         =       (word bp+0)
    5.75 +-@@Flags_ZF      =       0040h
    5.76 +-                push	bp
    5.77 +-		mov	bp,sp
    5.78 +-                add     [@@oldIP],2
    5.79 +-                and     [byte low @@oldFlags],not @@Flags_ZF
    5.80 +-                pop     bp
    5.81 +-                iret
    5.82 +-
    5.83 +-;***************************************************************
    5.84 + ;****** Helper: checks for vcpi
    5.85 + ;***************************************************************
    5.86 + label   check_vcpi near
    5.87 +-                push    dx
    5.88 +                 push    ds
    5.89 + ; Check whether it is safe to call 67h (we trust only known EMM managers)
    5.90 +                 push    0
    5.91 +@@ -119,6 +83,7 @@
    5.92 +               ;;push    dx              ;$ save handle
    5.93 +                 mov     ax,0DE00h       ; check for vcpi present
    5.94 +                 int     67h
    5.95 ++                mov     al,2
    5.96 +                 test    ah,ah
    5.97 +                 jz      @@386vcpi
    5.98 +               ;;pop     dx              ;$ handle
    5.99 +@@ -126,11 +91,10 @@
   5.100 +               ;;int     67h
   5.101 + @@no_vcpi:
   5.102 +                 xor     ax,ax
   5.103 +-                jmp     @@ret
   5.104 + @@386vcpi:
   5.105 +-                mov     ax,2
   5.106 + @@ret:
   5.107 +                 pop     ds
   5.108 ++@@end:
   5.109 +                 pop     dx
   5.110 +                 popf
   5.111 +                 ret
   5.112 +@@ -214,7 +178,7 @@
   5.113 +                 jmp     short $+2
   5.114 + 
   5.115 + ;****** Return *************************************************
   5.116 +-@@ret:          lgdt    [oldGDTR]
   5.117 ++                lgdt    [oldGDTR]
   5.118 +                 pop     edi esi ecx eax ds es
   5.119 +                 popf
   5.120 +                 leave
     6.1 --- a/slitaz-i18n/receipt	Mon Oct 24 11:39:42 2016 +0000
     6.2 +++ b/slitaz-i18n/receipt	Mon Oct 24 15:20:54 2016 +0200
     6.3 @@ -26,6 +26,9 @@
     6.4  # Rules to gen a SliTaz package suitable for Tazpkg.
     6.5  genpkg_rules()
     6.6  {
     6.7 +	# Allow to build the packages who want me...
     6.8 +	sed -i "/^$PACKAGE\$/d" $CACHE/broken 2> /dev/null || true
     6.9 +
    6.10  	mkdir -p $fs/usr/share/doc/slitaz
    6.11  	. $stuff/locale-pack.conf
    6.12  	for p in $CORE_PKGS; do