aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--com32/gfxboot/gfxboot.c3
-rw-r--r--com32/lib/memmem.c45
-rw-r--r--com32/modules/chain.c25
-rw-r--r--core/pxelinux.asm21
-rw-r--r--core/writedec.inc5
-rw-r--r--modules/Makefile2
-rw-r--r--modules/ver.asm606
-rw-r--r--sample/Makefile1
8 files changed, 683 insertions, 25 deletions
diff --git a/com32/gfxboot/gfxboot.c b/com32/gfxboot/gfxboot.c
index 3b09e74a..2323f8ed 100644
--- a/com32/gfxboot/gfxboot.c
+++ b/com32/gfxboot/gfxboot.c
@@ -21,6 +21,7 @@
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <minmax.h>
#include <syslinux/loadfile.h>
#include <syslinux/config.h>
@@ -770,7 +771,7 @@ void *load_one(char *file, ssize_t *file_size)
if(size) {
buf = malloc(size);
for(i = 1, cur = 0 ; cur < size && i > 0; cur += i) {
- i = save_read(fd, buf + cur, CHUNK_SIZE);
+ i = save_read(fd, buf + cur, min(CHUNK_SIZE, size - cur));
if(i == -1) break;
gfx_progress_update(i);
}
diff --git a/com32/lib/memmem.c b/com32/lib/memmem.c
index 8558a80d..7c42f1c3 100644
--- a/com32/lib/memmem.c
+++ b/com32/lib/memmem.c
@@ -18,26 +18,35 @@ void *memmem(const void *haystack, size_t n, const void *needle, size_t m)
size_t j, k, l;
- if (m > n)
- return NULL;
+ if (m > n || !m || !n)
+ return NULL;
- if (x[0] == x[1]) {
- k = 2;
- l = 1;
- } else {
- k = 1;
- l = 2;
- }
+ if (1 != m) {
+ if (x[0] == x[1]) {
+ k = 2;
+ l = 1;
+ } else {
+ k = 1;
+ l = 2;
+ }
- j = 0;
- while (j <= n - m) {
- if (x[1] != y[j + 1]) {
- j += k;
- } else {
- if (!memcmp(x + 2, y + j + 2, m - 2) && x[0] == y[j])
- return (void *)&y[j];
- j += l;
- }
+ j = 0;
+ while (j <= n - m) {
+ if (x[1] != y[j + 1]) {
+ j += k;
+ } else {
+ if (!memcmp(x + 2, y + j + 2, m - 2)
+ && x[0] == y[j])
+ return (void *)&y[j];
+ j += l;
+ }
+ }
+ } else {
+ do {
+ if (*y == *x)
+ return (void *)y;
+ y++;
+ } while (--n);
}
return NULL;
diff --git a/com32/modules/chain.c b/com32/modules/chain.c
index b93f38ed..89489d18 100644
--- a/com32/modules/chain.c
+++ b/com32/modules/chain.c
@@ -76,6 +76,10 @@
* equivalent to seg=0x70 file=<loader> sethidden,
* used with DOS' io.sys.
*
+ * drmk=<loader>
+ * Similar to msdos=<loader> but prepares the special options
+ * for the Dell Real Mode Kernel.
+ *
* grub=<loader>
* same as seg=0x800 file=<loader> & jumping to seg 0x820,
* used with GRUB Legacy stage2 files.
@@ -1707,16 +1711,31 @@ int main(int argc, char *argv[])
* We only really need 4 new, usable bytes at the end.
*/
int tsize = (data[ndata].size + 19) & 0xfffffff0;
+ const union syslinux_derivative_info *sdi;
+
+ sdi = syslinux_derivative_info();
+ /* We should lookup the Syslinux partition offset and use it */
+ fs_lba = *sdi->disk.partoffset;
+ /*
+ * fs_lba should be verified against the disk as some DRMK
+ * variants will check and fail if it does not match
+ */
+ dprintf(" fs_lba offset is %d\n", fs_lba);
+ /* DRMK only uses a DWORD */
+ if (fs_lba > 0xffffffff) {
+ error("LBA very large; Only using lower 32 bits; DRMK will probably fail\n");
+ }
regs.ss = regs.fs = regs.gs = 0; /* Used before initialized */
if (!realloc(data[ndata].data, tsize)) {
error("Failed to realloc for DRMK\n");
- goto bail;
+ goto bail; /* We'll never make it */
}
data[ndata].size = tsize;
- /* ds:[bp+28] must be 0x0000003f */
+ /* ds:bp is assumed by DRMK to be the boot sector */
+ /* offset 28 is the FAT HiddenSectors value */
regs.ds = (tsize >> 4) + (opt.seg - 2);
/* "Patch" into tail of the new space */
- *(int *)(data[ndata].data + tsize - 4) = 0x0000003f;
+ *(int *)(data[ndata].data + tsize - 4) = (int)(fs_lba & 0xffffffff);
}
ndata++;
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index a46b3da5..e8818a6c 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -365,6 +365,16 @@ pxenv:
pushfd
pushad
+ ; We may be removing ourselves from memory
+ cmp bx,0073h ; PXENV_RESTART_TFTP
+ jz .disable_timer
+ cmp bx,00E5h ; gPXE PXENV_FILE_EXEC
+ jnz .store_stack
+
+.disable_timer:
+ call timer_cleanup
+
+.store_stack:
mov [cs:PXEStack],sp
mov [cs:PXEStack+2],ss
lss sp,[cs:InitStack]
@@ -391,6 +401,17 @@ pxenv:
; This clobbers the AX return, but we already saved it into
; the PXEStatus variable.
popad
+
+ ; If the call failed, it could return.
+ cmp bx,0073h
+ jz .enable_timer
+ cmp bx,00E5h
+ jnz .pop_flags
+
+.enable_timer:
+ call timer_init
+
+.pop_flags:
popfd ; Restore flags (incl. IF, DF)
ret
diff --git a/core/writedec.inc b/core/writedec.inc
index bfac0997..19e47968 100644
--- a/core/writedec.inc
+++ b/core/writedec.inc
@@ -37,6 +37,7 @@ writedec_common:
xor cx,cx ; Number of digits
.cloop:
+ mov edx,0
div ebx
inc cx
push dx
@@ -53,5 +54,5 @@ writedec_common:
popad
ret
-writechr:
- ret
+; writechr:
+; ret
diff --git a/modules/Makefile b/modules/Makefile
index f3183641..9b50bb23 100644
--- a/modules/Makefile
+++ b/modules/Makefile
@@ -19,7 +19,7 @@ include $(topdir)/MCONFIG.embedded
INCLUDES = -I$(com32)/include
-BINS = pxechain.com poweroff.com int18.com
+BINS = pxechain.com poweroff.com int18.com ver.com
all: $(BINS)
diff --git a/modules/ver.asm b/modules/ver.asm
new file mode 100644
index 00000000..8ef63faf
--- /dev/null
+++ b/modules/ver.asm
@@ -0,0 +1,606 @@
+; ****************************************************************************
+;
+; ver.asm
+;
+; A COMBOOT/DOS COM program to display the version of the system
+; (Syslinux, DOS, or DRMK)
+;
+; Copyright (C) 2009-2010 Gene Cumm
+;
+; 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 DEBUG
+
+ section .text
+ org 0x100
+
+_start:
+ call crlf
+ mov si,info_str
+ call writestr
+ call getdosver
+ call chkprn_dosver
+ jnz .end
+ call chkprn_syslinux
+ call crlf
+.end:
+; pop ds
+ ret
+
+
+; chkprn_syslinux
+chkprn_syslinux:
+%ifdef DEBUG
+ mov si,may_sysl_str
+ call writestr
+%endif
+ cmp eax,59530000h
+ jne .end
+ cmp ebx,4C530000h
+ jne .end
+ cmp ecx,4E490000h
+ jne .end
+ cmp edx,58550000h
+ jne .end
+.is_syslinux:
+ pushad
+%ifdef DEBUG
+ mov si,is_sysl_str
+ call writestr
+%endif
+.get_sysl_ver:
+ mov ax,0001h
+ int 22h
+; AX=0001h [2.00] Get Version
+;
+; Input: AX 0001h
+; Output: AX number of INT 22h API functions available
+; CH Syslinux major version number
+; CL Syslinux minor version number
+; DL Syslinux derivative ID (e.g. 32h = PXELINUX)
+; ES:SI Syslinux version string
+; ES:DI Syslinux copyright string
+%ifdef DEBUG
+ push si
+ push cs
+ pop ds
+ mov si,gotver_str
+ call writestr
+ pop si
+%endif
+
+.prn_ver_str:
+ mov si,syslban_str
+ call writestr
+ push ds
+ push es
+ pop ds
+ call writestr
+ call crlf
+ pop ds
+.prn_var:
+ cmp dl,31h
+ je .var_sysl
+ cmp dl,32h
+ je .var_pxel
+ cmp dl,33h
+ je .var_isol
+ cmp dl,34h
+ je .var_extl
+ jmp .var_unk
+.var_sysl:
+ mov si,sysl_str
+ call writestr
+ jmp .prn_lnxsp
+.var_pxel:
+ mov si,pxel_str
+ call writestr
+ jmp .prn_lnxsp
+.var_isol:
+ mov si,isol_str
+ call writestr
+ jmp .prn_lnxsp
+.var_extl:
+ mov si,extl_str
+ call writestr
+; jmp .prn_lnxsp
+.prn_lnxsp:
+ mov si,linsp_str
+ call writestr
+ jmp .prn_ver
+.var_unk:
+ mov si,unkvar_str
+ call writestr
+.prn_ver:
+%ifdef DEBUG
+ push si
+ push cs
+ pop ds
+ mov si,prn_ver_str
+ call writestr
+ pop si
+%endif
+.prn_ver_maj:
+ mov al,ch
+ call writedecb
+ mov dl,'.'
+ call writechr_dl
+.prn_ver_min:
+ mov al,cl
+; cmp al,10
+; jae .min_wri
+; mov al,'0'
+; call writechr
+; mov al,cl
+; .min_wri:
+; call writedecb
+ call writedecb2
+
+.end_prn:
+ popad
+.end:
+ ret
+
+; chkprn_dosver Check and print DOS version;
+; Input Data from INT21 AH=30h
+; AH Major version of DOS or 0
+; AL Minor Version
+; BH DOS type
+; BL:CX 24-bit OEM serial number
+; Return
+; ZF Unset if DOS, Set if not DOS (AX=0)
+chkprn_dosver:
+ and ax,ax ; cmp ax,0
+ jz .end
+.is_dos:
+ push eax
+ push edx
+ push si
+%ifdef DEBUG
+ mov si,is_dos_str
+ call writestr
+ call crlf
+ call prnreg_gp_l
+ call crlf
+%endif
+.var_prn:
+ cmp bh,0
+ je .var_pcdos
+ cmp bh,0FFh
+ je .var_msdos
+ cmp bh,0FDh
+ je .var_freedos
+ cmp bh,0DEh
+ je .var_drmk
+ jmp .var_unk
+.var_pcdos:
+ mov si,pcdos_str
+ call writestr
+ jmp .var_end
+.var_msdos:
+ mov si,msdos_str
+ call writestr
+ jmp .var_end
+.var_freedos:
+ mov si,freedos_str
+ call writestr
+ jmp .var_end
+.var_drmk:
+ mov si,drmk_str
+ call writestr
+ jmp .var_end
+.var_unk:
+ mov si,unkdos_str
+ call writestr
+ mov si,spparen_str
+ call writestr
+ push eax
+ mov al,bh
+ call writehex2
+ pop eax
+ mov si,parensp_str
+ call writestr
+; jmp .var_end
+.var_end:
+ call prn_dosver_num
+ call crlf
+.subver:
+ pop si
+ pop edx
+ pop eax
+ cmp bh,0FFh
+ je .msdos_ver
+ cmp bh,0DEh
+ jne .end_ver
+.drmk_ver:
+ call getprn_drmkver
+; jmp .end_ver ; DRMK returns Extended/True DOS
+.msdos_ver:
+ cmp al,5
+ jb .end_ver
+ call getprn_msdosver
+.end_ver:
+ and ax,ax ; Unset ZF
+.end:
+ ret
+
+; prn_dosver_num Print the numerical DOS version
+; Input Data from INT21 AH=30h
+; AH Major version of DOS or 0
+; AL Minor Version
+; BH DOS type
+; BL:CX 24-bit OEM serial number
+prn_dosver_num:
+ push eax
+ push edx
+ push si
+ pushfd
+.vmaj_prn:
+ call writedecb
+; call writehex2
+ mov dl,'.'
+ call writechr_dl
+.vmin_prn:
+ mov al,ah
+ call writedecb
+; call writehex2
+.serial: ; Skip if 0
+ cmp bl,0
+ jne .ser_start
+ cmp cx,0
+ je .end
+.ser_start:
+ mov si,spparen_str
+ call writestr
+ mov si,zerox_str
+ call writestr
+.ser_bl:
+ mov al,bl
+ call writehex2
+.ser_cx:
+ mov ax,cx
+ call writehex4
+.serial_end:
+ mov si,parensp_str
+ call writestr
+.end:
+ popfd
+ pop si
+ pop edx
+ pop eax
+ ret
+
+; getdosver Get the DOS version
+; Return Version or 0 + SYSLINUX message
+; EAX Part 1
+; EBX Part 2
+; ECX Part 3
+; EDX Part 4
+getdosver:
+ mov ecx,0
+ mov edx,0
+ mov ebx,0
+ mov eax,3000h
+ int 21h
+ ret
+
+; getmsdosver Get the Extended MS-DOS version
+; Returns Version
+; EAX Part 1
+; EBX Part 2
+; ECX Part 3
+; EDX Part 4
+getmsdosver:
+ mov ecx,0
+ mov edx,0
+ mov ebx,0
+ mov eax,3306h
+ int 21h
+ ret
+
+; getprn_msdosver
+getprn_msdosver:
+ pushad
+ pushfd
+ call getmsdosver
+%ifdef DEBUG
+ call prnreg_gp_l
+ call crlf
+%endif
+ mov si,dosext_str
+ call writestr
+ mov eax,ebx
+ mov ebx,0
+ mov ecx,edx
+ call prn_dosver_num
+.end:
+ popfd
+ popad
+ ret
+
+; getdrmkver: Get the DRMK-specifc OS version
+; Returns Version
+; AX OS Version
+; DX Patch Version
+getdrmkver:
+ mov ax,4452h
+ int 21h
+ ret
+
+; getdrmkver: Get the DRMK-specifc Kernel build info
+; Returns Kernel build info
+; AX Kernel build date in DOS 16-bit format
+; [ES:BX] Kernel private data
+getdrmkbld:
+ mov ax,4458h
+ int 21h
+ ret
+
+; getprn_drmkver: Get/Print DRMK-specific Version info
+getprn_drmkver:
+ pushad
+ pushfd
+.getver:
+ call getdrmkver
+.prnosver: ; "OS Version"
+ mov si,osver_str
+ call writestr
+ mov si,zerox_str
+ call writestr
+; mov ax,0
+ call writehex4
+ call crlf
+.prnpatchver: ; "Patch Version"
+ mov si,patchver_str
+ call writestr
+ mov si,zerox_str
+ call writestr
+ mov ax,dx
+ call writehex4
+ call crlf
+.getbld:
+ call getdrmkbld
+.prnkernbld: ; "Kernel Build Date"
+ mov si,kernbld_str
+ call writestr
+ call writedate_ax
+ call crlf
+.prnkernprvaddr:
+ mov si,prvdat_str
+ call writestr
+ mov ax,es
+ call writehex4
+ mov dl,':'
+ call writechr_dl
+ mov ax,bx
+ call writehex4
+ call crlf
+%ifdef DEBUG
+.prnkernprv:
+ mov di,[es:bx]
+ mov ax,di
+ call writehex4
+ call crlf
+ mov si,2
+ mov cx,8
+.prnkernprv2:
+ push cx
+ mov cx,8
+.prnkernprv1:
+ mov eax,[es:bx+si]
+ call writehex8
+ cmp cx,1
+ jbe .prnkern0dash
+ mov ax,'-'
+ call writechr
+.prnkern0dash:
+ add si,4
+ sub di,4
+ cmp di,0
+ jbe .prnkernprvend
+ loop .prnkernprv1
+ call crlf
+ pop cx
+ loop .prnkernprv2
+ jmp .end
+.prnkernprvend:
+ pop cx
+%endif
+.end:
+ popfd
+ popad
+ ret
+
+;writedate_ax Write a date in AX in ISO8601 big endian format
+; Input
+; AX Date in 16-bit DOS format
+; 2006-01-11
+; 0011010 0001 01011
+writedate_ax:
+ pushad
+ pushfd
+ mov dx,ax
+%ifdef DEBUG
+ call writehex4
+ call crlf
+%endif
+.year:
+ shr ax,9
+ add ax,1980
+ call writedecw
+ mov al,'-'
+ call writechr
+ mov ax,dx
+.month:
+ shr ax,5
+ and ax,0Fh
+; cmp ax,10
+; jae .month_wri
+; mov cx,ax
+; mov ax,'0'
+; call writechr
+; mov ax,cx
+; .month_wri:
+; call writedecb
+ call writedecb2
+ mov al,'-'
+ call writechr
+ mov ax,dx
+.day:
+ and ax,1Fh
+; cmp ax,10
+; jae .day_wri
+; mov cx,ax
+; mov ax,'0'
+; call writechr
+; mov ax,cx
+; .day_wri:
+; call writedecb
+ call writedecb2
+.end:
+ popfd
+ popad
+ ret
+
+; writechr_dl Write a character to the console saving AX
+; Input
+; DL character to write
+writechr_dl:
+ push ax
+ mov ah,02h
+ int 21h
+.end:
+ pop ax
+ ret
+
+; writechr_al Write a character to the console saving AX
+; Input
+; AL character to write
+writechr:
+writechr_al:
+ push dx
+ mov dl,al
+ call writechr_dl
+.end: pop dx
+ ret
+
+; writedecb[23] Print byte as fixed width
+; Input
+; AL number to write
+writedecb3:
+ pushfd
+ cmp al,100
+ jae .skip
+ push ax
+ mov ax,'0'
+ call writechr
+ pop ax
+.skip: popfd
+writedecb2:
+ pushfd
+ cmp al,10
+ jae .skip
+ push ax
+ mov ax,'0'
+ call writechr
+ pop ax
+.skip: popfd
+ call writedecb
+ ret
+
+
+; prnreg_gp_l Dump GP registers (Long)
+prnreg_gp_l:
+ push eax
+ push si
+ call crlf
+ mov si,sp2_str
+ call writestr
+ mov si,eax_str
+ call writestr
+ call writehex8
+ mov si,sp2_str
+ call writestr
+ mov si,ecx_str
+ call writestr
+ mov eax,ecx
+ call writehex8
+ mov si,sp2_str
+ call writestr
+ mov si,edx_str
+ call writestr
+ mov eax,edx
+ call writehex8
+ mov si,sp2_str
+ call writestr
+ mov si,ebx_str
+ call writestr
+ mov eax,ebx
+ call writehex8
+ call crlf
+ pop si
+ pop eax
+.end:
+ ret
+
+; is_zf
+is_zf:
+ push si
+ jz .true
+.false:
+ mov si,zero_not_str
+ call writestr
+ jmp .end
+.true:
+ mov si,zero_is_str
+ call writestr
+.end:
+ pop si
+ ret
+
+%include "../core/macros.inc" ; CR/LF
+%include "../core/writestr.inc" ; String output
+%include "../core/writehex.inc" ; Hexadecimal output
+%include "../core/writedec.inc" ; Decimal output
+
+ section .data
+info_str db 'Ver.com b026', CR, LF, 0
+is_dos_str db 'Found DOS', CR, LF, 0
+is_sysl_str db 'Found a Syslinux variant', CR, LF, 0
+is_drmk_str db 'Found DRMK', CR, LF, 0
+may_sysl_str db 'Maybe Syslinux variant', CR, LF, 0
+gotver_str db 'Got the version back', CR, LF, 0
+prn_ver_str db 'Printing version number', CR, LF, 0
+syslban_str db 'Syslinux banner: ',0
+sysl_str db 'SYS', 0
+pxel_str db 'PXE', 0
+isol_str db 'ISO', 0
+extl_str db 'EXT', 0
+linsp_str db 'LINUX ', 0
+unkvar_str db 'Unkown-Variant ', 0
+pcdos_str db 'PC-DOS ', 0
+msdos_str db 'MS-DOS ', 0
+freedos_str db 'FreeDOS ', 0
+unkdos_str db 'Unknown-DOS ', 0
+drmk_str db 'DRMK ', 0
+dosext_str db ' Extended DOS version: ', 0
+osver_str db ' OS Version: ', 0
+patchver_str db ' Patch Version: ', 0
+kernbld_str db ' Kernel Build Date: ', 0
+prvdat_str db ' Private Data Ptr: ', 0
+spparen_str db ' (', 0
+zerox_str db '0x', 0
+parensp_str db ') ', 0
+eax_str db 'EAX=', 0
+ebx_str db 'EBX=', 0
+ecx_str db 'ECX=', 0
+edx_str db 'EDX=', 0
+sp2_str db ' ', 0
+zero_not_str db ' NOT_Zero ',0
+zero_is_str db ' IS_Zero ',0
diff --git a/sample/Makefile b/sample/Makefile
index f1006ff9..d7f439ca 100644
--- a/sample/Makefile
+++ b/sample/Makefile
@@ -15,6 +15,7 @@
##
topdir = ..
+include $(topdir)/MCONFIG.embedded
PPMTOLSS16 = $(topdir)/utils/ppmtolss16