# HG changeset patch # User Pascal Bellard # Date 1477315254 -7200 # Node ID 8c67051bb1986d9be21b10ab5964b9045b4f1806 # Parent ff2dbaab9ad7c47c7103e9c3394ca2fcebde5a26 linld: add zImage support diff -r ff2dbaab9ad7 -r 8c67051bb198 linld/receipt --- a/linld/receipt Mon Oct 24 11:39:42 2016 +0000 +++ b/linld/receipt Mon Oct 24 15:20:54 2016 +0200 @@ -21,6 +21,8 @@ cd $src patch -p0 < $stuff/load.u patch -p0 < $stuff/jump.u + patch -p0 < $stuff/a20.u + patch -p0 < $stuff/memcpy32.u sed -i 's/^@pause/rem &/;s|^tasm|& /l|' LINLD$SUFFIX/*.BAT unix2dos > MAKE.BAT <= 2 ? ++ jne oldzimage ++ test [byte bx+0Fh],1 ; load high ? (clear C) ++ jne isbzimage ++oldzimage: ++ ; finish loading ++ extrn @last_ditch$qv ++ push cs ++ call near @last_ditch$qv ++ ; self move ++ cld ++ push 9820h ; 512 bytes for cmdline ++ pop es ++ xor di,di ++ mov si,di ++ extrn _bss_end ++ mov cx,offset _bss_end ++ rep ++ movsb ++ push es ++ call near doretf ++ stc ++isbzimage: ++ pop ax ;caller return address ++ pop dx ; jmpseg ++ pop bx ; jmpofs + pop ax ; stk -+ pop dx ; jmpseg -+ pop cx ; jmpofs -+ mov ds,bx -+ mov es,bx -+ mov fs,bx -+ mov gs,bx -+ mov ss,bx ++ pop ss ; sseg + xchg sp,ax ++ push dx bx ++ jnc nomove ++ ; DOS shutdown ++ xor si,si ++ mov ds,si ++ push [dword si+4] ++ mov [word cs:loadsp19+1],sp ++ ;cmp [byte si+7],0F0h ++ ;jnc notdos ++ mov [word si+4],offset step19 ++ mov [si+6],cs ++ pushf ++ pop ax ++ inc ah ++ push ax ++ popf ++ jmp small [dword si+4*19h] ++doiret: ++ iret ++step19: ++ push si ++ push ds ++ mov si,sp ++ lds si,[dword ss:si+4] ++ cmp [word si],19CDh ++ pop ds ++ pop si ++ jne doiret ++ xor si,si ++ mov ds,si ++notdos: ++loadsp19: ++ mov sp,0 ++ pop [dword si+4] ++ ; move zImage system ++ ; memcpy32(dstseg=0, dstofs=10000h, srcseg=0, srcofs=100000h, size=80000h) ++ push cs ++ pop ds ++ push 8 ++ push si ; size ++ push 10h ; src ++ push si ; ofs ++ push si ; srcseg ++ push 1 ; dst ++ push si ; ofs ++ push si ; dstseg ++ extrn _memcpy32 ++ call near _memcpy32 ++ add sp,16 ++nomove: ++ push ss ++ pop ds ++ push ss ++ pop es ++ push ss ++ pop fs ++ push ss ++ pop gs assume nothing assume cs:DGROUP - ;;jmp [dword ofs2] - - push dx cx +- push dx cx ++doretf: retf -; Data -;;ofs2 dw ? -;;seg2 dw ? ++ ++movedend: endp _set_sregs_jump_seg_ofs ends _TEXT diff -r ff2dbaab9ad7 -r 8c67051bb198 linld/stuff/load.u --- a/linld/stuff/load.u Mon Oct 24 11:39:42 2016 +0000 +++ b/linld/stuff/load.u Mon Oct 24 15:20:54 2016 +0200 @@ -1,6 +1,135 @@ --- LINLD097/LOAD.CPP +++ LINLD097/LOAD.CPP -@@ -400,10 +400,8 @@ +@@ -10,12 +10,21 @@ + if(cnt != size) die(msg); + } + +-static char* read_cmdline_or_die(const char* fn, u16 maxsz, const char* msg) { +- int fd = open(fn, O_RDONLY|O_BINARY); +- if(fd == -1) die(msg); +- u32 size = lseek(fd,0,SEEK_END); +- if(s32(size)==-1L) die(msg); ++static int openimage(const char *name, const char *failmsg, u32 *size) { ++ int fd = open(name, O_RDONLY|O_BINARY); ++ if(fd != -1) { ++ *size = lseek(fd,0,SEEK_END); ++ if(s32(*size)!=-1L) goto gotimage; ++ } ++ die(failmsg); ++ gotimage: + lseek(fd,0,SEEK_SET); ++ return fd; ++} ++ ++static char* read_cmdline_or_die(const char* fn, u16 maxsz, const char* msg) { ++ u32 size; ++ int fd = openimage(fn, msg, &size); + if(size>=maxsz) die(msg); + char *buf = malloc_or_die(size+1, msg); // +1 for '\0' + read_or_die(fd, buf, size, msg); +@@ -188,7 +197,7 @@ + u8 pad30[0x400-0x22c]; // 022C + // 02D0 up to 32 20-byte mem info structs from + // int 0x15 fn 0xe820 +-}; //__attribute((packed)); ++} *first1k; //__attribute((packed)); + + #if sizeof(first1k_t)!=0x400 + #error BUG: Bad first1k +@@ -219,7 +228,7 @@ + + // Called from inside kernel just before rm->pm + // _loadds _saveregs: done by hand +-static void far last_ditch() { ++void far last_ditch() { + cli(); // we start doing *really* destructive things to DOS/BIOS + // it means: do not even try to enable ints + // or call BIOS services after this +@@ -296,6 +305,11 @@ + "\tvga=0" NL + "Use quotes: \"cl=...\" if you need spaces in cmdline" NL + "Use cl=@filename to take cmdline from file" ++#if 0 ++ NL NL "Example" NL ++ "\tcopy/b rootfs4.gz+rootfs3.gz+rootfs2.gz+rootfs1.gz rootfs.gz" NL ++ "\tlinld initrd=rootfs.gz \"cl=rw root=/dev/null video=-32\"" ++#endif + ); + } + +@@ -331,7 +345,10 @@ + + // Parse command line + +- if(argc<2) syntax(); ++ if(argc<2) { ++dosyntax: ++ syntax(); ++ } + #define STRNCMP(a,b) strncmp((a),(b),sizeof(b)-1) + {for(int i=1;i) +- int fd = open(kernel_name, O_RDONLY|O_BINARY); +- if(fd == -1) die("Can't open kernel file"); +- u32 image_size = lseek(fd,0,SEEK_END); +- if(s32(image_size)==-1L) die("Can't seek kernel file"); +- lseek(fd,0,SEEK_SET); ++ u32 image_size; ++ int fd = openimage(kernel_name, "Can't use kernel file", &image_size); + read_or_die(fd, rm_buf, 0x400, "Can't read first kb"); + +- struct first1k_t* first1k = (first1k_t*)rm_buf; +- // new kernels never need: if(!first1k->setup_sects) first1k->setup_sects=4; ++ first1k = (first1k_t*)rm_buf; ++ if(!first1k->setup_sects) first1k->setup_sects=4; + rm_size = 0x200*(first1k->setup_sects+1); // 0th sector is not counted there + if(rm_size>_32k) + die("rm_size is too big"); +@@ -400,33 +409,46 @@ if(first1k->boot_flag != 0xAA55) die("No boot signature (55,AA). It's not a kernel"); @@ -8,37 +137,89 @@ - die("No 'HdrS' signature (kernel is too old)"); - if(first1k->version < 0x202) - die("Loader protocol version is less than 2.02 (kernel is too old)"); -+ if(first1k->header != HdrS) // starting linux 1.3.73 -+ die("No 'HdrS' signature (kernel is too old, try /usr/bin/tobzimage)"); - if(!(first1k->loadflags & 0x01)) - die("I can't load bzImages low"); +- if(!(first1k->loadflags & 0x01)) +- die("I can't load bzImages low"); -@@ -414,15 +412,23 @@ +- // Read remaining rm loader +- +- read_or_die(fd, rm_buf+0x400, rm_size-0x400, "Can't read rm loader"); +- // Tell rm loader some info first1k->vid_mode = vid_mode; - first1k->cmd_line_ptr = 0x98000; -+ if(first1k->version >= 0x202) { // starting linux 2.4.0-test3-pre3 -+ first1k->cmd_line_ptr = 0x98000; -+ } -+ else { -+ first1k->cl_magic = 0xA33F; -+ first1k->cl_ofs = 0x8000; -+ } - first1k->type_of_loader = 0xff; // kernel do not know us (yet :-) - // * will be called just before rm -> pm - first1k->realmode_switch_ofs = ofs(last_ditch); - first1k->realmode_switch_seg = seg(last_ditch); +- first1k->type_of_loader = 0xff; // kernel do not know us (yet :-) +- // * will be called just before rm -> pm +- first1k->realmode_switch_ofs = ofs(last_ditch); +- first1k->realmode_switch_seg = seg(last_ditch); - // * offset limit of the setup heap - // heap_end_ptr appears to be relative to the start of setup (ofs 0x0200) - first1k->heap_end_ptr = _32k-0x0200; - first1k->loadflags |= 0x80; // says to rm loader it's ok to use heap -+ if(first1k->version >= 0x201) { -+ // * offset limit of the setup heap -+ // heap_end_ptr appears to be relative to the start of setup (ofs 0x0200) -+ first1k->heap_end_ptr = _32k-0x0200; -+ first1k->loadflags |= 0x80; // says to rm loader it's ok to use heap +- // * if we will ever stop moving ourself to 0x90000 +- // we must say setup.S how much to move +- //first1k->setup_move_size = _32k; ++#if 1 ++ if(first1k->header == HdrS) { // starting linux 1.3.73 ++ if(first1k->loadflags & 1) { ++#else ++ if((first1k->header != HdrS) || (first1k->loadflags & 1) == 0) ++ die("I can't load bzImage low"); ++ { ++ { ++#endif ++ first1k->realmode_switch_ofs = ofs(last_ditch); ++ first1k->realmode_switch_seg = seg(last_ditch); ++ } ++ first1k->type_of_loader = 0xff; // kernel do not know us (yet :-) ++ // * will be called just before rm -> pm ++ if(first1k->version >= 0x201) { ++ // * offset limit of the setup heap ++ // heap_end_ptr appears to be relative to the start of setup (ofs 0x0200) ++ first1k->heap_end_ptr = _32k-0x0200; ++ first1k->loadflags |= 0x80; // says to rm loader it's ok to use heap ++ } ++ // * if we will ever stop moving ourself to 0x90000 ++ // we must say setup.S how much to move ++ //first1k->setup_move_size = _32k; ++ if(first1k->version >= 0x202) { // starting linux 2.4.0-test3-pre3 ++ first1k->cmd_line_ptr = 0x98000; ++ goto cmd_line_ok; ++ } + } - // * if we will ever stop moving ourself to 0x90000 - // we must say setup.S how much to move - //first1k->setup_move_size = _32k; ++ first1k->cl_magic = 0xA33F; ++ first1k->cl_ofs = 0x8000; + ++cmd_line_ok: ++ // Read remaining rm loader ++ ++ read_or_die(fd, rm_buf+0x400, rm_size-0x400, "Can't read rm loader"); ++ + // Read remaining kernel (pm part) + // Try to load kernel high, maybe even blindly storing it + // in unallocated memory as a last resort +@@ -449,11 +471,7 @@ + // Read initrd if needed + + if(initrd_name) { +- int fd = open(initrd_name, O_RDONLY|O_BINARY); +- if(fd == -1) die("Can't open initrd file"); +- initrd_size = lseek(fd,0,SEEK_END); +- if(s32(initrd_size)==-1L) die("Can't seek initrd file"); +- lseek(fd,0,SEEK_SET); ++ int fd = openimage(initrd_name, "Can't use initrd file", &initrd_size); + initrd_target_addr = (memtop()-initrd_size) & (~PAGE_MASK); + //not needed: kernel detects this and drops initrd + //// assume 2:1 decompression ratio +@@ -520,9 +538,9 @@ + + // Jump to kernel rm code + set_sregs_jump_seg_ofs( +- 0x9000, //sregs ++ 0x9020,0, //cs,ip + 0xA000, //sp +- 0x9020,0 //cs,ip ++ 0x9000 //sregs + ); + + // Let compiler be happy diff -r ff2dbaab9ad7 -r 8c67051bb198 linld/stuff/memcpy32.u --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linld/stuff/memcpy32.u Mon Oct 24 15:20:54 2016 +0200 @@ -0,0 +1,117 @@ +--- LINLD097/MEMCPY32.ASM ++++ LINLD097/MEMCPY32.ASM +@@ -22,70 +22,34 @@ + global _is_rm32:near + proc _is_rm32 near + +- pushf +- cli ++ pushf ++ push dx + ; Check for oldies +- push sp +- pop ax +- cmp ax,sp +- jne @@bad ;it is a 86/186, not a 286+ ++ mov ax, 0F000h ++ push ax ; < 286 : flags[12..15] are forced 1 ++ popf ; = 286 : flags[12..15] are forced 0 ++ pushf ; > 286 : only flags[15] is forced 0 ++ pop dx ++ add dh,ah ; NS=386+, NC=286 ++ stc ++ js @@bad ;it is a 86/186/286, not a 386+ + ; Check for vm + smsw ax ;SMSW cannot be trapped! :-) + test al,1 ;MSW_PE +- +-; We're in vm, this is 386+ (there is no vm in 286) ++; We're in vm + jnz check_vcpi + +-; We're in rm, chk for 386+ +- push ds dx +- push 0 +- pop ds +- mov ax,offset excp6 +- mov dx,cs +- xchg [06h*4 ],ax +- xchg [06h*4+2],dx +- ;cmp sp,sp ;sets ZF - already done +- xchg eax,eax ;triggers excp6 on 286 - clears ZF +- mov [06h*4 ],ax +- mov [06h*4+2],dx +- pop dx ds +- jnz @@bad ;it's a 286 +- + ; It's a 386 in real mode, chk for paging (crazy but possible) +- push eax + mov eax,cr0 + shl eax,1 ;CR0_PG to CF +- pop eax +- jc @@bad ;CR0_PG was set - real mode paging +-@@386rm: +- mov ax,1 +- popf +- ret +-@@bad: xor ax,ax +- popf +- ret ++@@bad: sbb ax,ax ; ax=0h+!CF ++ inc ax ++ jmp @@end + + ;*************************************************************** +-;****** Helper int 6 handler: clears ZF, moves IP by 2 bytes +-;*************************************************************** +-label excp6 near +-@@oldFlags = (word bp+6) +-@@oldCS = (word bp+4) +-@@oldIP = (word bp+2) +-@@oldBP = (word bp+0) +-@@Flags_ZF = 0040h +- push bp +- mov bp,sp +- add [@@oldIP],2 +- and [byte low @@oldFlags],not @@Flags_ZF +- pop bp +- iret +- +-;*************************************************************** + ;****** Helper: checks for vcpi + ;*************************************************************** + label check_vcpi near +- push dx + push ds + ; Check whether it is safe to call 67h (we trust only known EMM managers) + push 0 +@@ -119,6 +83,7 @@ + ;;push dx ;$ save handle + mov ax,0DE00h ; check for vcpi present + int 67h ++ mov al,2 + test ah,ah + jz @@386vcpi + ;;pop dx ;$ handle +@@ -126,11 +91,10 @@ + ;;int 67h + @@no_vcpi: + xor ax,ax +- jmp @@ret + @@386vcpi: +- mov ax,2 + @@ret: + pop ds ++@@end: + pop dx + popf + ret +@@ -214,7 +178,7 @@ + jmp short $+2 + + ;****** Return ************************************************* +-@@ret: lgdt [oldGDTR] ++ lgdt [oldGDTR] + pop edi esi ecx eax ds es + popf + leave diff -r ff2dbaab9ad7 -r 8c67051bb198 slitaz-i18n/receipt --- a/slitaz-i18n/receipt Mon Oct 24 11:39:42 2016 +0000 +++ b/slitaz-i18n/receipt Mon Oct 24 15:20:54 2016 +0200 @@ -26,6 +26,9 @@ # Rules to gen a SliTaz package suitable for Tazpkg. genpkg_rules() { + # Allow to build the packages who want me... + sed -i "/^$PACKAGE\$/d" $CACHE/broken 2> /dev/null || true + mkdir -p $fs/usr/share/doc/slitaz . $stuff/locale-pack.conf for p in $CORE_PKGS; do