--- trunk/mkinitrd-magellan/isolinux/loadhigh.inc 2010/08/19 08:27:19 1132 +++ trunk/mkinitrd-magellan/isolinux/loadhigh.inc 2010/08/19 09:50:43 1133 @@ -1,7 +1,7 @@ -;; $Id: loadhigh.inc,v 1.1 2007-09-01 22:44:05 niro Exp $ ;; ----------------------------------------------------------------------- -;; -;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved +;; +;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved +;; Copyright 2009 Intel Corporation; author: H. Peter Anvin ;; ;; 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 @@ -13,7 +13,7 @@ ;; ;; loadhigh.inc -;; +;; ;; Load a file into high memory ;; @@ -23,34 +23,38 @@ ; load_high: loads (the remainder of) a file into high memory. ; This routine prints dots for each 64K transferred, and ; calls abort_check periodically. -; +; ; The xfer_buf_seg is used as a bounce buffer. ; +; Assumes CS == DS. +; ; The input address (EDI) should be dword aligned, and the final ; stretch is padded with zeroes if necessary. ; ; Inputs: SI = file handle/cluster pointer ; EDI = target address in high memory -; EAX = size of remaining file in bytes -; DX = zero-padding mask (e.g. 0003h for pad to dword) +; EAX = maximum number of bytes to load +; DX = zero-padding mask (e.g. 0003h for pad to dword) +; BX = subroutine to call at the top of each loop +; (to print status and check for abort) +; MyHighMemSize = maximum load address ; ; Outputs: SI = file handle/cluster pointer -; EDI = first untouched address (not including padding) +; EBX = first untouched address (not including padding) +; EDI = first untouched address (including padding) +; CF = reached EOF ; load_high: - push es + push es ; ES - mov bx,xfer_buf_seg - mov es,bx + mov cx,xfer_buf_seg + mov es,cx + mov [PauseBird],bx .read_loop: and si,si ; If SI == 0 then we have end of file jz .eof - push si - mov si,dot_msg - call cwritestr - pop si - call abort_check + call [PauseBird] push eax ; Total bytes to transfer cmp eax,(1 << 16) ; Max 64K in one transfer @@ -67,30 +71,44 @@ xor bx,bx ; ES:0 call getfssec ; Load the data into xfer_buf_seg pop edi ; Target buffer - pop ecx ; Byte count this round - push ecx ; Byte count this round - push edi ; Target buffer + pushf ; EOF status + lea ebx,[edi+ecx] ; End of data .fix_slop: test cx,dx jz .noslop ; The last dword fractional - pad with zeroes ; Zero-padding is critical for multi-file initramfs. mov byte [es:ecx],0 - inc ecx + inc cx jmp short .fix_slop .noslop: + lea eax,[edi+ecx] + cmp eax,[MyHighMemSize] + ja .overflow + push esi ; File handle/cluster pointer mov esi,(xfer_buf_seg << 4) ; Source address call bcopy ; Copy to high memory pop esi ; File handle/cluster pointer - pop edi ; Target buffer + popf ; EOF status pop ecx ; Byte count this round pop eax ; Total bytes to transfer - add edi,ecx + jc .eof sub eax,ecx - jnz .read_loop ; More to read... - + jnz .read_loop ; More to read... (if ZF=1 then CF=0) .eof: - pop es + pop es ; ES ret +.overflow: mov si,err_nohighmem + jmp abort_load + + section .data +err_nohighmem db CR, LF + db 'Not enough memory to load specified image.', CR, LF, 0 + + section .bss + alignb 2 +PauseBird resw 1 + + section .text