* MEMDISK: New subsystem; this is a driver which allows
legacy OSes to boot using an in-memory simulated disk.
See memdisk/memdisk.doc for more info.
+ * PXELINUX, ISOLINUX: Correctly handle files larger than 65535
+ blocks (32 MB for PXELINUX, 128 MB for ISOLINUX.)
Changes in 1.64:
* Limited support for hardware flow control when using a
RootDir resb dir_t_size ; Root directory
CurDir resb dir_t_size ; Current directory
SavedSSSP resd 1 ; Our SS:SP while running a COMBOOT image
+KernelClust resd 1 ; Kernel size in clusters
+InitRDClust resd 1 ; Ramdisk size in clusters
InitStack resd 1 ; Initial stack pointer (SS:SP)
FirstSecSum resd 1 ; Checksum of bytes 64-2048
ImageDwords resd 1 ; isolinux.bin size, dwords
FBytes equ $ ; Used by open/getc
FBytes1 resw 1
FBytes2 resw 1
-KernelClust resw 1 ; Kernel size in clusters
-InitRDClust resw 1 ; Ramdisk size in clusters
FClust resw 1 ; Number of clusters in open/getc file
FNextClust resw 1 ; Pointer to next cluster in d:o
FPtr resw 1 ; Pointer to next char in buffer
push word real_mode_seg
pop es
- push ax
- push dx
- div word [ClustSize] ; # of clusters total
- and dx,dx ; Round up
- setnz dl
- movzx dx,dl
- add ax,dx
- mov [KernelClust],ax
- pop dx
- pop ax
- mov [KernelSize],ax
- mov [KernelSize+2],dx
+ movzx eax,ax ; Fix this by using a 32-bit
+ shl edx,16 ; register for the kernel size
+ or eax,edx
+ mov [KernelSize],eax
+ xor edx,edx
+ div dword [ClustSize] ; # of clusters total
+ ; Round up...
+ add edx,byte -1 ; Sets CF if EDX >= 1
+ adc eax,byte 0 ; Add 1 to EAX if CF set
+ mov [KernelClust],eax
+
;
; Now, if we transfer these straight, we'll hit 64K boundaries. Hence we
; have to see if we're loading more than 64K, and if so, load it step by
; step.
;
- mov dx,1 ; 10000h
- xor ax,ax
- div word [ClustSize]
- mov [ClustPerMoby],ax ; Clusters/64K
+
;
; Start by loading the bootsector/setup code, to see if we need to
; do something funky. It should fit in the first 32K (loading 64K won't
; If we have larger than 32K clusters, yes, we're hosed.
;
call abort_check ; Check for abort key
- mov cx,[ClustPerMoby]
- shr cx,1 ; Half a moby
- cmp cx,[KernelClust]
+ mov ecx,[ClustPerMoby]
+ shr ecx,1 ; Half a moby
+ cmp ecx,[KernelClust]
jna .normalkernel
- mov cx,[KernelClust]
+ mov ecx,[KernelClust]
.normalkernel:
- sub [KernelClust],cx
+ sub [KernelClust],ecx
xor bx,bx
pop si ; Cluster pointer on stack
call getfssec
mov si,dot_msg ; Progress report
call cwritestr
call abort_check
- mov cx,[KernelClust]
- and cx,cx
+ mov ecx,[KernelClust]
+ and ecx,ecx
jz high_load_done ; Zero left (tiny kernel?)
- cmp cx,[ClustPerMoby]
+ cmp ecx,[ClustPerMoby]
jna high_last_moby
- mov cx,[ClustPerMoby]
+ mov ecx,[ClustPerMoby]
high_last_moby:
- sub [KernelClust],cx
+ sub [KernelClust],ecx
xor bx,bx ; Load at offset 0
pop si ; Restore cluster pointer
call getfssec
mov [HiLoadAddr],edi ; Point to next target area
popf ; Restore EOF
jc high_load_done ; If EOF we are done
- cmp word [KernelClust],byte 0 ; Are we done?
+ cmp dword [KernelClust],byte 0 ; Are we done?
jne high_load_loop ; Apparently not
high_load_done:
pop si ; No longer needed
;
load_initrd:
test byte [initrd_flag],1
- jz nk_noinitrd
+ jz near nk_noinitrd
push es ; ES->real_mode_seg
push ds
pop es ; We need ES==DS
mov [initrd_ptr],si ; Save cluster pointer
mov [es:su_ramdisklen1],ax ; Ram disk length
mov [es:su_ramdisklen2],dx
- div word [ClustSize]
- and dx,dx ; Round up
- setnz dl
- movzx dx,dl
- add ax,dx
- mov [InitRDClust],ax ; Ramdisk clusters
+ movzx eax,ax
+ shl edx,16
+ or eax,edx
+ xor edx,edx
+ div dword [ClustSize]
+ ; Round up...
+ add edx,byte -1 ; Sets CF if EDX >= 1
+ adc eax,byte 0 ; Add 1 to EAX if CF set
+ mov [InitRDClust],eax ; Ramdisk clusters
mov edx,[HighMemSize] ; End of memory
dec edx
mov eax,[RamdiskMax] ; Highest address allowed by kernel
call cwritestr
pop si ; Restore cluster pointer
call abort_check
- mov cx,[InitRDClust]
- cmp cx,[ClustPerMoby]
+ mov ecx,[InitRDClust]
+ cmp ecx,[ClustPerMoby]
jna rd_last_moby
- mov cx,[ClustPerMoby]
+ mov ecx,[ClustPerMoby]
rd_last_moby:
- sub [InitRDClust],cx
+ sub [InitRDClust],ecx
xor bx,bx ; Load at offset 0
push word xfer_buf_seg ; Bounce buffer segment
pop es
call bcopy ; Does not change flags!!
jc rd_load_done ; EOF?
add dword [InitRDat],10000h ; Point to next 64K
- cmp word [InitRDClust],byte 0 ; Are we done?
+ cmp dword [InitRDClust],byte 0 ; Are we done?
jne rd_load_loop ; Apparently not
rd_load_done:
pop si ; Clean up the stack
; **** ISOLINUX:: We may have to make this flexible, based on what the
; **** BIOS expects our "sector size" to be.
;
- alignb 2, db 0
-ClustSize dw SECTORSIZE ; Bytes/cluster
+ alignb 4, db 0
+ClustSize dd SECTORSIZE ; Bytes/cluster
+ClustPerMoby dd 65536/SECTORSIZE ; Clusters per 64K
SecPerClust dw 1 ; Same as bsSecPerClust, but a word
BufSafe dw trackbufsize/SECTORSIZE ; Clusters we can load into trackbuf
BufSafeSec dw trackbufsize/SECTORSIZE ; = how many sectors?
BufSafeBytes dw trackbufsize ; = how many bytes?
EndOfGetCBuf dw getcbuf+trackbufsize ; = getcbuf+BufSafeBytes
-ClustPerMoby dw 65536/SECTORSIZE ; Clusters per 64K
%if ( trackbufsize % SECTORSIZE ) != 0
%error trackbufsize must be a multiple of SECTORSIZE
%endif
PXEEntry resd 1 ; !PXE API entry point
SavedSSSP resd 1 ; Our SS:SP while running a COMBOOT image
RebootTime resd 1 ; Reboot timeout, if set by option
+KernelClust resd 1 ; Kernel size in clusters
+InitRDClust resd 1 ; Ramdisk size in clusters
FBytes equ $ ; Used by open/getc
FBytes1 resw 1
FBytes2 resw 1
-KernelClust resw 1 ; Kernel size in clusters
-InitRDClust resw 1 ; Ramdisk size in clusters
FClust resw 1 ; Number of clusters in open/getc file
FNextClust resw 1 ; Pointer to next cluster in d:o
FPtr resw 1 ; Pointer to next char in buffer
push word real_mode_seg
pop es
- push ax
- push dx
- div word [ClustSize] ; # of clusters total
- and dx,dx ; Round up
- setnz dl
- movzx dx,dl
- add ax,dx
- mov [KernelClust],ax
- pop dx
- pop ax
- mov [KernelSize],ax
- mov [KernelSize+2],dx
+ movzx eax,ax ; Fix this by using a 32-bit
+ shl edx,16 ; register for the kernel size
+ or eax,edx
+ mov [KernelSize],eax
+ xor edx,edx
+ div dword [ClustSize] ; # of clusters total
+ ; Round up...
+ add edx,byte -1 ; Sets CF if EDX >= 1
+ adc eax,byte 0 ; Add 1 to EAX if CF set
+ mov [KernelClust],eax
+
;
; Now, if we transfer these straight, we'll hit 64K boundaries. Hence we
; have to see if we're loading more than 64K, and if so, load it step by
; step.
;
- mov dx,1 ; 10000h
- xor ax,ax
- div word [ClustSize]
- mov [ClustPerMoby],ax ; Clusters/64K
+
;
; Start by loading the bootsector/setup code, to see if we need to
; do something funky. It should fit in the first 32K (loading 64K won't
; If we have larger than 32K clusters, yes, we're hosed.
;
call abort_check ; Check for abort key
- mov cx,[ClustPerMoby]
- shr cx,1 ; Half a moby
- cmp cx,[KernelClust]
+ mov ecx,[ClustPerMoby]
+ shr ecx,1 ; Half a moby
+ cmp ecx,[KernelClust]
jna .normalkernel
- mov cx,[KernelClust]
+ mov ecx,[KernelClust]
.normalkernel:
- sub [KernelClust],cx
+ sub [KernelClust],ecx
xor bx,bx
pop si ; Cluster pointer on stack
call getfssec
mov si,dot_msg ; Progress report
call cwritestr
call abort_check
- mov cx,[KernelClust]
- and cx,cx
+ mov ecx,[KernelClust]
+ and ecx,ecx
jz high_load_done ; Zero left (tiny kernel?)
- cmp cx,[ClustPerMoby]
+ cmp ecx,[ClustPerMoby]
jna high_last_moby
- mov cx,[ClustPerMoby]
+ mov ecx,[ClustPerMoby]
high_last_moby:
- sub [KernelClust],cx
+ sub [KernelClust],ecx
xor bx,bx ; Load at offset 0
pop si ; Restore cluster pointer
call getfssec
mov [HiLoadAddr],edi ; Point to next target area
popf ; Restore EOF
jc high_load_done ; If EOF we are done
- cmp word [KernelClust],byte 0 ; Are we done?
+ cmp dword [KernelClust],byte 0 ; Are we done?
jne high_load_loop ; Apparently not
high_load_done:
pop si ; No longer needed
;
load_initrd:
test byte [initrd_flag],1
- jz nk_noinitrd
+ jz near nk_noinitrd
push es ; ES->real_mode_seg
push ds
pop es ; We need ES==DS
mov [initrd_ptr],si ; Save cluster pointer
mov [es:su_ramdisklen1],ax ; Ram disk length
mov [es:su_ramdisklen2],dx
- div word [ClustSize]
- and dx,dx ; Round up
- setnz dl
- movzx dx,dl
- add ax,dx
- mov [InitRDClust],ax ; Ramdisk clusters
+ movzx eax,ax
+ shl edx,16
+ or eax,edx
+ xor edx,edx
+ div dword [ClustSize]
+ ; Round up...
+ add edx,byte -1 ; Sets CF if EDX >= 1
+ adc eax,byte 0 ; Add 1 to EAX if CF set
+ mov [InitRDClust],eax ; Ramdisk clusters
mov edx,[HighMemSize] ; End of memory
dec edx
mov eax,[RamdiskMax] ; Highest address allowed by kernel
call cwritestr
pop si ; Restore cluster pointer
call abort_check
- mov cx,[InitRDClust]
- cmp cx,[ClustPerMoby]
+ mov ecx,[InitRDClust]
+ cmp ecx,[ClustPerMoby]
jna rd_last_moby
- mov cx,[ClustPerMoby]
+ mov ecx,[ClustPerMoby]
rd_last_moby:
- sub [InitRDClust],cx
+ sub [InitRDClust],ecx
xor bx,bx ; Load at offset 0
push word xfer_buf_seg ; Bounce buffer segment
pop es
call bcopy ; Does not change flags!!
jc rd_load_done ; EOF?
add dword [InitRDat],10000h ; Point to next 64K
- cmp word [InitRDClust],byte 0 ; Are we done?
+ cmp dword [InitRDClust],byte 0 ; Are we done?
jne rd_load_loop ; Apparently not
rd_load_done:
pop si ; Clean up the stack
mov eax,[si+tftp_filepos]
shr eax,TFTP_BLOCKSIZE_LG2
inc ax ; Which packet are we waiting for?
-
xchg ah,al ; Network byte order
cmp word [packet_buf+2],ax
je .right_packet
;
; Variables that are uninitialized in SYSLINUX but initialized here
;
-ClustSize dw TFTP_BLOCKSIZE ; Bytes/cluster
+ alignb 4, db 0
+ClustSize dd TFTP_BLOCKSIZE ; Bytes/cluster
+ClustPerMoby dd 65536/TFTP_BLOCKSIZE ; Clusters per 64K
SecPerClust dw TFTP_BLOCKSIZE/512 ; Same as bsSecPerClust, but a word
BufSafe dw trackbufsize/TFTP_BLOCKSIZE ; Clusters we can load into trackbuf
BufSafeSec dw trackbufsize/512 ; = how many sectors?
BufSafeBytes dw trackbufsize ; = how many bytes?
EndOfGetCBuf dw getcbuf+trackbufsize ; = getcbuf+BufSafeBytes
-ClustPerMoby dw 65536/TFTP_BLOCKSIZE ; Clusters per 64K
%if ( trackbufsize % TFTP_BLOCKSIZE ) != 0
%error trackbufsize must be a multiple of TFTP_BLOCKSIZE
%endif