summaryrefslogtreecommitdiff
path: root/isolinux.asm
diff options
context:
space:
mode:
authorhpa <hpa>2001-12-14 08:21:08 +0000
committerhpa <hpa>2001-12-14 08:21:08 +0000
commita07e4a01ba45608500e95054fa06a12852a29f96 (patch)
treec6dbfc293ae1fc92eb0be10470fb3113d9540071 /isolinux.asm
parent4a6a0d52d0854f0c8482db64e63728786f759b24 (diff)
downloadsyslinux-a07e4a01ba45608500e95054fa06a12852a29f96.tar.gz
Correctly handle very large kernel images and very large ramdisks.
Diffstat (limited to 'isolinux.asm')
-rw-r--r--isolinux.asm87
1 files changed, 43 insertions, 44 deletions
diff --git a/isolinux.asm b/isolinux.asm
index 0400ca86..903e6fe7 100644
--- a/isolinux.asm
+++ b/isolinux.asm
@@ -314,14 +314,14 @@ KernelSize resd 1 ; Size of kernel (bytes)
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
@@ -1751,27 +1751,23 @@ kernel_sane: push ax
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
@@ -1779,13 +1775,13 @@ kernel_sane: push ax
; 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
@@ -2024,14 +2020,14 @@ high_load_loop:
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
@@ -2045,7 +2041,7 @@ high_last_moby:
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
@@ -2063,7 +2059,7 @@ high_load_done:
;
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
@@ -2079,12 +2075,15 @@ load_initrd:
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
@@ -2906,12 +2905,12 @@ rd_load_loop:
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
@@ -2925,7 +2924,7 @@ rd_last_moby:
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
@@ -4588,14 +4587,14 @@ ScrollAttribute db 07h ; White on black (for text mode)
; **** 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