[syslinux:elflink] elflink: a lot of core/fs merge

syslinux-bot for Feng Tang feng.tang at intel.com
Thu Aug 12 21:04:03 PDT 2010


Commit-ID:  2e91ec5f155f04aee878ed70a04fb5b15e40da3b
Gitweb:     http://syslinux.zytor.com/commit/2e91ec5f155f04aee878ed70a04fb5b15e40da3b
Author:     Feng Tang <feng.tang at intel.com>
AuthorDate: Wed, 14 Jul 2010 15:55:25 +0800
Committer:  Feng Tang <feng.tang at intel.com>
CommitDate: Tue, 20 Jul 2010 11:10:05 +0800

elflink: a lot of core/fs merge

As:
modified:   core/Makefile
modified:   core/adv.inc
modified:   core/call16.c
modified:   core/callback.inc
modified:   core/comboot.inc
modified:   core/diskstart.inc
deleted:    core/extlinux.asm
modified:   core/include/core.h
modified:   core/isolinux.asm
modified:   core/ldlinux.asm
modified:   core/pmapi.c
modified:   core/timer.inc
modified:   elf_gen_dep.sh


---
 core/Makefile       |    7 -
 core/adv.inc        |   42 ++--
 core/call16.c       |   18 ++-
 core/callback.inc   |   13 +-
 core/comboot.inc    |   14 +-
 core/diskstart.inc  |  599 ++++++++++++++++++++++++++++++---------------------
 core/extlinux.asm   |   38 ----
 core/include/core.h |    6 +-
 core/isolinux.asm   |   32 ++--
 core/ldlinux.asm    |    4 +
 core/pmapi.c        |    8 +
 core/timer.inc      |   15 ++-
 elf_gen_dep.sh      |    2 +-
 13 files changed, 458 insertions(+), 340 deletions(-)

diff --git a/core/Makefile b/core/Makefile
index 8c675c2..54848f2 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -33,7 +33,6 @@ CODEPAGE = cp865
 
 # The targets to build in this directory...
 BTARGET  = kwdhash.gen \
-	   extlinux.bin extlinux.bss extlinux.sys \
 	   ldlinux.bss ldlinux.sys ldlinux.bin \
 	   isolinux.bin isolinux-debug.bin pxelinux.0
 
@@ -110,12 +109,6 @@ ldlinux.bss: ldlinux.bin
 ldlinux.sys: ldlinux.bin
 	dd if=$< of=$@ bs=512 skip=1
 
-extlinux.bss: extlinux.bin
-	dd if=$< of=$@ bs=512 count=1
-
-extlinux.sys: extlinux.bin
-	dd if=$< of=$@ bs=512 skip=1
-
 codepage.cp: ../codepage/$(CODEPAGE).cp
 	cp -f $< $@
 
diff --git a/core/adv.inc b/core/adv.inc
index 6725261..0b45a6c 100644
--- a/core/adv.inc
+++ b/core/adv.inc
@@ -71,18 +71,12 @@ adv_init:
 		cmp word [ADVSectors],2		; Not present?
 		jb adv_verify
 
-		;
-		; Update pointers to default ADVs...
-		;
-		mov bx,[DataSectors]
-		shl bx,2
-		mov ecx,[bsHidden]
-		mov eax,[bx+SectorPtrs-4]; First ADV sector
-		mov edx,[bx+SectorPtrs]	; Second ADV sector
-		add eax,ecx
-		add edx,ecx
-		mov [ADVSec0],eax
-		mov [ADVSec1],edx
+		mov eax,[Hidden]
+		mov edx,[Hidden+4]
+		add [ADVSec0],eax
+		adc [ADVSec0+4],edx
+		add [ADVSec1],eax
+		adc [ADVSec1+4],edx
 		mov al,[DriveNumber]
 		mov [ADVDrive],al
 		jmp adv_read
@@ -300,23 +294,26 @@ adv_cleanup:
 ;		Returns CF=1 if the ADV cannot be written.
 ;
 adv_write:
-		cmp dword [ADVSec0],0
+		push eax
+		mov eax,[ADVSec0]
+		or eax,[ADVSec0+4]
 		je .bad
-		cmp dword [ADVSec1],0
+		mov eax,[ADVSec1]
+		or eax,[ADVSec1+4]
 		je .bad
 		cmp byte [ADVDrive],-1
 		je .bad
 
-		push ax
 		call adv_cleanup
 		mov ah,3			; Write
 		call adv_read_write
-		pop ax
 
 		clc
+		pop eax
 		ret
 .bad:						; No location for ADV set
 		stc
+		pop eax
 		ret
 
 ;
@@ -358,10 +355,12 @@ adv_read_write:
 .noedd:
 
 		mov eax,[ADVSec0]
+		mov edx,[ADVSec0+4]
 		mov bx,adv0
 		call .doone
 
 		mov eax,[ADVSec1]
+		mov edx,[ADVSec1+4]
 		mov bx,adv1
 		call .doone
 
@@ -369,7 +368,6 @@ adv_read_write:
 		ret
 
 .doone:
-		xor edx,edx			; Zero-extend LBA
 		push si
 		jmp si
 
@@ -409,6 +407,9 @@ adv_read_write:
 		push eax
 		push bp
 
+		and edx,edx			; > 2 TiB not possible
+		jnz .cb_overflow
+
 		mov dl,[ADVDrive]
 		and dl,dl
 		; Floppies: can't trust INT 13h 08h, we better know
@@ -445,6 +446,7 @@ adv_read_write:
                 ; Dividing by sectors to get (track,sector): we may have
                 ; up to 2^18 tracks, so we need to use 32-bit arithmetric.
                 ;
+		xor edx,edx
                 div esi
                 xor cx,cx
                 xchg cx,dx              ; CX <- sector index (0-based)
@@ -495,9 +497,9 @@ adv_read_write:
 		jmp .cb_done
 
 		section .data16
-		alignz 4
-ADVSec0		dd 0			; Not specified
-ADVSec1		dd 0			; Not specified
+		alignz 8
+ADVSec0		dq 0			; Not specified
+ADVSec1		dq 0			; Not specified
 ADVDrive	db -1			; No ADV defined
 ADVCHSInfo	db -1			; We have CHS info for this drive
 
diff --git a/core/call16.c b/core/call16.c
index 86d7046..095f814 100644
--- a/core/call16.c
+++ b/core/call16.c
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------- *
  *
- *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *   Copyright 2009-2010 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
@@ -17,11 +17,25 @@
  */
 
 #include <stddef.h>
+#include <stdio.h>
 #include "core.h"
 
 const com32sys_t zero_regs;	/* Common all-zero register set */
 
+static inline uint32_t eflags(void)
+{
+    uint32_t v;
+
+    asm volatile("pushfl ; popl %0" : "=rm" (v));
+    return v;
+}
+
 void call16(void (*func)(void), const com32sys_t *ireg, com32sys_t *oreg)
 {
-    core_farcall((size_t)func, ireg, oreg);
+    com32sys_t xreg = *ireg;
+
+    /* Enable interrupts if and only if they are enabled in the caller */
+    xreg.eflags.l = (xreg.eflags.l & ~EFLAGS_IF) | (eflags() & EFLAGS_IF);
+
+    core_farcall((size_t)func, &xreg, oreg);
 }
diff --git a/core/callback.inc b/core/callback.inc
index a33b582..d98d800 100644
--- a/core/callback.inc
+++ b/core/callback.inc
@@ -74,7 +74,7 @@ core_syscall:
 		mov eax,.rm_return	; Return seg:offs
 		stosd			; Save in stack frame
 		mov eax,[edi-12]	; Return flags
-		and eax,0x200cd7	; Mask (potentially) unsafe flags
+		and eax,0x200ed7	; Mask (potentially) unsafe flags
 		mov [edi-12],eax	; Primary flags entry
 		stosw			; Return flags
 
@@ -84,13 +84,15 @@ core_syscall:
 		bits 16
 		section .text16
 .rm:
+		mov ax,sp
+		add ax,9*4+4*2
+		mov [CallbackSP],ax
 		pop gs
 		pop fs
 		pop es
 		pop ds
 		popad
 		popfd
-		mov [cs:CallbackSP],sp
 		retf				; Invoke routine
 
 .rm_return:
@@ -138,6 +140,7 @@ core_syscall:
 ;
 ; Cfarcall invocation.  We copy the stack frame to the real-mode stack,
 ; followed by the return CS:IP and the CS:IP of the target function.
+; The value of IF is copied from the calling routine.
 ;
 		global core_cfarcall
 core_cfarcall:
@@ -156,11 +159,14 @@ core_cfarcall:
 		mov [word CallbackSP],di
 		sub edi,ecx		; Allocate space for stack frame
 		and edi,~3		; Round
-		sub edi,4*2		; Return pointer, return value
+		sub edi,4*3		; Return pointer, return value, EFLAGS
 		mov [word RealModeSSSP],di
 		shl ebx,4
 		add edi,ebx		; Create linear address
 
+		mov eax,[esp+5*4]	; EFLAGS from entry
+		and eax,0x202		; IF only
+		stosd
 		mov eax,[esp+7*4]	; CS:IP
 		stosd			; Save to stack frame
 		mov eax,.rm_return	; Return seg:off
@@ -179,6 +185,7 @@ core_cfarcall:
 		bits 16
 		section .text16
 .rm:
+		popfd
 		retf
 .rm_return:
 		mov sp,[cs:CallbackSP]
diff --git a/core/comboot.inc b/core/comboot.inc
index 0c9956a..59db7ec 100644
--- a/core/comboot.inc
+++ b/core/comboot.inc
@@ -1,7 +1,7 @@
 ;; -----------------------------------------------------------------------
 ;;
 ;;   Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
-;;   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+;;   Copyright 2009-2010 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
@@ -593,6 +593,8 @@ comapi_derinfo:
 		mov P_DL,al
 		mov P_FS,cs
 		mov P_SI,OrigESDI
+		mov P_GS,cs
+		mov P_DI,Hidden
 %if IS_SYSLINUX || IS_EXTLINUX
 		mov P_ES,cs
 		mov P_BX,PartInfo
@@ -751,11 +753,11 @@ comapi_runkernel:
 		; It's not just possible, but quite likely, that ES:BX
 		; points into real_mode_seg or xfer_buf_seg, so we
 		; need to exercise some special care here... use
-		; vk_append for temporary storage.
+		; VKernelBuf for temporary storage.
 		push ds
 		mov ds,P_ES
 		mov si,P_BX
-		mov di,vk_append
+		mov di,VKernelBuf
 		call strcpy
 		pop ds
 
@@ -784,7 +786,7 @@ comapi_runkernel:
 		push es
 		mov dx,real_mode_seg
 		mov es,dx
-		mov si,vk_append
+		mov si,VKernelBuf
 		mov di,cmd_line_here
 		call strcpy
 		mov word [es:di-1],' '	; Simulate APPEND: space plus null
@@ -837,10 +839,10 @@ comapi_userfont:
 ;
 %if IS_SYSLINUX || IS_ISOLINUX || IS_EXTLINUX
 comapi_readdisk:
-		mov esi,P_ESI		; Enforce ESI == EDI == 0, these
-		or esi,P_EDI		; are reserved for future expansion
+		cmp P_EDI,0		; Reserved for future expansion
 		jnz .err
 		mov eax,P_EDX
+		mov edx,P_ESI
 		mov es,P_ES
 		mov bx,P_BX
 		mov bp,P_CX		; WE CANNOT use P_* after touching bp!
diff --git a/core/diskstart.inc b/core/diskstart.inc
index 4084ff7..c61a615 100644
--- a/core/diskstart.inc
+++ b/core/diskstart.inc
@@ -17,24 +17,25 @@
 ; Common early-bootstrap code for harddisk-based Syslinux derivatives.
 ;
 
-		; Expanded superblock
-		section .earlybss
-		alignb 8
-SuperInfo	resq 16			; The first 16 bytes expanded 8 times
-DriveNumber	resb 1
-
 		section .init
 ;
 ; Some of the things that have to be saved very early are saved
 ; "close" to the initial stack pointer offset, in order to
 ; reduce the code size...
 ;
-StackBuf	equ STACK_TOP-44-32	; Start the stack here (grow down - 4K)
-PartInfo	equ StackBuf		; Saved partition table entry
-FloppyTable	equ PartInfo+16		; Floppy info table (must follow PartInfo)
-OrigFDCTabPtr	equ StackBuf-8		; The 2nd high dword on the stack
-OrigESDI	equ StackBuf-4		; The high dword on the stack
-StackHome	equ OrigFDCTabPtr	; The start of the canonical stack
+
+StackBuf	equ STACK_TOP-44-92	; Start the stack here (grow down - 4K)
+PartInfo	equ StackBuf
+.mbr		equ PartInfo
+.gptlen		equ PartInfo+16
+.gpt		equ PartInfo+20
+FloppyTable	equ PartInfo+76
+; Total size of PartInfo + FloppyTable == 76+16 = 92 bytes
+Hidden		equ StackBuf-20		; Partition offset
+OrigFDCTabPtr	equ StackBuf-12		; The 2nd high dword on the stack
+OrigESDI	equ StackBuf-8		; The high dword on the stack
+DriveNumber	equ StackBuf-4		; Drive number
+StackHome	equ Hidden		; The start of the canonical stack
 
 ;
 ; Primary entry point.  Tempting as though it may be, we can't put the
@@ -98,6 +99,7 @@ superblock_max	equ $-superblock
 
 		global SecPerClust
 SecPerClust	equ bxSecPerClust
+
 ;
 ; Note we don't check the constraints above now; we did that at install
 ; time (we hope!)
@@ -108,20 +110,24 @@ start:
 ;
 ; Set up the stack
 ;
-		xor ax,ax
-		mov ss,ax
-		mov sp,StackBuf		; Just below BSS
+		xor cx,cx
+		mov ss,cx
+		mov sp,StackBuf-2	; Just below BSS (-2 for alignment)
+		push dx			; Save drive number (in DL)
 		push es			; Save initial ES:DI -> $PnP pointer
 		push di
-		mov es,ax
+		mov es,cx
+
 ;
-; DS:SI may contain a partition table entry.  Preserve it for us.
+; DS:SI may contain a partition table entry and possibly a GPT entry.
+; Preserve it for us.  This saves 56 bytes of the GPT entry, which is
+; currently the maximum we care about.  Total is 76 bytes.
 ;
-		mov cx,8		; Save partition info
+		mov cl,(16+4+56)/2	; Save partition info
 		mov di,PartInfo
-		rep movsw
+		rep movsw		; This puts CX back to zero
 
-		mov ds,ax		; Now we can initialize DS...
+		mov ds,cx		; Now we can initialize DS...
 
 ;
 ; Now sautee the BIOS floppy info block to that it will support decent-
@@ -138,12 +144,12 @@ start:
 
 		; Save the old fdctab even if hard disk so the stack layout
 		; is the same.  The instructions above do not change the flags
-		mov [DriveNumber],dl	; Save drive number in DL
 		and dl,dl		; If floppy disk (00-7F), assume no
 					; partition table
 		js harddisk
 
 floppy:
+		xor ax,ax
 		mov cl,6		; 12 bytes (CX == 0)
 		; es:di -> FloppyTable already
 		; This should be safe to do now, interrupts are off...
@@ -151,26 +157,49 @@ floppy:
 		mov [bx+2],ax		; Segment 0
 		fs rep movsw		; Faster to move words
 		mov cl,[bsSecPerTrack]  ; Patch the sector count
-		mov [di-8],cl
-		; AX == 0 here
-		int 13h			; Some BIOSes need this
+		mov [di-76+8],cl
+
+		push ax			; Partition offset == 0
+		push ax
+		push ax
+		push ax
 
+		int 13h			; Some BIOSes need this
 		jmp short not_harddisk
 ;
 ; The drive number and possibly partition information was passed to us
 ; by the BIOS or previous boot loader (MBR).  Current "best practice" is to
 ; trust that rather than what the superblock contains.
 ;
-; Would it be better to zero out bsHidden if we don't have a partition table?
-;
 ; Note: di points to beyond the end of PartInfo
 ;
 harddisk:
-		test byte [di-16],7Fh	; Sanity check: "active flag" should
-		jnz no_partition	; be 00 or 80
-		mov eax,[di-8]		; Partition offset (dword)
-		mov [bsHidden],eax
-no_partition:
+		test byte [di-76],7Fh	; Sanity check: "active flag" should
+		jnz .no_partition	; be 00 or 80
+		cmp [di-76+4],cl	; Sanity check: partition type != 0
+		je .no_partition
+		cmp eax,'!GPT'		; !GPT signature?
+		jne .mbr
+		cmp byte [di-76+4],0EDh	; Synthetic GPT partition entry?
+		jne .mbr
+.gpt:					; GPT-style partition info
+		push dword [di-76+20+36]
+		push dword [di-76+20+32]
+		jmp .gotoffs
+.mbr:					; MBR-style partition info
+		push cx			; Upper half partition offset == 0
+		push cx
+		push dword [di-76+8]	; Partition offset (dword)
+		jmp .gotoffs
+.no_partition:
+;
+; No partition table given... assume that the Hidden field in the boot sector
+; tells the truth (in particular, is zero if this is an unpartitioned disk.)
+;
+		push cx
+		push cx
+		push dword [bsHidden]
+.gotoffs:
 ;
 ; Get disk drive parameters (don't trust the superblock.)  Don't do this for
 ; floppy drives -- INT 13:08 on floppy drives will (may?) return info about
@@ -211,7 +240,7 @@ eddcheck:
 		;
 		; We have EDD support...
 		;
-		mov byte [getlinsec.jmp+1],(getlinsec_ebios-(getlinsec.jmp+2))
+		mov byte [getonesec.jmp+1],(getonesec_ebios-(getonesec.jmp+2))
 .noedd:
 
 ;
@@ -219,7 +248,10 @@ eddcheck:
 ; with parsing the superblock and root directory; it doesn't fit
 ; together with EBIOS support, unfortunately.
 ;
-		mov eax,[FirstSector]	; Sector start
+		mov eax,strict dword 0xdeadbeef
+Sect1Ptr0	equ $-4
+		mov edx,strict dword 0xfeedface
+Sect1Ptr1	equ $-4
 		mov bx,ldlinux_sys	; Where to load it
 		call getonesec
 
@@ -228,79 +260,46 @@ eddcheck:
 		jne kaboom
 
 		; Go for it...
-		jmp ldlinux_ent
+		jmp 0:ldlinux_ent
 
-;
-; getonesec: get one disk sector
-;
-getonesec:
-		mov bp,1		; One sector
-		; Fall through
 
 ;
-; getlinsec: load a sequence of BP floppy sector given by the linear sector
-;	     number in EAX into the buffer at ES:BX.  We try to optimize
-;	     by loading up to a whole track at a time, but the user
-;	     is responsible for not crossing a 64K boundary.
-;	     (Yes, BP is weird for a count, but it was available...)
+; getonesec: load a single disk linear sector EDX:EAX into the buffer
+;	     at ES:BX.
 ;
-;	     On return, BX points to the first byte after the transferred
-;	     block.
-;
-;            This routine assumes CS == DS, and trashes most registers.
+;            This routine assumes CS == DS == SS, and trashes most registers.
 ;
 ; Stylistic note: use "xchg" instead of "mov" when the source is a register
 ; that is dead from that point; this saves space.  However, please keep
 ; the order to dst,src to keep things sane.
 ;
-		global getlinsec
-getlinsec:
-		add eax,[bsHidden]		; Add partition offset
-		xor edx,edx			; Zero-extend LBA (eventually allow 64 bits)
-
-.jmp:		jmp strict short getlinsec_cbios
+getonesec:
+		add eax,[Hidden]		; Add partition offset
+		adc edx,[Hidden+4]
+		mov cx,retry_count
+.jmp:		jmp strict short getonesec_cbios
 
 ;
-; getlinsec_ebios:
+; getonesec_ebios:
 ;
-; getlinsec implementation for EBIOS (EDD)
+; getonesec implementation for EBIOS (EDD)
 ;
-getlinsec_ebios:
-.loop:
-                push bp                         ; Sectors left
-.retry2:
-		call maxtrans			; Enforce maximum transfer size
-		movzx edi,bp			; Sectors we are about to read
-		mov cx,retry_count
+getonesec_ebios:
 .retry:
-
 		; Form DAPA on stack
 		push edx
 		push eax
 		push es
 		push bx
-		push di
+		push word 1
 		push word 16
 		mov si,sp
 		pushad
-                mov dl,[DriveNumber]
-		push ds
-		push ss
-		pop ds				; DS <- SS
                 mov ah,42h                      ; Extended Read
-		int 13h
-		pop ds
+		call xint13
 		popad
 		lea sp,[si+16]			; Remove DAPA
 		jc .error
-		pop bp
-		add eax,edi			; Advance sector pointer
-		sub bp,di			; Sectors left
-                shl di,SECTOR_SHIFT		; 512-byte sectors
-                add bx,di			; Advance buffer pointer
-                and bp,bp
-                jnz .loop
-
                 ret
 
 .error:
@@ -311,32 +310,21 @@ getlinsec_ebios:
 
 		pushad				; Try resetting the device
 		xor ax,ax
-		mov dl,[DriveNumber]
-		int 13h
+		call xint13
 		popad
 		loop .retry			; CX-- and jump if not zero
 
-		;shr word [MaxTransfer],1	; Reduce the transfer size
-		;jnz .retry2
-
 		; Total failure.  Try falling back to CBIOS.
-		mov byte [getlinsec.jmp+1],(getlinsec_cbios-(getlinsec.jmp+2))
-		;mov byte [MaxTransfer],63	; Max possibe CBIOS transfer
-
-		pop bp
-		; ... fall through ...
+		mov byte [getonesec.jmp+1],(getonesec_cbios-(getonesec.jmp+2))
 
 ;
-; getlinsec_cbios:
+; getonesec_cbios:
 ;
 ; getlinsec implementation for legacy CBIOS
 ;
-getlinsec_cbios:
-.loop:
-		push edx
-		push eax
-		push bp
-		push bx
+getonesec_cbios:
+.retry:
+		pushad
 
 		movzx esi,word [bsSecPerTrack]
 		movzx edi,word [bsHeads]
@@ -351,25 +339,13 @@ getlinsec_cbios:
 		; eax = track #
 		div edi			; Convert track to head/cyl
 
-		; We should test this, but it doesn't fit...
-		; cmp eax,1023
-		; ja .error
+		cmp eax,1023		; Outside the CHS range?
+		ja kaboom
 
 		;
 		; Now we have AX = cyl, DX = head, CX = sector (0-based),
-		; BP = sectors to transfer, SI = bsSecPerTrack,
-		; ES:BX = data target
+		; SI = bsSecPerTrack, ES:BX = data target
 		;
-
-		call maxtrans			; Enforce maximum transfer size
-
-		; Must not cross track boundaries, so BP <= SI-CX
-		sub si,cx
-		cmp bp,si
-		jna .bp_ok
-		mov bp,si
-.bp_ok:
-
 		shl ah,6		; Because IBM was STOOPID
 					; and thought 8 bits were enough
 					; then thought 10 bits were enough...
@@ -377,35 +353,14 @@ getlinsec_cbios:
 		or cl,ah
 		mov ch,al
 		mov dh,dl
-		mov dl,[DriveNumber]
-		xchg ax,bp		; Sector to transfer count
-		mov ah,02h		; Read sectors
-		mov bp,retry_count
-.retry:
-		pushad
-		int 13h
+		mov ax,0201h		; Read one sector
+		call xint13
 		popad
 		jc .error
-.resume:
-		movzx ecx,al		; ECX <- sectors transferred
-		shl ax,SECTOR_SHIFT	; Convert sectors in AL to bytes in AX
-		pop bx
-		add bx,ax
-		pop bp
-		pop eax
-		pop edx
-		add eax,ecx
-		sub bp,cx
-		jnz .loop
 		ret
 
 .error:
-		dec bp
-		jnz .retry
-
-		xchg ax,bp		; Sectors transferred <- 0
-		shr word [MaxTransfer],1
-		jnz .resume
+		loop .retry
 		; Fall through to disk_error
 
 ;
@@ -421,47 +376,51 @@ kaboom:
 		pop dword [fdctab]	; Restore FDC table
 .patch:					; When we have full code, intercept here
 		mov si,bailmsg
+		call writestr_early
 
-		; Write error message, this assumes screen page 0
+		xor ax,ax
+.again:		int 16h			; Wait for keypress
+					; NB: replaced by int 18h if
+					; chosen at install time..
+		int 19h			; And try once more to boot...
+.norge:		hlt			; If int 19h returned; this is the end
+		jmp short .norge
+
+;
+;
+; writestr_early: write a null-terminated string to the console
+;	    This assumes we're on page 0.  This is only used for early
+;           messages, so it should be OK.
+;
+writestr_early:
+		pushad
 .loop:		lodsb
 		and al,al
-                jz .done
+                jz .return
 		mov ah,0Eh		; Write to screen as TTY
 		mov bx,0007h		; Attribute
 		int 10h
 		jmp short .loop
-.done:
-		cbw			; AH <- 0
-.again:		int 16h			; Wait for keypress
-					; NB: replaced by int 18h if
-					; chosen at install time..
-		int 19h			; And try once more to boot...
-.norge:		jmp short .norge	; If int 19h returned; this is the end
+.return:	popad
+		ret
 
 ;
-; Truncate BP to MaxTransfer
+; INT 13h wrapper function
 ;
-maxtrans:
-		cmp bp,[MaxTransfer]
-		jna .ok
-		mov bp,[MaxTransfer]
-.ok:		ret
+xint13:
+                mov dl,[DriveNumber]
+		int 13h
+		ret
 
 ;
 ; Error message on failure
 ;
 bailmsg:	db 'Boot error', 0Dh, 0Ah, 0
 
-		; This fails if the boot sector overflows
-		zb 1F8h-($-$$)
+		; This fails if the boot sector overflowsg
+		zb 1FEh-($-$$)
 
-FirstSector	dd 0xDEADBEEF			; Location of sector 1
-MaxTransfer	dw 0x007F			; Max transfer size
-
-; This field will be filled in 0xAA55 by the installer, but we abuse it
-; to house a pointer to the INT 16h instruction at
-; kaboom.again, which gets patched to INT 18h in RAID mode.
-bootsignature	dw kaboom.again-bootsec
+bootsignature	dw 0xAA55
 
 ;
 ; ===========================================================================
@@ -493,24 +452,41 @@ ADVSectors	dw 0		; Additional sectors for ADVs
 LDLDwords	dd 0		; Total dwords starting at ldlinux_sys,
 CheckSum	dd 0		; Checksum starting at ldlinux_sys
 				; value = LDLINUX_MAGIC - [sum of dwords]
+MaxTransfer	dw 127		; Max sectors to transfer
+EPAPtr		dw EPA - LDLINUX_SYS	; Pointer to the extended patch area
+
+;
+; Extended patch area -- this is in .data16 so it doesn't occupy space in
+; the first sector.  Use this structure for anything that isn't used by
+; the first sector itself.
+;
+		section .data16
+		alignz 2
+EPA:
+ADVSecPtr	dw ADVSec0 - LDLINUX_SYS
 CurrentDirPtr	dw CurrentDirName-LDLINUX_SYS	; Current directory name string
 CurrentDirLen	dw CURRENTDIR_MAX
 SubvolPtr	dw SubvolName-LDLINUX_SYS
 SubvolLen	dw SUBVOL_MAX
 SecPtrOffset	dw SectorPtrs-LDLINUX_SYS
-SecPtrCnt	dw (SectorPtrsEnd - SectorPtrs) >> 2
+SecPtrCnt	dw (SectorPtrsEnd - SectorPtrs)/10
+
+;
+; Boot sector patch pointers
+;
+Sect1Ptr0Ptr	dw Sect1Ptr0 - bootsec		; Pointers to Sector 1 location
+Sect1Ptr1Ptr	dw Sect1Ptr1 - bootsec
+RAIDPatchPtr	dw kaboom.again - bootsec	; Patch to INT 18h in RAID mode
 
 ;
-; Installer pokes the base directory here.  This is in .data16 so it
-; isn't actually located in the first sector.
+; Base directory name and subvolume, if applicable.
 ;
 %define HAVE_CURRENTDIRNAME
-		section .data16
 		global CurrentDirName, SubvolName
 CurrentDirName	times CURRENTDIR_MAX db 0
 SubvolName	times SUBVOL_MAX db 0
-		section .init
 
+		section .init
 ldlinux_ent:
 ;
 ; Note that some BIOSes are buggy and run the boot sector at 07C0:0000
@@ -519,8 +495,6 @@ ldlinux_ent:
 ; value in CS, but we don't want to deal with that anymore from now
 ; on.
 ;
-		jmp 0:.next
-.next:
 		sti		; In case of broken INT 13h BIOSes
 
 ;
@@ -530,13 +504,26 @@ ldlinux_ent:
 		call writestr_early
 
 ;
+; Checksum data thus far
+;
+		mov si,ldlinux_sys
+		mov cx,SECTOR_SIZE >> 2
+		mov edx,-LDLINUX_MAGIC
+.checksum:
+		lodsd
+		add edx,eax
+		loop .checksum
+		mov [CheckSum],edx		; Save intermediate result
+
+;
 ; Tell the user if we're using EBIOS or CBIOS
 ;
 print_bios:
 		mov si,cbios_name
-		cmp byte [getlinsec.jmp+1],(getlinsec_ebios-(getlinsec.jmp+2))
+		cmp byte [getonesec.jmp+1],(getonesec_ebios-(getonesec.jmp+2))
 		jne .cbios
 		mov si,ebios_name
+		mov byte [getlinsec.jmp+1],(getlinsec_ebios-(getlinsec.jmp+2))
 .cbios:
 		mov [BIOSName],si
 		call writestr_early
@@ -547,8 +534,7 @@ BIOSName	resw 1
 
 		section .init
 ;
-; Now we read the rest of LDLINUX.SYS.	Don't bother loading the first
-; sector again, though.
+; Now we read the rest of LDLINUX.SYS.
 ;
 load_rest:
 		lea esi,[SectorPtrs]
@@ -558,37 +544,19 @@ load_rest:
 
 .get_chunk:
 		jcxz .done
-		xor ebp,ebp
-		mov di,bx			; Low 64K of target address
-		lodsd				; First sector of this chunk
-
-		mov edx,eax
-
-.make_chunk:
-		inc bp
-		dec cx
-		jz .chunk_ready
-		cmp ebx,esi			; Pointer we don't have yet?
-		jae .chunk_ready
-		inc edx				; Next linear sector
-		cmp [si],edx			; Does it match
-		jnz .chunk_ready		; If not, this is it
-		add si,4			; If so, add sector to chunk
-		add di,SECTOR_SIZE		; Check for 64K segment wrap
-		jnz .make_chunk
-
-.chunk_ready:
+		mov eax,[si]
+		mov edx,[si+4]
+		movzx ebp,word [si+8]
+		sub cx,bp
 		push ebx
-		push es
 		shr ebx,4			; Convert to a segment
 		mov es,bx
 		xor bx,bx
-		xor edx,edx			; Zero-extend LBA
-		call getlinsecsr
-		pop es
+		call getlinsec
 		pop ebx
 		shl ebp,SECTOR_SHIFT
 		add ebx,ebp
+		add si,10
 		jmp .get_chunk
 
 .done:
@@ -599,10 +567,10 @@ load_rest:
 ; by the time we get to the end it should all cancel out.
 ;
 verify_checksum:
-		mov si,ldlinux_sys
+		mov si,ldlinux_sys + SECTOR_SIZE
 		mov ecx,[LDLDwords]
-		mov eax,-LDLINUX_MAGIC
-		push ds
+		sub ecx,SECTOR_SIZE >> 2
+		mov eax,[CheckSum]
 .checksum:
 		add eax,[si]
 		add si,4
@@ -614,12 +582,7 @@ verify_checksum:
 .nowrap:
 		dec ecx
 		jnz .checksum
-		pop ds
 
-		push eax
-		mov si,cbios_name
-		call writestr_early
-		pop eax
 		and eax,eax			; Should be zero
 		jz all_read			; We're cool, go for it!
 
@@ -635,37 +598,181 @@ verify_checksum:
 ; Subroutines that have to be in the first sector
 ; -----------------------------------------------------------------------------
 
+
+
 ;
+; getlinsec: load a sequence of BP floppy sector given by the linear sector
+;	     number in EAX into the buffer at ES:BX.  We try to optimize
+;	     by loading up to a whole track at a time, but the user
+;	     is responsible for not crossing a 64K boundary.
+;	     (Yes, BP is weird for a count, but it was available...)
 ;
-; writestr_early: write a null-terminated string to the console
-;	    This assumes we're on page 0.  This is only used for early
-;           messages, so it should be OK.
+;	     On return, BX points to the first byte after the transferred
+;	     block.
 ;
-writestr_early:
+;            This routine assumes CS == DS.
+;
+		global getlinsec
+getlinsec:
 		pushad
-.loop:		lodsb
-		and al,al
-                jz .return
-		mov ah,0Eh		; Write to screen as TTY
-		mov bx,0007h		; Attribute
-		int 10h
-		jmp short .loop
-.return:	popad
-		ret
+		add eax,[Hidden]		; Add partition offset
+		adc edx,[Hidden+4]
+.jmp:		jmp strict short getlinsec_cbios
 
+;
+; getlinsec_ebios:
+;
+; getlinsec implementation for EBIOS (EDD)
+;
+getlinsec_ebios:
+.loop:
+                push bp                         ; Sectors left
+.retry2:
+		call maxtrans			; Enforce maximum transfer size
+		movzx edi,bp			; Sectors we are about to read
+		mov cx,retry_count
+.retry:
+
+		; Form DAPA on stack
+		push edx
+		push eax
+		push es
+		push bx
+		push di
+		push word 16
+		mov si,sp
+		pushad
+                mov ah,42h                      ; Extended Read
+		push ds
+		push ss
+		pop ds
+		call xint13
+		pop ds
+		popad
+		lea sp,[si+16]			; Remove DAPA
+		jc .error
+		pop bp
+		add eax,edi			; Advance sector pointer
+		adc edx,0
+		sub bp,di			; Sectors left
+                shl di,SECTOR_SHIFT		; 512-byte sectors
+                add bx,di			; Advance buffer pointer
+                and bp,bp
+                jnz .loop
+
+		popad
+                ret
+
+.error:
+		; Some systems seem to get "stuck" in an error state when
+		; using EBIOS.  Doesn't happen when using CBIOS, which is
+		; good, since some other systems get timeout failures
+		; waiting for the floppy disk to spin up.
+
+		pushad				; Try resetting the device
+		xor ax,ax
+		mov dl,[DriveNumber]
+		int 13h
+		popad
+		loop .retry			; CX-- and jump if not zero
+
+		;shr word [MaxTransfer],1	; Reduce the transfer size
+		;jnz .retry2
+
+		; Total failure.  Try falling back to CBIOS.
+		mov byte [getlinsec.jmp+1],(getlinsec_cbios-(getlinsec.jmp+2))
+		;mov byte [MaxTransfer],63	; Max possibe CBIOS transfer
+
+		pop bp
+		; ... fall through ...
 
 ;
-; getlinsecsr: save registers, call getlinsec, restore registers
-;	       Save/restore the flags, too, especially IF.
+; getlinsec_cbios:
+;
+; getlinsec implementation for legacy CBIOS
 ;
-getlinsecsr:	
-		pushfd
+getlinsec_cbios:
+.loop:
+		push edx
+		push eax
+		push bp
+		push bx
+
+		movzx esi,word [bsSecPerTrack]
+		movzx edi,word [bsHeads]
+		;
+		; Dividing by sectors to get (track,sector): we may have
+		; up to 2^18 tracks, so we need to use 32-bit arithmetric.
+		;
+		div esi
+		xor cx,cx
+		xchg cx,dx		; CX <- sector index (0-based)
+					; EDX <- 0
+		; eax = track #
+		div edi			; Convert track to head/cyl
+
+		cmp eax,1023		; Outside the CHS range?
+		ja kaboom
+
+		;
+		; Now we have AX = cyl, DX = head, CX = sector (0-based),
+		; BP = sectors to transfer, SI = bsSecPerTrack,
+		; ES:BX = data target
+		;
+
+		call maxtrans			; Enforce maximum transfer size
+
+		; Must not cross track boundaries, so BP <= SI-CX
+		sub si,cx
+		cmp bp,si
+		jna .bp_ok
+		mov bp,si
+.bp_ok:
+
+		shl ah,6		; Because IBM was STOOPID
+					; and thought 8 bits were enough
+					; then thought 10 bits were enough...
+		inc cx			; Sector numbers are 1-based, sigh
+		or cl,ah
+		mov ch,al
+		mov dh,dl
+		xchg ax,bp		; Sector to transfer count
+		mov ah,02h		; Read sectors
+		mov bp,retry_count
+.retry:
 		pushad
-		call getlinsec
+		call xint13
+		popad
+		jc .error
+.resume:
+		movzx ecx,al		; ECX <- sectors transferred
+		shl ax,SECTOR_SHIFT	; Convert sectors in AL to bytes in AX
+		pop bx
+		add bx,ax
+		pop bp
+		pop eax
+		pop edx
+		add eax,ecx
+		sub bp,cx
+		jnz .loop
 		popad
-		popfd
 		ret
 
+.error:
+		dec bp
+		jnz .retry
+
+		xchg ax,bp		; Sectors transferred <- 0
+		shr word [MaxTransfer],1
+		jnz .resume
+		jmp kaboom
+
+maxtrans:
+		cmp bp,[MaxTransfer]
+		jna .ok
+		mov bp,[MaxTransfer]
+.ok:		ret
+
 ;
 ; Checksum error message
 ;
@@ -691,16 +798,22 @@ rl_checkpt	equ $				; Must be <= 8000h
 
 rl_checkpt_off	equ ($-$$)
 %ifndef DEPEND
-%if rl_checkpt_off > 3FCh			; Need one pointer in here
-%error "Sector 1 overflow"
-%endif
+ %if rl_checkpt_off > 3F6h			; Need one extent
+  %assign rl_checkpt_overflow rl_checkpt_off - 3F6h
+  %error Sector 1 overflow by rl_checkpt_overflow bytes
+ %endif
 %endif
 
-; Sector pointers
-		alignz 4
+;
+; Extent pointers... each extent contains an 8-byte LBA and an 2-byte
+; sector count.  In most cases, we will only ever need a handful of
+; extents, but we have to assume a maximally fragmented system where each
+; extent contains only one sector.
+;
+		alignz 2
 MaxInitDataSize	equ 96 << 10
 MaxLMA		equ TEXT_START+SECTOR_SIZE+MaxInitDataSize
-SectorPtrs	times MaxInitDataSize >> SECTOR_SHIFT dd 0
+SectorPtrs	zb 10*(MaxInitDataSize >> SECTOR_SHIFT)
 SectorPtrsEnd	equ $
 
 ; ----------------------------------------------------------------------------
@@ -708,18 +821,19 @@ SectorPtrsEnd	equ $
 ; ----------------------------------------------------------------------------
 
 		section .text16
-test_string	db 'test', 0			; temp add by feng 
-
 all_read:
+		; We enter here with both DS and ES scrambled...
+		xor ax,ax
+		mov ds,ax
+		mov es,ax
 ;
 ; Let the user (and programmer!) know we got this far.  This used to be
 ; in Sector 1, but makes a lot more sense here.
 ;
-		;mov si,copyright_str
-		;call writestr_early
-
-		mov si,test_string
+		mov si,copyright_str
 		call writestr_early
+
+
 ;
 ; Insane hack to expand the DOS superblock to dwords
 ;
@@ -746,21 +860,16 @@ expand_super:
 		mov eax,ROOT_FS_OPS
 		movzx dx,byte [DriveNumber]
 		; DH = 0: we are boot from disk not CDROM
-		mov ecx,[bsHidden]
-		; Reserved for upper 32 bits of partition offset...
-		; mov ebx,[bsHidden+4]
-		xor ebx,ebx
+		mov ecx,[Hidden]
+		mov ebx,[Hidden+4]
 		mov si,[bsHeads]
 		mov di,[bsSecPerTrack]
 		movzx ebp,word [MaxTransfer]
-
-		;mov si,ebios_name
-		;call writestr_early
-
 		pm_call fs_init
-
-		;mov si,ebios_name
-		;call writestr_early
-
 		pm_call load_env32
 		popad
+
+		section .bss16
+SuperInfo	resq 16			; The first 16 bytes expanded 8 times
+
+		section .text16
diff --git a/core/extlinux.asm b/core/extlinux.asm
deleted file mode 100644
index 9538576..0000000
--- a/core/extlinux.asm
+++ /dev/null
@@ -1,38 +0,0 @@
-; -*- fundamental -*- (asm-mode sucks)
-; ****************************************************************************
-;
-;  extlinux.asm
-;
-;  A program to boot Linux kernels off an ext2/ext3 filesystem.
-;
-;   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
-;  the Free Software Foundation, Inc., 53 Temple Place Ste 330,
-;  Boston MA 02111-1307, USA; either version 2 of the License, or
-;  (at your option) any later version; incorporated herein by reference.
-;
-; ****************************************************************************
-
-%define IS_EXTLINUX 1
-%include "head.inc"
-
-;
-; Some semi-configurable constants... change on your own risk.
-;
-my_id		equ extlinux_id
-
-		section .rodata
-		alignz 4
-ROOT_FS_OPS:
-		extern vfat_fs_ops
-		dd vfat_fs_ops
-		extern ext2_fs_ops
-		dd ext2_fs_ops
-		extern btrfs_fs_ops
-		dd btrfs_fs_ops
-		dd 0
-
-%include "diskfs.inc"
diff --git a/core/include/core.h b/core/include/core.h
index 3de2b4d..799c337 100644
--- a/core/include/core.h
+++ b/core/include/core.h
@@ -64,10 +64,14 @@ __noreturn _kaboom(void);
 /*
  * Basic timer function...
  */
-extern volatile uint32_t __jiffies;
+extern volatile uint32_t __jiffies, __ms_timer;
 static inline uint32_t jiffies(void)
 {
     return __jiffies;
 }
+static inline uint32_t ms_timer(void)
+{
+    return __ms_timer;
+}
 
 #endif /* CORE_H */
diff --git a/core/isolinux.asm b/core/isolinux.asm
index 8060767..1ef68d8 100644
--- a/core/isolinux.asm
+++ b/core/isolinux.asm
@@ -101,7 +101,7 @@ ISOFlags	resb 1			; Flags for ISO directory search
 RetryCount      resb 1			; Used for disk access retries
 
 		alignb 8
-bsHidden	resq 1			; Used in hybrid mode
+Hidden		resq 1			; Used in hybrid mode
 bsSecPerTrack	resw 1			; Used in hybrid mode
 bsHeads		resw 1			; Used in hybrid mode
 
@@ -242,9 +242,6 @@ _start_hybrid:
 		pop eax
 		pop ebx
 .nooffset:
-		mov [cs:bsHidden],eax
-		mov [cs:bsHidden+4],ebx
-
 		mov si,bios_cbios
 		jcxz _start_common
 		mov si,bios_ebios
@@ -253,21 +250,26 @@ _start_hybrid:
 
 _start1:
 		mov si,bios_cdrom
+		xor eax,eax
+		xor ebx,ebx
 _start_common:
 		mov [cs:InitStack],sp	; Save initial stack pointer
 		mov [cs:InitStack+2],ss
-		xor ax,ax
-		mov ss,ax
+		xor cx,cx
+		mov ss,cx
 		mov sp,StackBuf		; Set up stack
 		push es			; Save initial ES:DI -> $PnP pointer
 		push di
-		mov ds,ax
-		mov es,ax
-		mov fs,ax
-		mov gs,ax
+		mov ds,cx
+		mov es,cx
+		mov fs,cx
+		mov gs,cx
 		sti
 		cld
 
+		mov [Hidden],eax
+		mov [Hidden+4],ebx
+
 		mov [BIOSType],si
 		mov eax,[si]
 		mov [GetlinsecPtr],eax
@@ -779,8 +781,8 @@ getlinsec_ebios:
 		xor edx,edx
 		shld edx,eax,2
 		shl eax,2			; Convert to HDD sectors
-		add eax,[bsHidden]
-		adc edx,[bsHidden+4]
+		add eax,[Hidden]
+		adc edx,[Hidden+4]
 		shl bp,2
 
 .loop:
@@ -852,7 +854,7 @@ getlinsec_ebios:
 getlinsec_cbios:
 		xor edx,edx
 		shl eax,2			; Convert to HDD sectors
-		add eax,[bsHidden]
+		add eax,[Hidden]
 		shl bp,2
 
 .loop:
@@ -1165,8 +1167,8 @@ init_fs:
 .hybrid:
 		movzx ebp,word [MaxTransfer]
 .common:
-	        mov ecx,[bsHidden]
-	        mov ebx,[bsHidden+4]
+	        mov ecx,[Hidden]
+	        mov ebx,[Hidden+4]
                 mov si,[bsHeads]
 		mov di,[bsSecPerTrack]
 		pm_call fs_init
diff --git a/core/ldlinux.asm b/core/ldlinux.asm
index 23540ea..f62f55b 100644
--- a/core/ldlinux.asm
+++ b/core/ldlinux.asm
@@ -35,6 +35,10 @@ my_id		equ syslinux_id
 ROOT_FS_OPS:
 		extern vfat_fs_ops
 		dd vfat_fs_ops
+		extern ext2_fs_ops
+		dd ext2_fs_ops
+		extern btrfs_fs_ops
+		dd btrfs_fs_ops
 		dd 0
 
 %include "diskfs.inc"
diff --git a/core/pmapi.c b/core/pmapi.c
index 3313cea..4b1ccbb 100644
--- a/core/pmapi.c
+++ b/core/pmapi.c
@@ -19,6 +19,8 @@
 
 const struct com32_pmapi pm_api_vector =
 {
+    .__pmapi_size = sizeof(struct com32_pmapi),
+
     .lmalloc	= pmapi_lmalloc, /* Allocate low memory */
     .lfree	= free,		 /* Free low memory */
 
@@ -32,4 +34,10 @@ const struct com32_pmapi pm_api_vector =
 
     .idle	= __idle,
     .reset_idle	= reset_idle,
+
+    .chdir	= chdir,
+    .getcwd	= getcwd,
+
+    .jiffies	= &__jiffies,
+    .ms_timer	= &__ms_timer,
 };
diff --git a/core/timer.inc b/core/timer.inc
index 728812b..b01ff91 100644
--- a/core/timer.inc
+++ b/core/timer.inc
@@ -19,6 +19,9 @@
 ;; about the BIOS_timer variable wrapping around at "midnight" and other
 ;; weird things.
 ;;
+;; This also maintains a timer variable calibrated in milliseconds
+;; (wraparound time = 49.7 days!)
+;;
 
 		section .text16
 
@@ -35,12 +38,20 @@ timer_cleanup:
 		mov [BIOS_timer_hook],eax
 		ret
 
+;
+; The specified frequency is 14.31818 MHz/12/65536; this turns out
+; to be a period of 54.92542 ms, or 0x36.ece8(187c) hexadecimal.
+;
 timer_irq:
 		inc dword [cs:__jiffies]
+		add word  [cs:__ms_timer_adj],0xece8
+		adc dword [cs:__ms_timer],0x36
 		jmp 0:0
 BIOS_timer_next	equ $-4
 
 		section .data16
 		alignz 4
-		global __jiffies
-__jiffies	dd 0			; The actual timer variable
+		global __jiffies, __ms_timer
+__jiffies	dd 0			; Clock tick timer
+__ms_timer	dd 0			; Millisecond timer
+__ms_timer_adj	dw 0			; Millisecond timer correction factor
diff --git a/elf_gen_dep.sh b/elf_gen_dep.sh
index 654f96d..306034a 100755
--- a/elf_gen_dep.sh
+++ b/elf_gen_dep.sh
@@ -4,7 +4,7 @@
 #  Round 1: get all the loacl and external symbols
 #######################################################
 
-for i in com32/elflink/modules/*.c32 core/extlinux.elf core/isolinux.elf core/pxelinux.elf
+for i in com32/elflink/modules/*.c32 core/isolinux.elf core/pxelinux.elf
 do
 	# module=$(echo $i | sed "s/^\(.*\).o$/\1/")
 	



More information about the Syslinux-commits mailing list