diff options
author | hpa <hpa> | 2001-12-14 08:21:08 +0000 |
---|---|---|
committer | hpa <hpa> | 2001-12-14 08:21:08 +0000 |
commit | a07e4a01ba45608500e95054fa06a12852a29f96 (patch) | |
tree | c6dbfc293ae1fc92eb0be10470fb3113d9540071 /isolinux.asm | |
parent | 4a6a0d52d0854f0c8482db64e63728786f759b24 (diff) | |
download | syslinux-a07e4a01ba45608500e95054fa06a12852a29f96.tar.gz |
Correctly handle very large kernel images and very large ramdisks.
Diffstat (limited to 'isolinux.asm')
-rw-r--r-- | isolinux.asm | 87 |
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 |