aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiu Aleaxander <Aleaxander@gmail.com>2009-07-26 11:51:09 +0800
committerLiu Aleaxander <Aleaxander@gmail.com>2009-07-26 11:51:09 +0800
commitf2cf077ea8b0c10427fc1342f0de797b3075be1c (patch)
tree47103ed76b105ebc06d0b61658f09b25aa665ae9
parent701346868953d8b130af114afe0fa20fd795c8cb (diff)
downloadpxelinux-f2cf077ea8b0c10427fc1342f0de797b3075be1c.tar.gz
pxelinux-f2cf077ea8b0c10427fc1342f0de797b3075be1c.tar.xz
pxelinux-f2cf077ea8b0c10427fc1342f0de797b3075be1c.zip
Core:PXELINUX: pxe_load_config converted
-rw-r--r--core/comboot.inc1
-rw-r--r--core/debug.c31
-rw-r--r--core/extern.inc4
-rw-r--r--core/getc.inc1
-rw-r--r--core/parsecmd.inc2
-rw-r--r--core/printf.c21
-rw-r--r--core/pxe.c155
-rw-r--r--core/pxelinux.asm103
8 files changed, 220 insertions, 98 deletions
diff --git a/core/comboot.inc b/core/comboot.inc
index 079b4761..ab5e33fe 100644
--- a/core/comboot.inc
+++ b/core/comboot.inc
@@ -1049,6 +1049,7 @@ err_notdos db ': attempted DOS system call INT ',0
err_comlarge db 'COMBOOT image too large.', CR, LF, 0
section .bss16
+ global ConfigName
alignb 4
DOSErrTramp resd 33 ; Error trampolines
ConfigName resb FILENAME_MAX
diff --git a/core/debug.c b/core/debug.c
index 346fa3f6..10571128 100644
--- a/core/debug.c
+++ b/core/debug.c
@@ -1,7 +1,34 @@
#include <stdio.h>
-
+#include <core.h>
void debug(void)
{
- printf("go there?\n");
+ printf("go there?\n");for(;;);
+}
+
+
+/*
+ * for debug use, dump the first 16 bytes from buf
+ */
+void dump16(void *buf)
+{
+ uint8_t *p = (uint8_t *)buf;
+ int i = 0;
+
+ for (; i < 16; i++)
+ printf("%02x ", *p++);
+
+ p = (uint8_t *)buf;
+ printf(" ");
+ for (i = 0; i < 16; i++)
+ printf("%c", *p++);
+ printf("\n");
+}
+
+void print_reg(com32sys_t *regs)
+{
+ printf(" DI: %p ", regs->edi.w[0]);
+ //dump16(regs->edi.w[0]);
+ printf(" eax:%p ", regs->eax.l);
+ printf(" ZF %s ", (regs->eflags.l & EFLAGS_ZF) ? "SET" : "CLEAR");
}
diff --git a/core/extern.inc b/core/extern.inc
index 34a1d092..b13aef39 100644
--- a/core/extern.inc
+++ b/core/extern.inc
@@ -15,9 +15,9 @@
; pxe.c
extern parse_dotquad, is_url, lchexbytes, uchexbytes, is_pxe, is_pxenv
extern memory_scan_for_pxe_struct, memory_scan_for_pxenv_struct
- extern gendotquad
+ extern gendotquad, pxe_load_config, try_load
; debug.c
- extern debug
+ extern debug, print_reg
%endif ; EXTERN_INC
diff --git a/core/getc.inc b/core/getc.inc
index a8d54c7f..82f1016e 100644
--- a/core/getc.inc
+++ b/core/getc.inc
@@ -60,6 +60,7 @@ getc_file_lg2 equ 4 ; Size of getc_file as a power of 2
;
; close: Output: CF set if nothing open
;
+ global open
open:
call searchdir
jz openfd.ret
diff --git a/core/parsecmd.inc b/core/parsecmd.inc
index 94627b8c..44895eae 100644
--- a/core/parsecmd.inc
+++ b/core/parsecmd.inc
@@ -122,10 +122,12 @@ FKeyName resb MAX_FKEYS*FILENAME_MAX ; File names for F-key help
KernelCNameLen resw 1 ; Length of unmangled kernel name
InitRDCNameLen resw 1 ; Length of unmangled initrd name
%if IS_SYSLINUX
+ global KernelName
KernelName resb FILENAME_MAX+1 ; Mangled name for kernel
KernelCName resb FILENAME_MAX+2 ; Unmangled kernel name
InitRDCName resb FILENAME_MAX+2 ; Unmangled initrd name
%else
+ global KernelName
KernelName resb FILENAME_MAX ; Mangled name for kernel
KernelCName resb FILENAME_MAX ; Unmangled kernel name
InitRDCName resb FILENAME_MAX ; Unmangled initrd name
diff --git a/core/printf.c b/core/printf.c
new file mode 100644
index 00000000..a05d0d7d
--- /dev/null
+++ b/core/printf.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <unistd.h>
+
+#include "core.h"
+
+extern void myputs(char *);
+int printf(const char *format, ...)
+{
+ char buf[1024];
+ va_list ap;
+ int rv;
+
+ va_start(ap, format);
+ rv = vsnprintf(buf, sizeof buf, format, ap);
+ va_end(ap);
+
+ myputs(buf);
+
+ return rv;
+
+}
diff --git a/core/pxe.c b/core/pxe.c
index 5d7321d8..a691cc6e 100644
--- a/core/pxe.c
+++ b/core/pxe.c
@@ -3,6 +3,10 @@
#include <core.h>
#include <pxe.h>
+
+#define FILENAME_MAX_LG2 7
+#define FILENAME_MAX (1 << FILENAME_MAX_LG2)
+
#define GPXE 1
#define is_digit(c) ((c >= '0') && (c <= '9'))
@@ -274,8 +278,155 @@ void gendotquad(com32sys_t *regs)
ip >>= 8;
}
-
- /* update ES:SI */
+ /* drop the last dot '.' and zero-terminate string*/
+ str --;
+ *str = 0;
+ /* update ES:DI */
regs->edi.w[0] = OFFS_WRT(str, 0);
}
+
+/********************************
+void genipopt(com32sys_t *regs)
+{
+ extern char IPOption[];
+ extern uint32_t MyIP;
+ extern uint32_t ServerIP;
+ extern uint32_t Gateway;
+ extern uint32_t Netmask;
+
+ char *p = IPOtion;
+
+ strcat(p, "ip=");
+ p += 3;
+
+ regs->edi.w[0] = p;
+ regs->eax.l = MyIP;
+ gendotquad(regs);
+ p = regs->edi.w[0];
+ *p++ = ':';
+
+ ............;
+}
+*********************************/
+
+ /**
+ * try to load a config file, if found, return 1, or return 0
+ *
+ */
+int try_load(com32sys_t *regs)
+{
+ extern void mangle_name();
+ extern void open();
+ extern void try();
+ extern char KernelName[];
+ char *config_name = (char *)(regs->edi.w[0]);
+ char *trying_msg = "Trying to load: ";
+
+ printf("%s%s ", trying_msg, config_name);
+
+ regs->esi.w[0] = OFFS_WRT(config_name, 0);
+ regs->edi.w[0] = OFFS_WRT(KernelName, 0);
+ call16(mangle_name, regs, regs);
+ call16(open, regs, regs);
+ if (regs->eflags.l & EFLAGS_ZF) {
+ printf(" [FAILED]\n");
+ return 0;
+ } else {
+ printf(" [OK ]\n");
+ return 1;
+ }
+}
+
+
+ /**
+ * load configuration file
+ *
+ */
+void pxe_load_config(com32sys_t *regs)
+{
+ extern char ConfigName[FILENAME_MAX];
+ extern char UUID[];
+ extern char MACStr[];
+ extern uint8_t DHCPMagic;
+ extern uint8_t MyIP[];
+ extern void no_config();
+ char *cfgprefix = "pxelinux.cfg/";
+ char *default_str = "default";
+ char *config_file;
+
+ int HaveUUID = 0;
+ uint8_t uuid_dashes[] = {4, 2, 2, 2, 6, 0};
+ uint8_t *uuid_ptr;
+
+ int tries = 8;
+ uint8_t *last;
+
+ if (DHCPMagic & 0x02) {
+ /* We got a DHCP option, try it first */
+ if (try_load(regs))
+ return;
+ }
+
+ memcpy(ConfigName, cfgprefix, strlen(cfgprefix));
+ config_file = ConfigName + strlen(cfgprefix);
+ /*
+ * Have to guess config file name ...
+ */
+
+ /* Try loading by UUID */
+ if (HaveUUID) {
+ uuid_ptr = uuid_dashes;
+ while (*uuid_ptr) {
+ regs->ecx.w[0] = *uuid_ptr;
+ regs->edi.w[0] = OFFS_WRT(config_file, 0);
+ regs->esi.w[0] = OFFS_WRT(UUID, 0);
+ lchexbytes(regs);
+ uuid_ptr++;
+ *(char *)(regs->edi.w[0]) = '-';
+ regs->edi.w[0] ++;
+ }
+ /* Remove last dash and zero-terminate */
+ *(char *)(regs->edi.w[0] - 1) = 0;
+ regs->edi.w[0] = OFFS_WRT(ConfigName, 0);
+ if (try_load(regs))
+ return;
+ }
+
+ /* Try loading by MAC address */
+ strcpy(config_file, MACStr);
+ regs->edi.w[0] = OFFS_WRT(ConfigName, 0);
+ if (try_load(regs))
+ return;
+
+#if 0
+ printf("MY IP: %p(%X)\n", MyIP, *(uint32_t *)MyIP);
+ #endif
+
+ /* Nope, try hexadecimal IP prefixes... */
+ regs->ecx.w[0] = 4;
+ regs->edi.w[0] = OFFS_WRT(config_file, 0);
+ regs->esi.w[0] = OFFS_WRT(MyIP, 0);
+ uchexbytes(regs); /* Convet to hex string */
+
+ last = (uint8_t *)(regs->edi.w[0]);
+ while (tries) {
+ *last = '\0'; /* Zero-terminate string */
+ regs->edi.w[0] = OFFS_WRT(ConfigName, 0);
+ if (try_load(regs))
+ return;
+ last--; /* Drop one character */
+ tries --;
+ };
+
+ /* Final attempt: "default" string */
+ strcpy(config_file, default_str);
+ regs->edi.w[0] = OFFS_WRT(ConfigName, 0);
+ if (try_load(regs))
+ return;
+
+ //call16(no_config, NULL, NULL);
+}
+
+
+
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index c713a509..792c7c61 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -178,6 +178,7 @@ InitStack resd 1 ; Pointer to reset stack (SS:SP)
PXEStack resd 1 ; Saved stack during PXE call
alignb 4
+ global DHCPMagic
RebootTime resd 1 ; Reboot timeout, if set by option
StrucPtr resd 1 ; Pointer to PXENV+ or !PXE structure
APIVer resw 1 ; PXE API version found
@@ -187,6 +188,7 @@ OverLoad resb 1 ; Set if DHCP packet uses "overloading"
DHCPMagic resb 1 ; PXELINUX magic flags
; The relative position of these fields matter!
+ global MACStr
MAC_MAX equ 32 ; Handle hardware addresses this long
MACLen resb 1 ; MAC address len
MACType resb 1 ; MAC address type
@@ -195,6 +197,7 @@ BOOTIFStr resb 7 ; Space for "BOOTIF="
MACStr resb 3*(MAC_MAX+1) ; MAC address as a string
; The relative position of these fields matter!
+ global UUID
UUIDType resb 1 ; Type byte from DHCP option
UUID resb 16 ; UUID, from the PXE stack
UUIDNull resb 1 ; dhcp_copyoption zero-terminates
@@ -674,98 +677,7 @@ prefix: test byte [DHCPMagic], 04h ; Did we get a path prefix option
;
; Load configuration file
;
-find_config:
-
-;
-; Begin looking for configuration file
-;
-config_scan:
- test byte [DHCPMagic], 02h
- jz .no_option
-
- ; We got a DHCP option, try it first
- call .try
- jnz .success
-
-.no_option:
- mov di,ConfigName
- mov si,cfgprefix
- mov cx,cfgprefix_len
- rep movsb
-
- ; Have to guess config file name...
-
- ; Try loading by UUID.
- cmp byte [HaveUUID],0
- je .no_uuid
-
- push di
- mov bx,uuid_dashes
- mov si,UUID
-.gen_uuid:
- movzx cx,byte [bx]
- jcxz .done_uuid
- inc bx
- pm_call lchexbytes
- mov al,'-'
- stosb
- jmp .gen_uuid
-.done_uuid:
- mov [di-1],cl ; Remove last dash and zero-terminate
- pop di
- call .try
- jnz .success
-.no_uuid:
-
- ; Try loading by MAC address
- push di
- mov si,MACStr
- call strcpy
- pop di
- call .try
- jnz .success
-
- ; Nope, try hexadecimal IP prefixes...
-.scan_ip:
- mov cx,4
- mov si,MyIP
- pm_call uchexbytes ; Convert to hex string
-
- mov cx,8 ; Up to 8 attempts
-.tryagain:
- mov byte [di],0 ; Zero-terminate string
- call .try
- jnz .success
- dec di ; Drop one character
- loop .tryagain
-
- ; Final attempt: "default" string
- mov si,default_str ; "default" string
- call strcpy
- call .try
- jnz .success
-
- mov si,err_noconfig
- call writestr_early
- jmp kaboom
-
-.try:
- pusha
- mov si,trying_msg
- call writestr_early
- mov di,ConfigName
- mov si,di
- call writestr_early
- call crlf
- mov si,di
- mov di,KernelName ; Borrow this buffer for mangled name
- call mangle_name
- call open
- popa
- ret
-
-
-.success:
+ pm_call pxe_load_config
;
; Linux kernel loading code is common. However, we need to define
@@ -814,6 +726,11 @@ local_boot:
; kaboom: write a message and bail out. Wait for quite a while,
; or a user keypress, then do a hard reboot.
;
+ global no_config
+; set the no_config kaboom here
+no_config:
+ mov si, err_noconfig
+ call writestr_early
kaboom:
RESET_STACK_AND_SEGS AX
.patch: mov si,bailmsg
@@ -1351,6 +1268,7 @@ HasGPXE db -1 ; Unknown
;
; No segment assumptions permitted.
;
+ global mangle_name
mangle_name:
push di
%if GPXE
@@ -2511,6 +2429,7 @@ ack_packet_buf: dw TFTP_ACK, 0 ; TFTP ACK packet
;
; IP information (initialized to "unknown" values)
+ global MyIP
MyIP dd 0 ; My IP address
ServerIP dd 0 ; IP address of boot server
Netmask dd 0 ; Netmask of this subnet