From: hpa Date: Tue, 24 Apr 2001 05:10:09 +0000 (+0000) Subject: - Graphics fixes X-Git-Tag: syslinux-3.11~832 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f596388e20cde977bbdfc13c827592ff5107f1f6;p=platform%2Fupstream%2Fsyslinux.git - Graphics fixes - 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. --- diff --git a/isolinux.asm b/isolinux.asm index 56d740b..f3f926b 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 78329f8..50e5e29 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 aa95f9e..a690e66 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 aa95f9e..a690e66 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 48696e3..f1d6158 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 96e95cb..2ec710c 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: