Bug fixes. Support for large disks by Robb Main.
authorKen Yap <ken_yap@users.sourceforge.net>
Thu, 17 Jul 2003 08:10:45 +0000 (08:10 +0000)
committerKen Yap <ken_yap@users.sourceforge.net>
Thu, 17 Jul 2003 08:10:45 +0000 (08:10 +0000)
LOG
Makefile
README
TruncFD.pm
disnbi.pl
first-dos.S
first-dos.h
mknbi.pl
start32.S
startmenu.S

diff --git a/LOG b/LOG
index d92d001..679ee4b 100644 (file)
--- a/LOG
+++ b/LOG
@@ -175,3 +175,26 @@ that don't have to be global.
 + Downloadable Lua interpreter.
 
 Released as mknbi-1.4.0 (production)
+
++ Number segments in disnbi from 0 both in messages and in filenames.
+
++ Fix problem found by Eric in startmenu.S which affects segment
+override on 486s.
+
++ Add -I. to CFLAGS to make sure we get our includes instead of the
+system's.
+
++ In disnbi, call binmode on O not 0.
+
++ Quick and dirty Perl script to convert NBI Linux images to ELF.
+
++ Patches from Robb Main to handle larger "disks".
+
++ Added a --version option to display version.
+
++ Use lret to jump off to kernel instead of indirect jump through a
+data location.
+
++ Warn if in a .UTF-8 locale as this may affect binary string handling.
+
+Released as mknbi-1.4.1 (production)
index 3367250..3f3d0ce 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
-VERSION=1.4.0
+VERSION=1.4.1
 EXTRAVERSION=
-TARVERSION=1.4.0
+TARVERSION=1.4.1
 # spec file can override
 RPMVERSION=$(VERSION)
 
@@ -17,7 +17,7 @@ ASM=nasm
 # This one makes multiple versions
 FIRSTRELOCS=   0x92800 0x82800
 OLDGAS:=       $(shell $(AS) --version | grep -q '2\.9\.1' && echo -DGAS291)
-CFLAGS=                -Os -ffreestanding -fstrength-reduce -fomit-frame-pointer \
+CFLAGS=                -I. -Os -ffreestanding -fstrength-reduce -fomit-frame-pointer \
                -mcpu=i386 \
                -Wall -W -Wno-format -Wno-unused -DVERSION=\"$(VERSION)$(EXTRAVERSION)\"
 LDBINARYFLAG=  --oformat binary
@@ -44,7 +44,7 @@ DOCDIR=               $(INSTPREFIX)/share/doc/mknbi-$(RPMVERSION)
 
 INSTALL=       install
 
-PROG=  mknbi disnbi dismbr disdosbb
+PROG=  mknbi disnbi dismbr disdosbb nbitoelf
 MODULES=Nbi.pm Elf.pm TruncFD.pm
 FIRSTS=        $(foreach i,$(FIRSTRELOCS),first32@$(i).linux first32elf@$(i).linux) \
        first.dos first.fdos menu nfl
@@ -77,6 +77,11 @@ disdosbb:    disdosbb.pl
        cp -p disdosbb.pl disdosbb
        chmod 755 disdosbb
 
+# NBI to ELF converter
+nbitoelf:      nbitoelf.pl
+       cp -p nbitoelf.pl nbitoelf
+       chmod 755 nbitoelf
+
 # 32-bit first stage protected mode call setup program
 first32@%.linux:       start32@%.o first32.o memsizes.o printf.o
        $(LD) -N -Ttext $* -e _start $(LDBINARYFLAG) -o $@ start32@$*.o first32.o memsizes.o printf.o
@@ -217,6 +222,7 @@ install:    all $(ALTBOOT)
        (cd $(BINDIR); ln -sf ../lib/mknbi/disnbi disnbi)
        (cd $(BINDIR); ln -sf ../lib/mknbi/dismbr dismbr)
        (cd $(BINDIR); ln -sf ../lib/mknbi/disdosbb disdosbb)
+       (cd $(BINDIR); ln -sf ../lib/mknbi/nbitoelf nbitoelf)
        -mkdir -p $(MANDIR)
        $(INSTALL) -m 644 mknbi.1 disnbi.1 $(MANDIR)/
        cd $(MANDIR); \
diff --git a/README b/README
index 6685444..9b42197 100644 (file)
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-mknbi.pl 1.4.0
+mknbi.pl 1.4.1
 
 mknbi is a utility for building a tagged image for a kernel for various
 operating systems. It can also build a tagged images for an Etherboot ROM
index eacdfea..08d9bfd 100755 (executable)
@@ -3,6 +3,9 @@
 #
 # AFAIK works on FAT12 and FAT16. Won't work on FAT32
 #
+# 2003.04.28 R. Main.
+#   Fixes for images with > 65535 sectors
+#
 # Placed under GNU Public License by Ken Yap, April 2000
 
 package TruncFD;
@@ -27,8 +30,11 @@ sub truncfd ($)
 
        my ($dummy1, $bytepersect, $sectperclus, $resvsectors, $fats, $rootdirents,
                $sectors, $dummy2, $sectperfat, $sectpertrk, $heads, $hidsectors,
-               $dummy3, $fstype) =
-               unpack('a11vCvCvvavvvva24a5', $buffer);
+               $bigsectors, $dummy3, $fstype) =
+               unpack('a11vCvCvvavvvVVa19a5', $buffer);
+       if ($sectors == 0) {
+           $sectors = $bigsectors;
+       }
        $cylinders = $sectors / ($sectpertrk * $heads);
        $clusters = $sectors / $sectperclus;
        $fatsectors = $fats * $sectperfat;
index 5be98ba..8963cfb 100755 (executable)
--- a/disnbi.pl
+++ b/disnbi.pl
@@ -13,7 +13,7 @@
 use strict;
 
 use vars qw($imagefile $data $curoffset $dirfile @seglengths $vendordata
-       $extract $segnum $status $i);
+       $extract $status $i);
 
 sub getvendordata ($)
 {
@@ -50,7 +50,7 @@ sub one_nbi_segment ($)
 
        my ($flags, $loadaddr, $imagelen, $memlength) = unpack('V4', substr($data, $curoffset));
        $curoffset += 16;
-       print "Segment number $segnum\n";
+       printf "Segment number %d\n", $segnum;
        printf "Load address:\t\t%08x\n", $loadaddr;
        printf "Image length:\t\t%d\n", $imagelen;
        printf "Memory length:\t\t%d\n", $memlength;
@@ -91,7 +91,7 @@ sub decode_nbi
        print "\n";
 
        # Now decode each segment record
-       $segnum = 1;
+       my $segnum = 0;
        do {
                $i = &one_nbi_segment($segnum);
                ++$segnum;
@@ -104,7 +104,7 @@ sub one_elf_segment ($$)
 
        my ($offset, $vaddr, $paddr, $filesz, $memsz, $flags,
                $align) = unpack('@4V6', substr($data, $curoffset));
-       print "Segment number $segnum\n";
+       printf "Segment number %d\n", $segnum;
        printf "Load address:\t\t%08x\n", $vaddr;
        printf "Image length:\t\t%d\n", $filesz;
        printf "Memory length:\t\t%d\n", $memsz;
@@ -121,7 +121,7 @@ sub decode_elf
                print "\tReturn to loader after execution (extension)\n" if ($flags & 0x8000000);
        print "\n";
        $curoffset = $phoff;
-       foreach $i (1..$phnum) {
+       foreach $i (0..$phnum-1) {
                &one_elf_segment($i, $curoffset);
                $curoffset += $phentsize;
        }
@@ -153,7 +153,7 @@ if ($magic eq "\x36\x13\x03\x1B") {
 exit(0) if ($extract == 0);
 print "Dumping directory to `$dirfile'...\n";
 open(O, ">$dirfile") or die "$dirfile: $!\n";
-binmode(0);
+binmode(O);
 print O $data;
 close(O);
 $data = '';
index fe59077..9b99bc8 100644 (file)
@@ -3,6 +3,10 @@
 ; Copyright (C) 1996-1998 Gero Kuhlmann   <gero@gkminix.han.de>
 ; Modifications for booting FreeDOS by Ken Yap <ken_yap@users.sourceforge.net>
 ;
+; 2003.04.28 Robb Main
+;  Tweaks & bugfixes to allow use with much larger disk images, remove
+;  '2 head assumption', use 32-bit GDT, and other 'stuff'.
+;
 ;  This program is free software; you can redistribute it and/or modify
 ;  it under the terms of the GNU General Public License as published by
 ;  the Free Software Foundation; either version 2 of the License, or
@@ -169,7 +173,13 @@ getrd:     mov     si,CON(recerr)
        shl     bx,CON(1)
        SEGES
        mov     ax,[di+bx+BOOT_LD_SECNUM]       ; get number of sectors
-       mov     LOC(secnum),ax
+       mov     LOC(secnumlo),ax
+       SEGES
+       mov     ax,[di+bx+BOOT_LD_SECNUM+2]     ; get number of sectors
+       mov     LOC(secnumhi),ax
+       SEGES
+       mov     ax,[di+bx+BOOT_LD_HEADS]        ; get head count
+       mov     LOC(heads),al
        SEGES
        mov     ax,[di+bx+BOOT_LD_SPT]          ; get sectors per track
        mov     LOC(secptk),al
@@ -240,11 +250,15 @@ gotnum:   mov     LOC(drvnum),dl          ; save number of disk drives
        mov     ax,CON(TEMP_SEGMENT)
        mov     es,ax                   ; pointer to temporary buffer
        xor     bx,bx
-       xor     al,al                   ; indicate read
        xor     dx,dx                   ; first sector
+       xor     ax,ax
+       xor     ch,ch                   ; indicate read
+       mov     cl,1                    ; one sector
        call    rwsect                  ; read boot sector
+       
        mov     si,CON(rderr)
        jc      doerr2
+
        cmp     BLOC(drvid),CON(0x80)   ; if the ram disk is simulates a
        jb      chkbot                  ; floppy, there is no partition table
 
@@ -252,43 +266,56 @@ gotnum:   mov     LOC(drvnum),dl          ; save number of disk drives
        SEGES
        cmp     BLOC(PART_STATUS),CON(PART_ACTIVE)
        jne     doerr2
+       
        SEGES
        cmp     BLOC(PART_TYPE),CON(PART_FAT16)
        je      partok
+       
        SEGES
        cmp     BLOC(PART_TYPE),CON(PART_FAT12)
        jne     doerr2
-partok:        SEGES
-       mov     dx,[PART_ABS_SECT+0]    ; get number of first sector
+partok:
        SEGES
-       mov     ax,[PART_ABS_SECT+2]
-       or      ax,ax
-       jnz     doerr2
-       xor     al,al                   ; indicate read
+       mov     dx,[PART_ABS_SECT+2]    ; get number of first sector
+       SEGES
+       mov     ax,[PART_ABS_SECT+0]
+       xor     ch,ch                   ; indicate read
+       mov     cl,1                    ; one sector
        call    rwsect                  ; read boot sector
        mov     si,CON(rderr)
        jc      doerr2
+
 #ifndef        HD_PARM_CHECK
        JMP(dobotp)
 #endif
 
-chkbot:        mov     si,CON(dskerr)          ; prepare for correct error message
+chkbot:
+       mov     si,CON(dskerr)          ; prepare for correct error message
        mov     al,LOC(drvid)
        SEGES
        cmp     BLOC(DISK_BOOT),al      ; check boot disk number
        jne     doerr2
+
        SEGES
        cmp     WLOC(DISK_BPS),CON(SECT_SIZE)   ; check sector size
        jne     doerr2
+
        SEGES
        cmp     WLOC(DISK_HEADS),BCON(16)       ; check number of heads
        jg      doerr2
+
        SEGES
        mov     ax,LOC(DISK_SPT)        ; check number of sectors per track
        cmp     al,LOC(secptk)
        je      dobotp
-
-doerr2:        call    prnstr                  ; in case of error return to the
+doerr2:        
+       call    prnstr                  ; in case of error return to the
+#if 1
+       push    ax
+       mov     ah,0                    ; wait for a keypress, so user
+       int     0x16                    ; can read the error message
+       pop     ax
+#endif
        mov     si,LOC(oldSI)           ; boot rom with registers set
        mov     di,LOC(oldDI)           ; correctly
        mov     bp,LOC(oldBP)
@@ -567,7 +594,6 @@ lop:        JMP(lop)
 #endif
 
 
-
 ;====================================================================
 ;
 ; Setup DOS drive parameter block (DPB) for floppy disk drive. The
@@ -912,7 +938,6 @@ oldDI:      dw      0                       ; old DI from boot rom
 ;
 
        ALIGN(16)                       ; has to be paragraph aligned
-
 start_resident:                                ; indicate start of resident section
 
 
@@ -1028,7 +1053,6 @@ intF88:   or      al,al
 intF89:        iret
 
 
-
 ;====================================================================
 ;
 ; New interrupt 13h routine to handle disk accesses. It is different
@@ -1260,58 +1284,64 @@ f1301:  push    es
 
 ;====================================================================
 ;
-; Function 02/03 - read/write from disk
+; Function 02/03 - read from/write to disk
 
 f1302:
-f1303: pop     bx                      ; get old BX from stack
+f1303:
+       pop     bx                      ; get old BX from stack
        push    dx
+       push    cx
+       push    bx
        push    ax
+
+       xchg    cx,ax
+       sub     ch,2                    ; ch=0 for reads, ch=1 for writes
        call    cvtsec                  ; get linear sector number
+       jnc     f13026
+
        pop     ax
-       jnc     f13021
        mov     ah,CON(0x04)            ; error: sector not found
-f13028:        pop     dx
+f13021:        
+       pop     bx
+       pop     cx
+       pop     dx
        stc
        JMP(f13end)                     ; terminate
+f13022:
+       cmp     dx,LOC(secnumhi)        ; check if sector is still correct
+       jb      f13024
+       
+       cmp     ax,LOC(secnumlo)
+       jbe     f13024
 
-f13021:        push    cx
-       push    bx
-       push    ax
-       mov     cl,al                   ; move number of sectors into CX
-       xor     ch,ch
-f13022:        jcxz    f13026
-       cmp     dx,LOC(secnum)          ; check if sector is still correct
-       jb      f13023
-       pop     ax
        mov     ah,CON(0x04)            ; error: sector not found
-f13027:        sub     al,cl                   ; compute number of sectors processed
+f13023:
        pop     bx
-       pop     cx
-       JMP(f13028)
-
-f13023:        pop     ax
-       push    ax
-       xor     al,al
-       cmp     ah,CON(0x02)            ; check if read or write sector
-       je      f13024
-       inc     al
-f13024:        call    rwsect                  ; actually handle request
+       mov     al,bl
+       sub     al,cl                   ; compute number of sectors processed
+       JMP(f13021)
+f13024:
+       call    rwsect                  ; actually handle request
        jnc     f13025
-       pop     ax
-       mov     ah,CON(0x20)            ; error: disk controller error
-       JMP(f13027)
 
-f13025:        inc     dx
-       dec     cx                      ; proceed with next sector
-       add     bx,CON(SECT_SIZE)
-       JMP(f13022)
-
-f13026:        pop     ax
+       mov     ah,CON(0x20)            ; error: disk controller error
+       JMP(f13023)
+f13025:
+       inc     ax                      ; proceed with next linear sector
+       adc     dx,CON(0)
+       add     bx,CON(SECT_SIZE)       ; increment src/dst address
+       dec     cl                      ; decrement sector count
+f13026:
+       or      cl,cl
+       jnz     f13022
+f13027:
+       pop     ax
        pop     bx
        pop     cx
        pop     dx
        xor     ah,ah                   ; no error
-f13e1: JMP(f13end)
+f13e1:
+       JMP(f13end)
 
 
 
@@ -1323,7 +1353,8 @@ f1308:    pop     bx                      ; get old BX from stack
        mov     dl,LOC(drvnum)          ; get number of disk drives
        mov     cl,LOC(secptk)          ; get sectors per track
        mov     ch,LOC(cylnum)          ; number of cylinders
-       mov     dh,CON(1)               ; number of heads - 1
+       mov     dh,LOC(heads)           ; number of heads - 1
+       dec     dh
        xor     bx,bx                   ; ramdisk drive type
        xor     ax,ax
        dec     ch
@@ -1374,13 +1405,16 @@ f1318:  pop     bx                      ; get old BX from stack
 
 f130C: pop     bx                      ; get old BX from stack
        push    dx
+       push    cx
        push    ax
+       xchg    ax,cx
        call    cvtsec                  ; get linear sector number
        pop     ax
        mov     ah,CON(0x00)            ; no error
        jnc     f130C1
        mov     ah,CON(0x04)            ; error: sector not found
-f130C1:        pop     dx
+f130C1:        pop     cx
+       pop     dx
        JMP(f13e1)                      ; terminate
 
 
@@ -1394,117 +1428,144 @@ f1315:        pop     bx                      ; get old BX from stack
        cmp     dl,CON(0x80)            ; check if floppy disk type requested
        jb      f13159
        inc     ah                      ; indicate hard disk
-       mov     dx,LOC(secnum)          ; get number of sectors on disk
-       xor     cx,cx
+       mov     dx,LOC(secnumlo)        ; get number of sectors on disk
+       mov     cx,LOC(secnumhi)
 f13159:        clc
        JMP(f13e1)
 
 
-
 ;====================================================================
 ;
 ; Convert Cyl/Sec/Head notation into a linear sector number
-; Input:  CH  -  cylinder number
-;         CL  -  sector number
+; Input:  AH  -  cylinder number
+;         AL  -  sector number
 ;         DH  -  head number
-; Output: DX  -  linear sector number
+; Output: DX:AX  -  32-bit linear sector number
 ;         carry flag set if invalid sector number
 ; Registers changed: AX,DX
 
-cvtsec:        push    cx
-       cmp     dh,CON(2)               ; check if head number is correct
-       jae     cvts8                   ; maximum number of heads is always 2
-       mov     dl,dh
-       xor     dh,dh                   ; move current head number into DX
-       mov     al,ch
-       mov     ch,cl
-       mov     ah,cl                   ; compute track number into AX, the
+cvtsec:        push    bx
+       push    cx
+
+       mov     bl,al                   ; move sector number into BL
+       mov     bh,dh                   ; move head number into BH
+       
+       xchg    ah,al                   ; compute track number into AX, the
        mov     cl,CON(6)               ; upper two bits of CL are the high
        shr     ah,cl                   ; bits of the 10 bit cylinder number
-       shl     ax,CON(1)               ; compute track number from cylinders
-       add     ax,dx
-       mov     dl,LOC(secptk)
-       xor     dh,dh
-       mul     dx                      ; compute number of track starting
-       or      dx,dx                   ; sector
-       jnz     cvts8                   ; should not be more than 65535 sectors
-
-       mov     dl,ch
-       and     dl,CON(0x3F)            ; move sector number into AX
-       cmp     dl,LOC(secptk)          ; check if sector number is correct
+       xor     dx,dx
+       xor     cx,cx
+       mov     cl,LOC(heads)
+       mul     cx                      ; compute track number from cylinders
+       mov     cl,bh
+       add     ax,cx
+       adc     dx,CON(0)
+       mov     cl,LOC(secptk)
+       push    bx
+       xor     bx,bx
+       or      dx,dx                   ; is 32-bit value > 16-bits yet?
+       jz      cvts6
+       
+       push    ax
+       push    dx
+       mov     ax,dx                   ; multiply upper 16-bits first
+       mul     cx
+       mov     bx,ax                   ; save result in bx
+       pop     dx
+       pop     ax
+cvts6:
+       mul     cx                      ; compute number of track starting
+       add     dx,bx                   ; fixup upper 16-bits
+       pop     bx
+
+       mov     cl,bl
+       and     cl,CON(0x3F)            ; move sector number into AX
+       cmp     cl,LOC(secptk)          ; check if sector number is correct
        ja      cvts8
-       xor     dh,dh
-       dec     dx                      ; sector numbers start with 1
+
+       dec     cx                      ; sector numbers start with 1
        js      cvts8                   ; therefore sector 0 does not exist
-       add     dx,ax                   ; compute final sector number
-       jc      cvts8                   ; should never overflow
-       cmp     dx,LOC(secnum)          ; check if the sector is valid
-       jae     cvts8
-       clc                             ; no error
+
+       add     ax,cx                   ; compute final sector number
+       adc     dx,CON(0)
+
+       cmp     dx,LOC(secnumhi)        ; check if the sector is valid
+       jb      cvts8
+       ja      cvts7
+
+       cmp     ax,LOC(secnumlo)
+       jb      cvts8
+cvts7:
+       stc
        JMP(cvts9)
-cvts8: stc                             ; return with error
-cvts9: pop     cx
+cvts8:
+       clc                             ; return with error
+cvts9:
+       pop     cx
+       pop     bx
        ret
 
 
-
 ;====================================================================
 ;
 ; Read/write a sector from the ram disk. This routine requires a
 ; sector to be 512 bytes long.
-; Input:  AL     -  non-zero if write to ram disk
-;         DX     -  logical sector number
+; Input:  CH     -  non-zero if write to ram disk
+;         DX:AX  -  logical sector number
 ;         ES:BX  -  pointer to destination buffer
 ; Output: carry flag set if error
 ; Registers changed: AX
 
-rwsect:        push    cx
+rwsect:
+       push    si
+       push    di
+       push    cx
        push    dx
-       mov     ch,al                   ; save direction indicator
-       mov     dx,es
-       mov     ax,dx
-       mov     cl,CON(12)
-       shr     ax,cl
-       mov     cl,CON(4)
-       shl     dx,cl                   ; compute linear buffer address
-       add     dx,bx
-       adc     ax,CON(0)
+       push    ax
+
+       mov     si,rd_srcb
+       mov     di,rd_dstb
        or      ch,ch                   ; check direction of transfer
        jz      rwsec1
-       mov     LOC(rd_srcb+0),dx       ; set source address for write
-       mov     LOC(rd_srcb+2),al
-       JMP(rwsec2)
-rwsec1:        mov     LOC(rd_dstb+0),dx       ; set destination address for read
-       mov     LOC(rd_dstb+2),al
-rwsec2:        pop     dx
 
-       push    dx
-       mov     ax,dx
-       mov     cl,CON(9)
-       shl     dx,cl                   ; compute linear ramdisk address
-       mov     cl,CON(7)               ; from sector number
-       shr     ax,cl
-       add     dx,LOC(rdaddr+0)
-       adc     ax,LOC(rdaddr+2)
-       or      ch,ch                   ; check direction of transfer
-       jz      rwsec3
-       mov     LOC(rd_dstb+0),dx       ; set destination address for write
-       mov     LOC(rd_dstb+2),al
-       JMP(rwsec4)
-rwsec3:        mov     LOC(rd_srcb+0),dx       ; set source address for read
-       mov     LOC(rd_srcb+2),al
-rwsec4:        push    es
-       push    si
+       mov     si,rd_dstb
+       mov     di,rd_srcb
+rwsec1:
+       mov     cx,CON(SECT_SIZE)       ; compute linear ramdisk address
+       mul     cx                      ; from sector number
+       add     ax,LOC(rdaddr+0)
+       adc     dx,LOC(rdaddr+2)
+
+       mov     [si],ax                 ; set src for read, dst for write
+       mov     [si+2],dl
+       mov     [si+5],dh
+
+       mov     ax,es
+       xor     dx,dx
+       mov     cl,CON(0x10)
+       xor     ch,ch
+       mul     cx                      ; compute linear buffer address
+       add     ax,bx
+       adc     dx,CON(0)
+
+       mov     [di],ax                 ; set dst for read, src for write
+       mov     [di+2],dl
+       mov     [di+5],dh
+
+       push    es
        mov     ax,cs
        mov     es,ax
        mov     si,CON(rd_gdt)
        mov     cx,CON(SECT_SIZE/2)     ; copy 512 bytes, e.g. 256 words
        mov     ax,CON(0x8700)          ; let the BIOS move the sector
        int     0x15
-       pop     si
        pop     es
+
+       pop     ax
        pop     dx
        pop     cx
+       pop     di
+       pop     si
        ret
 
 
@@ -1879,8 +1940,10 @@ statof:          dw      BIOS_FDSTAT     ; offset to BIOS disk status byte
 rdaddr:                dd      0               ; base address of ram disk
 rdsize:                dw      0               ; size of ram disk in kb
 cylnum:                dw      80              ; number of cylinders
-secnum:                dw      2400            ; number of sectors on disk
+secnumlo:      dw      2400            ; number of sectors on disk
+secnumhi:      dw      0
 secptk:                dw      15              ; number of sectors per track
+heads:         db      1               ; number of heads
 drvnum:                db      1               ; number of disk drives
 drvid:         db      0               ; ram disk drive id
 nohd:          db      0               ; no-hard-disk flag
@@ -1907,6 +1970,8 @@ newtos:                                   ; new top of stack
 if1sig:                STRDECL('NetB')
 
 
+       ALIGN(16)                       ; has to be paragraph aligned
+
 ; Descriptor table to access ram disk using the BIOS
 
 rd_gdt:                dw      0,0,0,0
@@ -1914,11 +1979,13 @@ rd_gdt:         dw      0,0,0,0
 rd_src:                dw      0xffff          ; length
 rd_srcb:       db      0,0,0           ; base
                db      0x93            ; typebyte
-               dw      0               ; limit16,base24 =0
+               db      0               ; limit16 =0
+rd_srcbh:      db      0               ; base24
 rd_dst:                dw      0xffff          ; length
 rd_dstb:       db      0,0,0           ; base
                db      0x93            ; typebyte
-               dw      0               ; limit16,base24 =0
+               db      0               ; limit16 =0
+rd_dstbh:      db      0               ; base24
                dw      0,0,0,0         ; BIOS CS
                dw      0,0,0,0         ; BIOS DS
 
index b3ef499..4f79e15 100644 (file)
 #define BOOT_FLAG_EOF  0x04            /* mask for load record flag EOF */
 
 #define BOOT_LD_SECNUM 0               /* offset of total number of sectors */
-#define BOOT_LD_SPT    2               /* offset of sectors per track */
-#define BOOT_LD_CYL    4               /* offset of number of cylinders */
-#define BOOT_LD_DRIVE  6               /* offset of boot drive ID */
-#define BOOT_LD_NOHD   7               /* offset of no-hard-disk flag */
+#define BOOT_LD_HEADS   4              /* offset of head count */
+#define BOOT_LD_SPT    6               /* offset of sectors per track */
+#define BOOT_LD_CYL    8               /* offset of number of cylinders */
+#define BOOT_LD_DRIVE  10              /* offset of boot drive ID */
+#define BOOT_LD_NOHD   11              /* offset of no-hard-disk flag */
 
 
 
index a06c638..fcb3ea3 100644 (file)
--- a/mknbi.pl
+++ b/mknbi.pl
@@ -3,6 +3,9 @@
 # Program to create a netboot image for ROM/FreeDOS/DOS/Linux
 # Placed under GNU Public License by Ken Yap, December 2000
 
+# 2003.04.28 R. Main
+#  Tweaks to work with new first-dos.S for large disk images
+
 BEGIN {
        push(@INC, '@@LIBDIR@@');
 }
@@ -20,9 +23,11 @@ use constant;
 use constant DEBUG => 0;
 use constant LUA_VERSION => 0x04000100;        # 4.0.1.0
 
+use bytes;
+
 use vars qw($libdir $version $format $target $output $module $relocseg $relocsegstr
        $progreturns $param $append $rootdir $rootmode $ip $ramdisk $rdbase
-       $simhd $dishd $squashfd $first32);
+       $simhd $dishd $squashfd $first32 $showversion);
 
 sub check_file
 {
@@ -229,37 +234,48 @@ sub get_geom ($$)
 {
        my ($file, $block) = @_;
        my ($usedsize, $declsize, $firsttracksize, $geom_string, $fstype);
-       my ($secttot, $secttrk, $heads, $bootid, $sig, $cyltot);
+       my ($secttot, $secttrk, $heads, $bigsectors, $bootid, $sig, $cyltot);
 
        ($usedsize = $squashfd ? &TruncFD::truncfd($file) : -s $file) > 0
                or die "Error reading $file\n";
-       (undef, $secttot, undef, $secttrk, $heads, undef, $bootid, undef,
-               $fstype, $sig) = unpack('a19va3vva8Ca17a5@510a2', $$block);
+       (undef, $secttot, undef, $secttrk, $heads, undef, $bigsectors, $bootid, undef,
+               $fstype, $sig) = unpack('a19va3vva4VCa17a5@510a2', $$block);
        print STDERR "Warning, this doesn't appear to be a DOS boot sector\n"
                if ($sig ne "\x55\xAA");
+       
+       if ($secttot == 0) {
+           $secttot = $bigsectors;
+       }
+       
+       print STDERR "Geometry...\n";
+       print STDERR "totSect:$secttot,spt:$secttrk,hd:$heads,bid:$bootid,fsType:$fstype,sig:$sig,simhd:$simhd\n";
+
        if ($simhd) {
                # change MediaDescriptor
                substr($$block, 0x15, 1) = "\xF8";
                # change HiddenSectors
-               substr($$block, 0x1c, 4) = pack('V', $secttrk * $heads);
+               substr($$block, 0x1c, 4) = pack('V', $secttrk);
                # change the boot drive
                substr($$block, 0x24, 1) = "\x80";
        }
        $cyltot = $secttot / ($secttrk * $heads);
        $declsize = $secttot * 512;
-       $firsttracksize = $secttrk * $heads * 512;
+       $firsttracksize = $secttrk * 512;
        print STDERR "Warning, used size $usedsize is greater than declared size $declsize\n"
                if ($usedsize > $declsize);
-       $geom_string = pack('v3C2', $secttot, $secttrk, $cyltot, $simhd ? 0x80 : 0, $dishd);
+               
+       print STDERR "cyl:$cyltot,decl_size:$declsize,used_size:$usedsize\n";
+               
+       $geom_string = pack('Vv3C2', $secttot, $heads, $secttrk, $cyltot, $simhd ? 0x80 : 0, $dishd);
        return ($usedsize, $declsize, $firsttracksize, $geom_string, $fstype);
 }
 
 sub mod_geom_string ($)
 {
        my ($geom_string) = @_;
-       my ($secttot, $secttrk, $cyltot, $simhd, $dishd) = unpack('v3C2', $geom_string);
+       my ($secttot, $heads, $secttrk, $cyltot, $simhd, $dishd) = unpack('Vv3C2', $geom_string);
        $cyltot++;      # for partition table
-       return (pack('v3C2', $secttot, $secttrk, $cyltot, $simhd, $dishd));
+       return (pack('Vv3C2', $secttot, $heads, $secttrk, $cyltot, $simhd, $dishd));
 }
 
 sub encode_chs ($$$)
@@ -274,18 +290,22 @@ sub encode_chs ($$$)
 sub make_mbr ($$)
 {
        my ($geom_string, $fstype) = @_;
-       my ($heads, $bootsect);
-       my ($secttot, $secttrk, $cyltot, $simhd, $x) = unpack('v3C2', $geom_string);
+       my ($bootsect);
+       my ($secttot, $heads, $secttrk, $cyltot, $simhd, $x) = unpack('Vv3C2', $geom_string);
 
        $cyltot--;
        # $cyltot was incremented in mod_geom_string
-       $heads = $secttot / ($secttrk * $cyltot);
+#      $heads = $secttot / ($secttrk * $cyltot);
        # bootsect is first sector of track 1
-       $bootsect = $secttrk * $heads;
+       $bootsect = $secttrk;
+       
+       print STDERR "--- Making MBR\n";
+       print STDERR "cyls:$cyltot,heads:$heads,spt:$secttrk,totalSect:$secttot,FSTYPE:$fstype,BS:$bootsect\n";
+       
        # CHS stupidity:
        # cylinders is 0 based, heads is 0 based, but sectors is 1 based
        # 0x01 for FAT12, 0x04 for FAT16
-       return (pack('@446C8V2@510v', 0x80, &encode_chs(1, 0, 1),
+       return (pack('@446C8V2@510v', 0x80, &encode_chs(0, 1, 1),
                $fstype eq 'FAT12' ? 0x01 : 0x04, &encode_chs($cyltot, $heads - 1, $secttrk),
                $bootsect, $secttot, 0xAA55));
 }
@@ -504,6 +524,7 @@ sub mkelf_lua ($)
 $libdir = '@@LIBDIR@@';                # where config and auxiliary files are stored
 
 $version = '@@VERSION@@';
+$showversion = '';
 $simhd = 0;
 $dishd = 0;
 $squashfd = 1;
@@ -523,7 +544,21 @@ GetOptions('format=s' => \$format,
        'squash!' => \$squashfd,
        'first32:s' => \$first32,
        'progreturns!' => \$progreturns,
-       'relocseg=s' => \$relocsegstr);
+       'relocseg=s' => \$relocsegstr,
+       'version' => \$showversion);
+
+if ($showversion) {
+       print STDERR "$version\n";
+       exit 0;
+}
+
+if ($ENV{LANG} =~ /\.UTF-8$/i) {
+       print STDERR <<'EOF';
+Warning: Perl 5.8 may have a bug that affects handing of strings in Unicode
+locales that may cause misbehaviour with binary files.  To work around this
+problem, set $LANG to not have a suffix of .UTF-8 before running this program.
+EOF
+}
 
 $0 =~ /mk([a-z]*)-([a-z]+)$/ and ($format = $1, $target = $2);
 if (!defined($format)) {
@@ -591,6 +626,8 @@ mknbi - make network bootable image
 
 =head1 SYNOPSIS
 
+B<mknbi> --version
+
 B<mknbi> --format=I<format> --target=I<target> [--output=I<outputfile>] I<target-specific-arguments>
 
 B<mknbi-linux> [--output=I<outputfile>] I<kernelimage> [I<ramdisk>]
@@ -621,6 +658,9 @@ which are ROM boot loaders.  If you are looking to boot using PXE, look
 no further, mknbi is not what you want. You probably want something like
 PXELINUX which is part of the SYSLINUX package.
 
+B<mknbi> --version prints the current version. Use this before reporting
+problems.
+
 B<mknbi> can be invoked with the B<--format> and B<--target> options or
 links can be made to it under format and target specific names. E.g.
 mkelf-linux is the same as mknbi --format=elf --target=linux.
index a7d36a6..593e7f8 100644 (file)
--- a/start32.S
+++ b/start32.S
@@ -226,7 +226,7 @@ basememsize:
        ret
 
 /**************************************************************************
-XSTART - Transfer control to the kernel just loaded
+XSTART - Transfer control to the kernel just loaded in real mode
 **************************************************************************/
        .globl  xstart
 xstart:
@@ -241,13 +241,13 @@ xstart:
        andl    $0xF,%eax
        andl    $0xFFFFFFF0,%ebx
        shll    $12,%ebx
-       orl     %ebx,%eax
-       movl    %eax,_execaddr
+       orl     %eax,%ebx
        call    _prot_to_real
        .code16
        movl    $((RELOC<<12)+(1f-RELOC)),%eax
        pushl   %eax
-       ADDR32  LJMPI(_execaddr-_start)
+       pushl   %ebx
+       lret
 1:
        addw    $4,%sp          /* XXX or is this 10 in case of a 16bit "ret" */
        DATA32 call     _real_to_prot
@@ -258,9 +258,6 @@ xstart:
        popl    %ebp
        ret
 
-_execaddr:
-       .long   0
-
 /**************************************************************************
 _REAL_TO_PROT - Go from REAL mode to Protected Mode
 **************************************************************************/
index 9bb5600..b800a14 100644 (file)
@@ -302,7 +302,9 @@ real16:
        call    *RADDR(real_ip)
 
        /* Save the stack pointer */
-       cs
+       /* Reload %ds */
+       movw    %cs, %ax
+       movw    %ax, %ds
        movw    %sp, RADDR(real_sp)
 
        /* Disable interrupts */