aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhpa <hpa>2001-04-24 05:10:09 +0000
committerhpa <hpa>2001-04-24 05:10:09 +0000
commitf596388e20cde977bbdfc13c827592ff5107f1f6 (patch)
tree8f2948aaeed74b1bfd18bcb50037688e1c072c66
parent23d61d559b41a241c9844bcbe69340e282339a88 (diff)
downloadsyslinux-elf-syslinux-1.62-pre3.tar.gz
syslinux-elf-syslinux-1.62-pre3.tar.xz
syslinux-elf-syslinux-1.62-pre3.zip
- Graphics fixessyslinux-1.62-pre3
- More work on memdisk.asm - PXELINUX: Move private options to 208 (to avoid Etherboot conflict); document need to force these options on the server and the associated problems.
-rw-r--r--isolinux.asm6
-rw-r--r--ldlinux.asm6
-rw-r--r--memdisk.asm217
-rw-r--r--memdisk/memdisk.asm217
-rw-r--r--pxelinux.asm65
-rw-r--r--pxelinux.doc29
6 files changed, 468 insertions, 72 deletions
diff --git a/isolinux.asm b/isolinux.asm
index 56d740ba..f3f926b4 100644
--- a/isolinux.asm
+++ b/isolinux.asm
@@ -3043,7 +3043,7 @@ use_font:
jne .text
.graphics:
- xor cx,bx
+ xor cx,cx
mov cl,bh ; CX = bytes/character
mov ax,480
div cl ; Compute char rows per screen
@@ -3052,7 +3052,7 @@ use_font:
mov [VidRows],al
mov ax,1121h ; Set user character table
int 10h
- mov [VidRows], byte 79 ; Always 80 bytes/line
+ mov [VidCols], byte 79 ; Always 80 bytes/line
mov [TextPage], byte 0 ; Always page 0
ret ; No need to call adjust_screen
@@ -4156,7 +4156,7 @@ vgaclearmode:
; mov dx,TextColorReg ; Restore color registers
; mov ax,1002h
; int 10h
-
+ mov [UsingVGA], byte 0
call use_font ; Restore text font/data
mov byte [ScrollAttribute], 07h
diff --git a/ldlinux.asm b/ldlinux.asm
index 78329f8b..50e5e29f 100644
--- a/ldlinux.asm
+++ b/ldlinux.asm
@@ -2989,7 +2989,7 @@ use_font:
jne .text
.graphics:
- xor cx,bx
+ xor cx,cx
mov cl,bh ; CX = bytes/character
mov ax,480
div cl ; Compute char rows per screen
@@ -2998,7 +2998,7 @@ use_font:
mov [VidRows],al
mov ax,1121h ; Set user character table
int 10h
- mov [VidRows], byte 79 ; Always 80 bytes/line
+ mov [VidCols], byte 79 ; Always 80 bytes/line
mov [TextPage], byte 0 ; Always page 0
ret ; No need to call adjust_screen
@@ -4126,7 +4126,7 @@ vgaclearmode:
; mov dx,TextColorReg ; Restore color registers
; mov ax,1002h
; int 10h
-
+ mov [UsingVGA], byte 0
call use_font ; Restore text font/data
mov byte [ScrollAttribute], 07h
diff --git a/memdisk.asm b/memdisk.asm
index aa95f9ec..a690e66b 100644
--- a/memdisk.asm
+++ b/memdisk.asm
@@ -19,10 +19,15 @@
org 0h
+%define SECTORSIZE_LG2 9 ; log2(sector size)
+%define SECTORSIZE (1 << SECTORSIZE_LG2)
+
MyStack equ 1024
; Parameter registers definition; this is the definition
; of the stack frame.
+%define P_DS word [bp+34]
+%define P_ES word [bp+32]
%define P_EAX dword [bp+28]
%define P_AX word [bp+28]
%define P_AL byte [bp+28]
@@ -86,6 +91,7 @@ Done: ; Standard routine for return
mov [LastStatus],ah
mov P_AX,ax
cmp ah,1
+DoneWeird:
setnb al ; AL <- (AH > 0) ? 1 : 0 (CF)
lds bx,[Stack] ; DS:BX <- Old stack pointer
mov [bx+4],al ; Low byte of old FLAGS -> arithmetric flags
@@ -106,38 +112,208 @@ Reset:
and dl,80h ; Clear all but the type bit
jmp far [OldInt13]
+Invalid:
+ mov ax,0100h ; Unsupported function
+ ret
+
+GetDriveType:
+ pop ax ; Drop return address
+ mov ah,[DriveNo]
+ shr ah,7
+ or ah,02h ; CF = 0
+ mov P_AH,ah
+ mov [LastStatus],byte 0 ; Success, but AH returns a value
+ jmp short DoneWeird
+
GetStatus:
mov ah,[LastStatus] ; Copy last status
ret
-CheckIfReady:
+CheckIfReady: ; These are always-successful noop functions
Recalibrate:
- xor ah,ah ; Always successful
+InitWithParms:
+DetectChange:
+success:
+ xor ax,ax ; Always successful
ret
Read:
+ call setup_regs
+do_copy:
+ call bcopy
+ movzx ax,P_AL ; AH = 0, AL = transfer count
+ ret
+
Write:
+ call setup_regs
+ xchg esi,edi
+ jmp short do_copy
+
+ ; These verify one sector only
+Seek:
+ mov P_AL,1
+
+ ; Verify integrity; just bounds-check
Verify:
-Format:
+ call setup_regs ; Returns error if appropriate
+ jmp short success
+
GetParms:
-InitWithParms:
-Seek:
-GetDriveType:
-DetectChange:
+ ; We need to get the "number of drives" from the BIOS
+ mov dl,P_DL
+ inc dl ; The drive whose number we're stealing
+ mov ah,08h
+ int 13h
+ inc dl ; Add ourselves to the count
+ mov P_DL,dl ; Drive count
+ mov P_DI,di ; Steal the diskette parameter table if applicable
+ mov ax,es
+ mov P_ES,ax
+ mov bl,[DriveType]
+ mov P_BL,bl
+ mov ax,[Cylinders]
+ dec ax ; We report the highest #, not the count
+ or ah,[Sectors]
+ xchg al,ah
+ mov P_CX,ax
+ mov al,[Heads]
+ dec al
+ mov P_DH,al
+ xor ax,ax
+ ret
-Invalid:
- mov ah,01h ; Unsupported function
+ ; Convert a CHS address in CX/DH into an LBA in EAX
+chstolba:
+ xor ebx,ebx
+ mov bl,cl ; Sector number
+ and bl,3Fh
+ dec bx
+ mov si,dx
+ mov ax,[Heads]
+ shr cl,6
+ xchg cl,ch ; Now CX <- cylinder number
+ mul cx ; DX:AX <- AX*CX
+ shr si,8 ; SI <- head number
+ add ax,si
+ adc dx,byte 0
+ shl edx,16
+ or eax,edx
+ mul dword [Sectors]
+ add eax,ebx
+ ret
+
+bcopy:
+ ; Do something here
+
+ ; Set up registers as for a "Read", and compares against disk size
+setup_regs:
+ call chstolba
+ movzx edi,P_BX ; Get linear address of target buffer
+ movzx ecx,P_ES
+ shr ecx,4
+ add edi,ecx
+ movzx ecx,P_AL
+ lea ebx,[eax+ecx]
+ mov esi,eax
+ shr esi,SECTORSIZE_LG2
+ add esi,[DiskBuf]
+ cmp ebx,[DiskSize]
+ jae .overrun
ret
+.overrun: pop ax ; Drop return address
+ mov ax,0400h ; Sector not found
+ ret
+
+int15_e820:
+ cmp edx,534D4150h
+ jne near oldint15
+ cmp ecx,20 ; Need 20 bytes
+ jb err86
+ push edx ; "SMAP"
+ push esi
+ push edi
+ and ebx,ebx
+ jne .renew
+ mov ebx,[E820Table]
+.renew: mov esi,ebx
+ xor edi,edi
+ mov di,cs
+ shr di,4
+ add edi,E820Buf
+ mov ecx,24/4
+ call bcopy
+ add ebx, byte 12
+ pop edi
+ pop esi
+ mov eax,[cs:E820Buf]
+ mov [es:di],eax
+ mov eax,[cs:E820Buf+4]
+ mov [es:di+4],eax
+ mov eax,[cs:E820Buf+12]
+ mov [es:di+8],eax
+ mov eax,[cs:E820Buf+16]
+ mov [es:di+12],eax
+ mov eax,[cs:E820Buf+8]
+ mov [es:di+16],eax
+ cmp dword [cs:E820Buf+20], byte -1
+ jne .notdone
+ xor ebx,ebx ; Done with table
+.notdone:
+ pop eax ; "SMAP"
+ mov ecx,20 ; Bytes loaded
+int15_success:
+ mov byte [bp+12], 02h ; Clear CF
+ pop bp
+ iret
+
+err86:
+ mov byte [bp+12], 03h ; Set CF
+ mov ah,86h
+ pop bp
+ iret
+
+Int15Start:
+ push bp
+ mov bp,sp
+ cmp ax,0E820h
+ je near int15_e820
+ cmp ax,0E801h
+ je int15_e801
+ cmp ax,0E881h
+ je int15_e881
+ cmp ah,88h
+ je int15_88
+oldint15: pop bp
+ jmp far [OldInt15]
+
+int15_e801:
+ mov ax,[cs:Mem1MB]
+ mov cx,ax
+ mov bx,[cs:Mem16MB]
+ mov dx,ax
+ jmp short int15_success
+
+int15_e881:
+ mov eax,[cs:Mem1MB]
+ mov ecx,eax
+ mov ebx,[cs:Mem16MB]
+ mov edx,eax
+ jmp short int15_success
+
+int15_88:
+ mov ax,[cs:MemInt1588]
+ jmp short int15_success
+
section .data
Int13Funcs dw Reset ; 00h - RESET
dw GetStatus ; 01h - GET STATUS
dw Read ; 02h - READ
dw Write ; 03h - WRITE
dw Verify ; 04h - VERIFY
- dw Format ; 05h - FORMAT TRACK
- dw Format ; 06h - FORMAT TRACK AND SET BAD FLAGS
- dw Format ; 07h - FORMAT DRIVE AT TRACK
+ dw Invalid ; 05h - FORMAT TRACK
+ dw Invalid ; 06h - FORMAT TRACK AND SET BAD FLAGS
+ dw Invalid ; 07h - FORMAT DRIVE AT TRACK
dw GetParms ; 08h - GET PARAMETERS
dw InitWithParms ; 09h - INITIALIZE CONTROLLER WITH DRIVE PARAMETERS
dw Invalid ; 0Ah
@@ -157,11 +333,24 @@ Int13FuncsEnd equ $
Int13FuncsMax equ (Int13FuncsEnd-Int13Funcs) >> 1
DriveNo db 0 ; Our drive number
+DriveType db 0 ; Our drive type (floppies)
LastStatus db 0 ; Last return status
+ alignb 4, db 0
+Cylinders dw 0 ; Cylinder count
+Heads dw 0 ; Head count
+Sectors dd 0 ; Sector count (zero-extended)
+DiskSize dd 0 ; Size of disk in blocks
+DiskBuf dd 0 ; Linear address of high memory disk
+
+E820Table dd 0 ; E820 table in high memory
+Mem1MB dd 0 ; 1MB-16MB memory amount (1K)
+Mem16MB dd 0 ; 16MB-4G memory amount (64K)
+MemInt1588 dw 0 ; 1MB-65MB memory amount (1K)
+
section .bss
OldInt13 resd 1 ; INT 13h in chain
+OldInt15 resd 1 ; INT 15h in chain
Stack resd 1 ; Saved SS:SP on invocation
+E820Buf resd 6 ; E820 fetch buffer
SavedAX resw 1 ; AX saved during initialization
-
-
diff --git a/memdisk/memdisk.asm b/memdisk/memdisk.asm
index aa95f9ec..a690e66b 100644
--- a/memdisk/memdisk.asm
+++ b/memdisk/memdisk.asm
@@ -19,10 +19,15 @@
org 0h
+%define SECTORSIZE_LG2 9 ; log2(sector size)
+%define SECTORSIZE (1 << SECTORSIZE_LG2)
+
MyStack equ 1024
; Parameter registers definition; this is the definition
; of the stack frame.
+%define P_DS word [bp+34]
+%define P_ES word [bp+32]
%define P_EAX dword [bp+28]
%define P_AX word [bp+28]
%define P_AL byte [bp+28]
@@ -86,6 +91,7 @@ Done: ; Standard routine for return
mov [LastStatus],ah
mov P_AX,ax
cmp ah,1
+DoneWeird:
setnb al ; AL <- (AH > 0) ? 1 : 0 (CF)
lds bx,[Stack] ; DS:BX <- Old stack pointer
mov [bx+4],al ; Low byte of old FLAGS -> arithmetric flags
@@ -106,38 +112,208 @@ Reset:
and dl,80h ; Clear all but the type bit
jmp far [OldInt13]
+Invalid:
+ mov ax,0100h ; Unsupported function
+ ret
+
+GetDriveType:
+ pop ax ; Drop return address
+ mov ah,[DriveNo]
+ shr ah,7
+ or ah,02h ; CF = 0
+ mov P_AH,ah
+ mov [LastStatus],byte 0 ; Success, but AH returns a value
+ jmp short DoneWeird
+
GetStatus:
mov ah,[LastStatus] ; Copy last status
ret
-CheckIfReady:
+CheckIfReady: ; These are always-successful noop functions
Recalibrate:
- xor ah,ah ; Always successful
+InitWithParms:
+DetectChange:
+success:
+ xor ax,ax ; Always successful
ret
Read:
+ call setup_regs
+do_copy:
+ call bcopy
+ movzx ax,P_AL ; AH = 0, AL = transfer count
+ ret
+
Write:
+ call setup_regs
+ xchg esi,edi
+ jmp short do_copy
+
+ ; These verify one sector only
+Seek:
+ mov P_AL,1
+
+ ; Verify integrity; just bounds-check
Verify:
-Format:
+ call setup_regs ; Returns error if appropriate
+ jmp short success
+
GetParms:
-InitWithParms:
-Seek:
-GetDriveType:
-DetectChange:
+ ; We need to get the "number of drives" from the BIOS
+ mov dl,P_DL
+ inc dl ; The drive whose number we're stealing
+ mov ah,08h
+ int 13h
+ inc dl ; Add ourselves to the count
+ mov P_DL,dl ; Drive count
+ mov P_DI,di ; Steal the diskette parameter table if applicable
+ mov ax,es
+ mov P_ES,ax
+ mov bl,[DriveType]
+ mov P_BL,bl
+ mov ax,[Cylinders]
+ dec ax ; We report the highest #, not the count
+ or ah,[Sectors]
+ xchg al,ah
+ mov P_CX,ax
+ mov al,[Heads]
+ dec al
+ mov P_DH,al
+ xor ax,ax
+ ret
-Invalid:
- mov ah,01h ; Unsupported function
+ ; Convert a CHS address in CX/DH into an LBA in EAX
+chstolba:
+ xor ebx,ebx
+ mov bl,cl ; Sector number
+ and bl,3Fh
+ dec bx
+ mov si,dx
+ mov ax,[Heads]
+ shr cl,6
+ xchg cl,ch ; Now CX <- cylinder number
+ mul cx ; DX:AX <- AX*CX
+ shr si,8 ; SI <- head number
+ add ax,si
+ adc dx,byte 0
+ shl edx,16
+ or eax,edx
+ mul dword [Sectors]
+ add eax,ebx
+ ret
+
+bcopy:
+ ; Do something here
+
+ ; Set up registers as for a "Read", and compares against disk size
+setup_regs:
+ call chstolba
+ movzx edi,P_BX ; Get linear address of target buffer
+ movzx ecx,P_ES
+ shr ecx,4
+ add edi,ecx
+ movzx ecx,P_AL
+ lea ebx,[eax+ecx]
+ mov esi,eax
+ shr esi,SECTORSIZE_LG2
+ add esi,[DiskBuf]
+ cmp ebx,[DiskSize]
+ jae .overrun
ret
+.overrun: pop ax ; Drop return address
+ mov ax,0400h ; Sector not found
+ ret
+
+int15_e820:
+ cmp edx,534D4150h
+ jne near oldint15
+ cmp ecx,20 ; Need 20 bytes
+ jb err86
+ push edx ; "SMAP"
+ push esi
+ push edi
+ and ebx,ebx
+ jne .renew
+ mov ebx,[E820Table]
+.renew: mov esi,ebx
+ xor edi,edi
+ mov di,cs
+ shr di,4
+ add edi,E820Buf
+ mov ecx,24/4
+ call bcopy
+ add ebx, byte 12
+ pop edi
+ pop esi
+ mov eax,[cs:E820Buf]
+ mov [es:di],eax
+ mov eax,[cs:E820Buf+4]
+ mov [es:di+4],eax
+ mov eax,[cs:E820Buf+12]
+ mov [es:di+8],eax
+ mov eax,[cs:E820Buf+16]
+ mov [es:di+12],eax
+ mov eax,[cs:E820Buf+8]
+ mov [es:di+16],eax
+ cmp dword [cs:E820Buf+20], byte -1
+ jne .notdone
+ xor ebx,ebx ; Done with table
+.notdone:
+ pop eax ; "SMAP"
+ mov ecx,20 ; Bytes loaded
+int15_success:
+ mov byte [bp+12], 02h ; Clear CF
+ pop bp
+ iret
+
+err86:
+ mov byte [bp+12], 03h ; Set CF
+ mov ah,86h
+ pop bp
+ iret
+
+Int15Start:
+ push bp
+ mov bp,sp
+ cmp ax,0E820h
+ je near int15_e820
+ cmp ax,0E801h
+ je int15_e801
+ cmp ax,0E881h
+ je int15_e881
+ cmp ah,88h
+ je int15_88
+oldint15: pop bp
+ jmp far [OldInt15]
+
+int15_e801:
+ mov ax,[cs:Mem1MB]
+ mov cx,ax
+ mov bx,[cs:Mem16MB]
+ mov dx,ax
+ jmp short int15_success
+
+int15_e881:
+ mov eax,[cs:Mem1MB]
+ mov ecx,eax
+ mov ebx,[cs:Mem16MB]
+ mov edx,eax
+ jmp short int15_success
+
+int15_88:
+ mov ax,[cs:MemInt1588]
+ jmp short int15_success
+
section .data
Int13Funcs dw Reset ; 00h - RESET
dw GetStatus ; 01h - GET STATUS
dw Read ; 02h - READ
dw Write ; 03h - WRITE
dw Verify ; 04h - VERIFY
- dw Format ; 05h - FORMAT TRACK
- dw Format ; 06h - FORMAT TRACK AND SET BAD FLAGS
- dw Format ; 07h - FORMAT DRIVE AT TRACK
+ dw Invalid ; 05h - FORMAT TRACK
+ dw Invalid ; 06h - FORMAT TRACK AND SET BAD FLAGS
+ dw Invalid ; 07h - FORMAT DRIVE AT TRACK
dw GetParms ; 08h - GET PARAMETERS
dw InitWithParms ; 09h - INITIALIZE CONTROLLER WITH DRIVE PARAMETERS
dw Invalid ; 0Ah
@@ -157,11 +333,24 @@ Int13FuncsEnd equ $
Int13FuncsMax equ (Int13FuncsEnd-Int13Funcs) >> 1
DriveNo db 0 ; Our drive number
+DriveType db 0 ; Our drive type (floppies)
LastStatus db 0 ; Last return status
+ alignb 4, db 0
+Cylinders dw 0 ; Cylinder count
+Heads dw 0 ; Head count
+Sectors dd 0 ; Sector count (zero-extended)
+DiskSize dd 0 ; Size of disk in blocks
+DiskBuf dd 0 ; Linear address of high memory disk
+
+E820Table dd 0 ; E820 table in high memory
+Mem1MB dd 0 ; 1MB-16MB memory amount (1K)
+Mem16MB dd 0 ; 16MB-4G memory amount (64K)
+MemInt1588 dw 0 ; 1MB-65MB memory amount (1K)
+
section .bss
OldInt13 resd 1 ; INT 13h in chain
+OldInt15 resd 1 ; INT 15h in chain
Stack resd 1 ; Saved SS:SP on invocation
+E820Buf resd 6 ; E820 fetch buffer
SavedAX resw 1 ; AX saved during initialization
-
-
diff --git a/pxelinux.asm b/pxelinux.asm
index 48696e37..f1d6158f 100644
--- a/pxelinux.asm
+++ b/pxelinux.asm
@@ -657,6 +657,17 @@ query_bootp:
call crlf ; ***
;
+; Check to see if we got any PXELINUX-specific DHCP options; in particular,
+; if we didn't get the magic enable, do not recognize any other options.
+;
+check_dhcp_magic:
+ test byte [DHCPMagic], 1 ; If we didn't get the magic enable...
+ jnz .got_magic
+ mov byte [DHCPMagic], 0 ; If not, kill all other options
+.got_magic:
+
+
+;
; Initialize UDP stack
;
udp_init:
@@ -779,16 +790,6 @@ mkkeymap: stosb
;
-; Check to see if we got any PXELINUX-specific DHCP options
-;
-check_dhcp_magic:
- test byte [DHCPMagic], 1 ; If we didn't get the magic enable...
- jnz .got_magic
- mov byte [DHCPMagic], 0 ; If not, kill all other options
-.got_magic:
-
-
-;
; Store standard filename prefix
;
prefix: test byte [DHCPMagic], 04h ; Did we get a path prefix option
@@ -857,6 +858,7 @@ config_scan:
jz .no_option
; We got a DHCP option, try it first
+ push di
mov si,trying_msg
call writestr
mov di,ConfigName
@@ -864,6 +866,7 @@ config_scan:
call writestr
call crlf
call open
+ pop di
jnz .success
.no_option: ; Have to guess config file name
@@ -3054,7 +3057,7 @@ use_font:
jne .text
.graphics:
- xor cx,bx
+ xor cx,cx
mov cl,bh ; CX = bytes/character
mov ax,480
div cl ; Compute char rows per screen
@@ -3063,7 +3066,7 @@ use_font:
mov [VidRows],al
mov ax,1121h ; Set user character table
int 10h
- mov [VidRows], byte 79 ; Always 80 bytes/line
+ mov [VidCols], byte 79 ; Always 80 bytes/line
mov [TextPage], byte 0 ; Always page 0
ret ; No need to call adjust_screen
@@ -4247,32 +4250,31 @@ parse_dhcp_options:
mov edx,[si]
mov [Netmask],edx
jmp short .opt_done
-
.not_subnet:
+
cmp dl,3 ; ROUTER option
jne .not_router
mov edx,[si]
mov [Gateway],edx
jmp short .opt_done
-
.not_router:
+
cmp dl,52 ; OPTION OVERLOAD option
jne .not_overload
mov dl,[si]
mov [OverLoad],dl
jmp short .opt_done
-
.not_overload:
+
cmp dl,67 ; BOOTFILE NAME option
jne .not_bootfile
mov di,BootFile
jmp short .copyoption
-
.done:
ret ; This is here to make short jumps easier
-
.not_bootfile:
- cmp dl,176 ; PXELINUX MAGIC option
+
+ cmp dl,208 ; PXELINUX MAGIC option
jne .not_pl_magic
cmp al,4 ; Must have length == 4
jne .opt_done
@@ -4280,23 +4282,23 @@ parse_dhcp_options:
jne .opt_done
or byte [DHCPMagic], byte 1 ; Found magic #
jmp short .opt_done
-
.not_pl_magic:
- cmp dl,177 ; PXELINUX CONFIGFILE option
+
+ cmp dl,209 ; PXELINUX CONFIGFILE option
jne .not_pl_config
mov di,ConfigName
or byte [DHCPMagic], byte 2 ; Got config file
jmp short .copyoption
-
.not_pl_config:
- cmp dl,178 ; PXELINUX PATHPREFIX option
+
+ cmp dl,210 ; PXELINUX PATHPREFIX option
jne .not_pl_prefix
mov di,PathPrefix
or byte [DHCPMagic], byte 4 ; Got path prefix
jmp short .copyoption
-
.not_pl_prefix:
- cmp dl,179 ; PXELINUX REBOOTTIME option
+
+ cmp dl,211 ; PXELINUX REBOOTTIME option
jne .not_pl_timeout
cmp al,4
jne .opt_done
@@ -4307,8 +4309,8 @@ parse_dhcp_options:
mov [RebootTime],edx
or byte [DHCPMagic], byte 8 ; Got RebootTime
; jmp short .opt_done
+.not_pl_timeout:
-.not_pl_timeout
; Unknown option. Skip to the next one.
.opt_done:
add si,ax
@@ -4584,11 +4586,13 @@ vgasetmode:
mov ax,1A00h ; Get video card and monitor
xor bx,bx
int 10h
- cmp bl, 8 ; If not VGA card/VGA monitor, give up
- jne .error ; ZF=0
+ sub bl, 7 ; BL=07h and BL=08h OK
+ cmp bl, 1
+ ja .error ; ZF=0
; mov bx,TextColorReg
; mov dx,1009h ; Read color registers
; int 10h
+.ok:
mov ax,0012h ; Set mode = 640x480 VGA 16 colors
int 10h
mov dx,linear_color
@@ -4611,20 +4615,21 @@ vgaclearmode:
push ds
push cs
pop ds ; DS <- CS
- pushad
cmp [UsingVGA], byte 1
jne .done
+ pushad
mov ax,0003h ; Return to normal video mode
int 10h
; mov dx,TextColorReg ; Restore color registers
; mov ax,1002h
; int 10h
-
+ mov [UsingVGA], byte 0
call use_font ; Restore text font/data
mov byte [ScrollAttribute], 07h
-.done:
popad
+.done:
+
pop ds
ret
diff --git a/pxelinux.doc b/pxelinux.doc
index 96e95cbf..2ec710c1 100644
--- a/pxelinux.doc
+++ b/pxelinux.doc
@@ -235,20 +235,20 @@ PXELINUX (starting with version 1.62) supports the following
nonstandard DHCP options, which depending on your DHCP server you may
be able to use to customize the specific behaviour of PXELINUX:
-Option 176 pxelinux.magic
+Option 208 pxelinux.magic
- Must be set to F1:00:74:7E (241.0.116.126) for PXELINUX to
recognize any special DHCP options whatsoever.
-Option 177 pxelinux.configfile
+Option 209 pxelinux.configfile
- Specifies the PXELINUX configuration file name.
-Option 178 pxelinux.pathprefix
+Option 210 pxelinux.pathprefix
- Specifies the PXELINUX common path prefix, instead of
deriving it from the boot file name. This almost certainly
needs to end in whatever character the TFTP server OS uses
as a pathname separator, e.g. slash (/) for Unix.
-Option 179 pxelinux.reboottime
+Option 211 pxelinux.reboottime
- Specifies, in seconds, the time to wait before reboot in the
event of TFTP failure. 0 means wait "forever" (in reality,
it waits approximately 136 years.)
@@ -258,10 +258,10 @@ options; you can use the following syntax in dhcpd.conf if you are
running this version of dhcpd:
option space pxelinux;
- option pxelinux.magic code 176 = string;
- option pxelinux.configfile code 177 = text;
- option pxelinux.pathprefix code 178 = text;
- option pxelinux.reboottime code 179 = unsigned integer 32;
+ option pxelinux.magic code 208 = string;
+ option pxelinux.configfile code 209 = text;
+ option pxelinux.pathprefix code 210 = text;
+ option pxelinux.reboottime code 211 = unsigned integer 32;
Then, inside your PXELINUX-booting group or class (whereever you have
the PXELINUX-related options, such as the filename option), you can
@@ -272,12 +272,25 @@ add, for example:
option pxelinux.configfile "configs/common";
option pxelinux.pathprefix "/tftpboot/pxelinux/files/";
option pxelinux.reboottime 30;
+ option dhcp-parameter-request-list 1, 3, 208, 209, 210, 211;
filename "/tftpboot/pxelinux/pxelinux.bin";
Note that the configfile is relative to the pathprefix: this will look
for a config file called /tftpboot/pxelinux/files/configs/common on
the TFTP server.
+The "option dhcp-parameter-request-list" is unfortunately required,
+since the DHCP exchange happens before PXELINUX starts.
+Unfortunately at least DHCP 3.0rc2pl1 takes this as "send these
+options and no others", even when the client explicitly requests
+them. This can easily cause problems for your operating system; you
+may need to add additional options here. I'm afraid I don't have a
+neat and clean solution for this problem using existing software.
+Fixing it in PXELINUX would require a fairly large amount of
+additional code, since PXELINUX would be required to conduct its own
+DHCP exchange rather than getting the cached packet from the PXE
+stack.
+
Using ISC dhcp 3.0 you can create a lot of these strings on the fly.
For example, to use the hexadecimal form of the hardware address as
the configuration file name, you could do something like: