- Graphics fixes
authorhpa <hpa>
Tue, 24 Apr 2001 05:10:09 +0000 (05:10 +0000)
committerhpa <hpa>
Tue, 24 Apr 2001 05:10:09 +0000 (05:10 +0000)
- 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.

isolinux.asm
ldlinux.asm
memdisk.asm
memdisk/memdisk.asm
pxelinux.asm
pxelinux.doc

index 56d740b..f3f926b 100644 (file)
@@ -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
index 78329f8..50e5e29 100644 (file)
@@ -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
index aa95f9e..a690e66 100644 (file)
 
                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
-
-
index aa95f9e..a690e66 100644 (file)
 
                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
-
-
index 48696e3..f1d6158 100644 (file)
@@ -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
 
index 96e95cb..2ec710c 100644 (file)
@@ -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: