diff options
author | H. Peter Anvin <hpa@zytor.com> | 2010-06-18 18:45:02 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-06-18 18:45:02 -0700 |
commit | 7c890f5a328f6f0fc7e293247cbbcb18d369c447 (patch) | |
tree | 0f0a2a13578c9aeecba8d0fcf2f88d33309db450 | |
parent | e554f2fadd8d7a79a0f84707e545c31997c93528 (diff) | |
parent | c81d67125d108a5e76039ac6ebaf5b24bca7c107 (diff) | |
download | syslinux-7c890f5a328f6f0fc7e293247cbbcb18d369c447.tar.gz |
Merge branch 'pathbased' of ssh://terminus.zytor.com/pub/git/syslinux/syslinux into pathbasedsyslinux-4.00-pre50
-rw-r--r-- | com32/include/syslinux/config.h | 9 | ||||
-rw-r--r-- | com32/sysdump/acpi.c | 175 | ||||
-rw-r--r-- | com32/sysdump/be_tftp.c | 27 | ||||
-rw-r--r-- | com32/sysdump/main.c | 1 | ||||
-rw-r--r-- | com32/sysdump/memmap.c | 6 | ||||
-rw-r--r-- | com32/sysdump/sysdump.h | 1 | ||||
-rw-r--r-- | com32/sysdump/vesa.c | 7 | ||||
-rw-r--r-- | core/comboot.inc | 4 | ||||
-rw-r--r-- | core/fs/pxe/dhcp_option.c | 12 | ||||
-rw-r--r-- | core/fs/pxe/dnsresolv.c | 4 | ||||
-rw-r--r-- | core/fs/pxe/idle.c | 2 | ||||
-rw-r--r-- | core/fs/pxe/pxe.c | 42 | ||||
-rw-r--r-- | core/fs/pxe/pxe.h | 29 | ||||
-rw-r--r-- | core/pxelinux.asm | 14 | ||||
-rw-r--r-- | doc/comboot.txt | 8 |
15 files changed, 289 insertions, 52 deletions
diff --git a/com32/include/syslinux/config.h b/com32/include/syslinux/config.h index 868b0f10..60d8d231 100644 --- a/com32/include/syslinux/config.h +++ b/com32/include/syslinux/config.h @@ -54,6 +54,14 @@ struct syslinux_version { const char *copyright_string; }; +struct syslinux_ipinfo { + uint32_t ipver; + uint32_t myip; + uint32_t netmask; + uint32_t gateway; + uint32_t serverip; +}; + extern __nocommon struct syslinux_version __syslinux_version; static inline const struct syslinux_version *syslinux_version(void) { @@ -116,6 +124,7 @@ union syslinux_derivative_info { uint32_t _eflags; const void *pxenvptr; const void *stack; + const struct syslinux_ipinfo *ipinfo; } pxe; /* pxelinux */ struct { uint16_t _gs, _fs, _es, _ds; diff --git a/com32/sysdump/acpi.c b/com32/sysdump/acpi.c new file mode 100644 index 00000000..48b890ae --- /dev/null +++ b/com32/sysdump/acpi.c @@ -0,0 +1,175 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2010 Intel Corporation; author: H. Peter Anvin + * + * 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., 51 Franklin St, Fifth Floor, + * Boston MA 02110-1301, USA; either version 2 of the License, or + * (at your option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* + * Dump ACPI information + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "sysdump.h" +#include "backend.h" + +struct acpi_rsdp { + uint8_t magic[8]; /* "RSD PTR " */ + uint8_t csum; + char oemid[6]; + uint8_t rev; + uint32_t rsdt_addr; + uint32_t len; + uint64_t xdst_addr; + uint8_t xcsum; + uint8_t rsvd[3]; +}; + +struct acpi_hdr { + char sig[4]; /* Signature */ + uint32_t len; + uint8_t rev; + uint8_t csum; + char oemid[6]; + char oemtblid[16]; + uint32_t oemrev; + uint32_t creatorid; + uint32_t creatorrev; +}; + +struct acpi_rsdt { + struct acpi_hdr hdr; + uint32_t entry[0]; +}; + +enum tbl_errs { + ERR_NONE, /* No errors */ + ERR_CSUM, /* Invalid checksum */ + ERR_SIZE, /* Impossibly large table */ + ERR_NOSIG /* No signature */ +}; + +static uint8_t checksum_range(const void *start, uint32_t size) +{ + const uint8_t *p = start; + uint8_t csum = 0; + + while (size--) + csum += *p++; + + return csum; +} + +static enum tbl_errs is_valid_table(const void *ptr) +{ + const struct acpi_hdr *hdr = ptr; + + if (hdr->sig[0] == 0) + return ERR_NOSIG; + + if (hdr->len < 10 || hdr->len > (1 << 20)) { + /* Either insane or too large to dump */ + return ERR_SIZE; + } + + return checksum_range(hdr, hdr->len) == 0 ? ERR_NONE : ERR_CSUM; +} + +static const struct acpi_rsdp *scan_for_rsdp(uint32_t base, uint32_t end) +{ + for (base &= ~15; base < end-20; base += 16) { + const struct acpi_rsdp *rsdp = (const struct acpi_rsdp *)base; + + if (memcmp(rsdp->magic, "RSD PTR ", 8)) + continue; + + if (checksum_range(rsdp, 20)) + continue; + + if (rsdp->rev > 0) { + if (base + rsdp->len >= end || + checksum_range(rsdp, rsdp->len)) + continue; + } + + return rsdp; + } + + return NULL; +} + +static const struct acpi_rsdp *find_rsdp(void) +{ + uint32_t ebda; + const struct acpi_rsdp *rsdp; + + ebda = (*(uint16_t *)0x40e) << 4; + if (ebda >= 0x70000 && ebda < 0xa0000) { + rsdp = scan_for_rsdp(ebda, ebda+1024); + + if (rsdp) + return rsdp; + } + + return scan_for_rsdp(0xe0000, 0x100000); +} + +static void dump_table(struct backend *be, + const char name[], const void *ptr, uint32_t len) +{ + char namebuf[64]; + + /* XXX: this make cause the same directory to show up more than once */ + snprintf(namebuf, sizeof namebuf, "acpi/%4.4s", name); + cpio_mkdir(be, namebuf); + + snprintf(namebuf, sizeof namebuf, "acpi/%4.4s/%08x", name, (uint32_t)ptr); + cpio_hdr(be, MODE_FILE, len, namebuf); + + write_data(be, ptr, len); +} + +void dump_acpi(struct backend *be) +{ + const struct acpi_rsdp *rsdp; + const struct acpi_rsdt *rsdt; + uint32_t rsdp_len; + uint32_t i, n; + + rsdp = find_rsdp(); + + if (!rsdp) + return; /* No ACPI information found */ + + cpio_mkdir(be, "acpi"); + + rsdp_len = rsdp->rev > 0 ? rsdp->len : 20; + + dump_table(be, "RSDP", rsdp, rsdp_len); + + rsdt = (const struct acpi_rsdt *)rsdp->rsdt_addr; + + if (memcmp(rsdt->hdr.sig, "RSDT", 4) || is_valid_table(rsdt) != ERR_NONE) + return; + + dump_table(be, rsdt->hdr.sig, rsdt, rsdt->hdr.len); + + if (rsdt->hdr.len < 36) + return; + + n = (rsdt->hdr.len - 36) >> 2; + + for (i = 0; i < n; i++) { + const struct acpi_hdr *hdr = (const struct acpi_hdr *)(rsdt->entry[i]); + + if (is_valid_table(hdr) <= ERR_CSUM) + dump_table(be, hdr->sig, hdr, hdr->len); + } +} diff --git a/com32/sysdump/be_tftp.c b/com32/sysdump/be_tftp.c index 07fdb084..8c92d4d6 100644 --- a/com32/sysdump/be_tftp.c +++ b/com32/sysdump/be_tftp.c @@ -21,23 +21,30 @@ enum tftp_opcode { struct tftp_state { uint32_t my_ip; uint32_t srv_ip; + uint32_t srv_gw; uint16_t my_port; uint16_t srv_port; uint16_t seq; }; +#define RCV_BUF 2048 + static int send_ack_packet(struct tftp_state *tftp, const void *pkt, size_t len) { com32sys_t ireg, oreg; - t_PXENV_UDP_WRITE *uw = __com32.cs_bounce; - t_PXENV_UDP_READ *ur = __com32.cs_bounce; + t_PXENV_UDP_WRITE *uw; + t_PXENV_UDP_READ *ur; clock_t start; static const clock_t timeouts[] = { 2, 2, 3, 3, 4, 5, 6, 7, 9, 10, 12, 15, 18, 21, 26, 31, 37, 44, 53, 64, 77, 92, 110, 132, 159, 191, 229, 0 }; const clock_t *timeout; + int err = -1; + + uw = lmalloc(sizeof *uw + len); + ur = lmalloc(sizeof *ur + RCV_BUF); memset(&ireg, 0, sizeof ireg); ireg.eax.w[0] = 0x0009; @@ -46,6 +53,7 @@ static int send_ack_packet(struct tftp_state *tftp, memset(uw, 0, sizeof uw); memcpy(uw+1, pkt, len); uw->ip = tftp->srv_ip; + uw->gw = tftp->srv_gw; uw->src_port = tftp->my_port; uw->dst_port = tftp->srv_port ? tftp->srv_port : htons(69); uw->buffer_size = len; @@ -65,7 +73,7 @@ static int send_ack_packet(struct tftp_state *tftp, ur->dest_ip = tftp->my_ip; ur->s_port = tftp->srv_port; ur->d_port = tftp->my_port; - ur->buffer_size = __com32.cs_bounce_size - sizeof *ur; + ur->buffer_size = RCV_BUF; ur->buffer = FAR_PTR(ur+1); ireg.ebx.w[0] = PXENV_UDP_READ; @@ -82,15 +90,20 @@ static int send_ack_packet(struct tftp_state *tftp, if (ntohs(xb[0]) == TFTP_ACK && ntohs(xb[1]) == tftp->seq) { tftp->srv_port = ur->s_port; - return 0; /* All good! */ + err = 0; /* All good! */ + goto done; } else if (ntohs(xb[1]) == TFTP_ERROR) { - return -1; /* All bad! */ + goto done; } } } while ((clock_t)(times(NULL) - start) < *timeout); } - return -1; /* No success... */ +done: + lfree(ur); + lfree(uw); + + return err; } static int be_tftp_write(struct backend *be) @@ -108,6 +121,8 @@ static int be_tftp_write(struct backend *be) tftp.my_ip = sdi->pxe.myip; tftp.my_port = htons(local_port++); tftp.srv_ip = pxe_dns(be->argv[1]); + tftp.srv_gw = ((tftp.srv_ip ^ tftp.my_ip) & sdi->pxe.ipinfo->netmask) + ? sdi->pxe.ipinfo->gateway : 0; tftp.srv_port = 0; tftp.seq = 0; diff --git a/com32/sysdump/main.c b/com32/sysdump/main.c index d4a0320e..26f562be 100644 --- a/com32/sysdump/main.c +++ b/com32/sysdump/main.c @@ -41,6 +41,7 @@ static void dump_all(struct backend *be, const char *argv[]) dump_memory_map(be); dump_memory(be); dump_dmi(be); + dump_acpi(be); dump_cpuid(be); dump_pci(be); dump_vesa_tables(be); diff --git a/com32/sysdump/memmap.c b/com32/sysdump/memmap.c index a85f0925..251107d5 100644 --- a/com32/sysdump/memmap.c +++ b/com32/sysdump/memmap.c @@ -19,10 +19,12 @@ struct e820_info { static void dump_e820(struct backend *be) { com32sys_t ireg, oreg; - struct e820_info *curr = __com32.cs_bounce; + struct e820_info *curr; struct e820_info *buf, *p; int nentry, nalloc; + curr = lmalloc(sizeof *curr); + buf = p = NULL; nentry = nalloc = 0; memset(&ireg, 0, sizeof ireg); @@ -56,7 +58,9 @@ static void dump_e820(struct backend *be) if (nentry) cpio_writefile(be, "memmap/15e820", buf, nentry*sizeof *buf); + free(buf); + lfree(curr); } void dump_memory_map(struct backend *be) diff --git a/com32/sysdump/sysdump.h b/com32/sysdump/sysdump.h index 61a04a2b..a5b963f8 100644 --- a/com32/sysdump/sysdump.h +++ b/com32/sysdump/sysdump.h @@ -7,6 +7,7 @@ void dump_memory_map(struct backend *); void snapshot_lowmem(void); void dump_memory(struct backend *); void dump_dmi(struct backend *); +void dump_acpi(struct backend *); void dump_cpuid(struct backend *); void dump_pci(struct backend *); void dump_vesa_tables(struct backend *); diff --git a/com32/sysdump/vesa.c b/com32/sysdump/vesa.c index 9bdc7153..017f9e4f 100644 --- a/com32/sysdump/vesa.c +++ b/com32/sysdump/vesa.c @@ -7,6 +7,7 @@ void dump_vesa_tables(struct backend *be) { com32sys_t rm; + struct vesa_info *vip; struct vesa_general_info *gip, gi; struct vesa_mode_info *mip, mi; uint16_t mode, *mode_ptr; @@ -15,8 +16,9 @@ void dump_vesa_tables(struct backend *be) printf("Scanning VESA BIOS... "); /* Allocate space in the bounce buffer for these structures */ - gip = &((struct vesa_info *)__com32.cs_bounce)->gi; - mip = &((struct vesa_info *)__com32.cs_bounce)->mi; + vip = lmalloc(sizeof *vip); + gip = &vip->gi; + mip = &vip->mi; memset(&rm, 0, sizeof rm); memset(gip, 0, sizeof *gip); @@ -56,5 +58,6 @@ void dump_vesa_tables(struct backend *be) cpio_writefile(be, modefile, &mi, sizeof mi); } + lfree(vip); printf("done.\n"); } diff --git a/core/comboot.inc b/core/comboot.inc index 45b770f3..0c9956a0 100644 --- a/core/comboot.inc +++ b/core/comboot.inc @@ -580,8 +580,10 @@ comapi_derinfo: mov P_SI,ax mov ax,[InitStack+2] mov P_FS,ax - mov eax,[MyIP] + mov eax,[IPInfo.MyIP] mov P_ECX,eax + mov P_GS,0 + mov P_DI,IPInfo %else ; Physical medium... diff --git a/core/fs/pxe/dhcp_option.c b/core/fs/pxe/dhcp_option.c index e18b605d..39b51666 100644 --- a/core/fs/pxe/dhcp_option.c +++ b/core/fs/pxe/dhcp_option.c @@ -16,14 +16,14 @@ static void subnet_mask(void *data, int opt_len) { if (opt_len != 4) return; - net_mask = *(uint32_t *)data; + IPInfo.netmask = *(uint32_t *)data; } static void router(void *data, int opt_len) { if (opt_len != 4) return; - gate_way = *(uint32_t *)data; + IPInfo.gateway = *(uint32_t *)data; } static void dns_servers(void *data, int opt_len) @@ -83,12 +83,12 @@ static void server(void *data, int opt_len) if (opt_len != 4) return; - if (server_ip) + if (IPInfo.serverip) return; ip = *(uint32_t *)data; if (ip_ok(ip)) - server_ip = ip; + IPInfo.serverip = ip; } static void client_identifier(void *data, int opt_len) @@ -246,10 +246,10 @@ void parse_dhcp(int pkt_len) over_load = 0; if (ip_ok(dhcp->yip)) - MyIP = dhcp->yip; + IPInfo.myip = dhcp->yip; if (ip_ok(dhcp->sip)) - server_ip = dhcp->sip; + IPInfo.serverip = dhcp->sip; opt_len = (char *)dhcp + pkt_len - (char *)&dhcp->options; if (opt_len && (dhcp->option_magic == BOOTP_OPTION_MAGIC)) diff --git a/core/fs/pxe/dnsresolv.c b/core/fs/pxe/dnsresolv.c index df7f33c1..134f24e3 100644 --- a/core/fs/pxe/dnsresolv.c +++ b/core/fs/pxe/dnsresolv.c @@ -229,7 +229,7 @@ uint32_t dns_resolv(const char *name) continue; /* just move on before runing the time out */ udp_write.status = 0; udp_write.ip = srv; - udp_write.gw = ((srv ^ MyIP) & net_mask) ? gate_way : 0; + udp_write.gw = gateway(srv); udp_write.src_port = local_port; udp_write.dst_port = DNS_PORT; udp_write.buffer_size = p - DNSSendBuf; @@ -242,7 +242,7 @@ uint32_t dns_resolv(const char *name) while (1) { udp_read.status = 0; udp_read.src_ip = srv; - udp_read.dest_ip = MyIP; + udp_read.dest_ip = IPInfo.myip; udp_read.s_port = DNS_PORT; udp_read.d_port = local_port; udp_read.buffer_size = DNS_MAX_PACKET; diff --git a/core/fs/pxe/idle.c b/core/fs/pxe/idle.c index 0538b163..52a87c34 100644 --- a/core/fs/pxe/idle.c +++ b/core/fs/pxe/idle.c @@ -27,7 +27,7 @@ static int pxe_idle_poll(void) memset(&read_buf, 0, sizeof read_buf); read_buf.src_ip = 0; /* Any destination */ - read_buf.dest_ip = MyIP; + read_buf.dest_ip = IPInfo.myip; read_buf.s_port = 0; /* Any source port */ read_buf.d_port = htons(9); /* Discard port (not used...) */ read_buf.buffer_size = sizeof junk_pkt; diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c index 011ef293..ef2398b4 100644 --- a/core/fs/pxe/pxe.c +++ b/core/fs/pxe/pxe.c @@ -9,10 +9,7 @@ #define GPXE 1 -uint32_t server_ip = 0; /* IP address of boot server */ -uint32_t net_mask = 0; /* net_mask of this subnet */ -uint32_t gate_way = 0; /* Default router */ -uint16_t real_base_mem; /* Amount of DOS memory after freeing */ +static uint16_t real_base_mem; /* Amount of DOS memory after freeing */ uint8_t MAC[MAC_MAX]; /* Actual MAC address */ uint8_t MAC_len; /* MAC address len */ @@ -297,7 +294,7 @@ static void tftp_error(struct inode *inode, uint16_t errnum, udp_write.src_port = socket->tftp_localport; udp_write.dst_port = socket->tftp_remoteport; udp_write.ip = socket->tftp_remoteip; - udp_write.gw = ((udp_write.ip ^ MyIP) & net_mask) ? gate_way : 0; + udp_write.gw = gateway(udp_write.ip); udp_write.buffer = FAR_PTR(&err_buf); udp_write.buffer_size = 4 + len + 1; @@ -326,7 +323,7 @@ static void ack_packet(struct inode *inode, uint16_t ack_num) udp_write.src_port = socket->tftp_localport; udp_write.dst_port = socket->tftp_remoteport; udp_write.ip = socket->tftp_remoteip; - udp_write.gw = ((udp_write.ip ^ MyIP) & net_mask) ? gate_way : 0; + udp_write.gw = gateway(udp_write.ip); udp_write.buffer = FAR_PTR(ack_packet_buf); udp_write.buffer_size = 4; @@ -513,7 +510,7 @@ static void fill_buffer(struct inode *inode) udp_read.buffer = FAR_PTR(packet_buf); udp_read.buffer_size = PKTBUF_SIZE; udp_read.src_ip = socket->tftp_remoteip; - udp_read.dest_ip = MyIP; + udp_read.dest_ip = IPInfo.myip; udp_read.s_port = socket->tftp_remoteport; udp_read.d_port = socket->tftp_localport; err = pxe_call(PXENV_UDP_READ, &udp_read); @@ -688,12 +685,12 @@ static void pxe_searchdir(const char *filename, struct file *file) case PXE_RELATIVE: /* Really shouldn't happen... */ case PXE_URL: buf = stpcpy(buf, filename); - ip = server_ip; /* Default server */ + ip = IPInfo.serverip; /* Default server */ break; case PXE_HOMESERVER: buf = stpcpy(buf, filename+2); - ip = server_ip; + ip = IPInfo.serverip; break; case PXE_TFTP: @@ -781,7 +778,7 @@ sendreq: tid = socket->tftp_localport; /* TID(local port No) */ udp_write.buffer = FAR_PTR(rrq_packet_buf); udp_write.ip = ip; - udp_write.gw = ((udp_write.ip ^ MyIP) & net_mask) ? gate_way : 0; + udp_write.gw = gateway(udp_write.ip); udp_write.src_port = tid; udp_write.dst_port = server_port; udp_write.buffer_size = buf - rrq_packet_buf; @@ -794,7 +791,7 @@ wait_pkt: buf = packet_buf; udp_read.buffer = FAR_PTR(buf); udp_read.buffer_size = PKTBUF_SIZE; - udp_read.dest_ip = MyIP; + udp_read.dest_ip = IPInfo.myip; udp_read.d_port = tid; err = pxe_call(PXENV_UDP_READ, &udp_read); if (err) { @@ -1107,7 +1104,7 @@ static int pxe_load_config(void) return 0; /* Nope, try hexadecimal IP prefixes... */ - uchexbytes(config_file, (uint8_t *)&MyIP, 4); /* Convet to hex string */ + uchexbytes(config_file, (uint8_t *)&IPInfo.myip, 4); /* Convet to hex string */ last = &config_file[8]; while (tries) { *last = '\0'; /* Zero-terminate string */ @@ -1151,26 +1148,23 @@ char __bss16 IPOption[3+4*16]; static void genipopt(void) { char *p = IPOption; + const uint32_t *v = &IPInfo.myip; + int i; p = stpcpy(p, "ip="); - p += gendotquad(p, MyIP); - *p++ = ':'; - - p += gendotquad(p, server_ip); - *p++ = ':'; - - p += gendotquad(p, gate_way); - *p++ = ':'; - - gendotquad(p, net_mask); + for (i = 0; i < 4; i++) { + p += gendotquad(p, *v++); + *p++ = ':'; + } + *--p = '\0'; } /* Generate ip= option and print the ip adress */ static void ip_init(void) { - uint32_t ip = MyIP; + uint32_t ip = IPInfo.myip; genipopt(); gendotquad(dot_quad_buf, ip); @@ -1412,7 +1406,7 @@ static void udp_init(void) { int err; static __lowmem struct s_PXENV_UDP_OPEN udp_open; - udp_open.src_ip = MyIP; + udp_open.src_ip = IPInfo.myip; err = pxe_call(PXENV_UDP_OPEN, &udp_open); if (err || udp_open.status) { printf("Failed to initialize UDP stack "); diff --git a/core/fs/pxe/pxe.h b/core/fs/pxe/pxe.h index e801aea5..cad63507 100644 --- a/core/fs/pxe/pxe.h +++ b/core/fs/pxe/pxe.h @@ -170,13 +170,20 @@ struct pxe_pvt_inode { #define PVT(i) ((struct pxe_pvt_inode *)((i)->pvt)) /* + * Network boot information + */ +struct ip_info { + uint32_t ipv4; + uint32_t myip; + uint32_t serverip; + uint32_t gateway; + uint32_t netmask; +}; + +/* * Variable externs */ -extern uint32_t server_ip; -extern uint32_t MyIP; -extern uint32_t net_mask; -extern uint32_t gate_way; -extern uint16_t server_port; +extern struct ip_info IPInfo; extern uint8_t MAC[]; extern char BOOTIFStr[]; @@ -195,7 +202,6 @@ extern char dot_quad_buf[]; extern uint32_t dns_server[]; -extern uint16_t real_base_mem; extern uint16_t APIVer; extern far_ptr_t PXEEntry; extern uint8_t KeepPXE; @@ -209,6 +215,17 @@ extern char uuid[]; extern uint16_t BIOS_fbm; extern const uint8_t TimeoutTable[]; +/* + * Compute the suitable gateway for a specific route -- too many + * vendor PXE stacks don't do this correctly... + */ +static inline uint32_t gateway(uint32_t ip) +{ + if ((ip ^ IPInfo.myip) & IPInfo.netmask) + return IPInfo.gateway; + else + return 0; +} /* * functions diff --git a/core/pxelinux.asm b/core/pxelinux.asm index 0b87e735..6fb77c25 100644 --- a/core/pxelinux.asm +++ b/core/pxelinux.asm @@ -530,7 +530,15 @@ exten_table_end: KeepPXE db 0 ; Should PXE be kept around? ; -; IP information (initialized to "unknown" values) +; IP information. Note that the field are in the same order as the +; Linux kernel expects in the ip= option. +; + section .bss16 alignz 4 - global MyIP -MyIP dd 0 ; My IP address + global IPInfo +IPInfo: +.IPv4 resd 1 ; IPv4 information +.MyIP resd 1 ; My IP address +.ServerIP resd 1 +.GatewayIP resd 1 +.Netmask resd 1 diff --git a/doc/comboot.txt b/doc/comboot.txt index f39d7243..036bd784 100644 --- a/doc/comboot.txt +++ b/doc/comboot.txt @@ -448,6 +448,7 @@ AX=000Ah [2.00] Get Derivative-Specific Information ECX Local IP number (network byte order) [3.85] ES:BX pointer to PXENV+ or !PXE structure FS:SI pointer to original stack with invocation record + GS:DI pointer to network information [4.00] Note: DX notes the API version detected by PXELINUX, which may be more conservative than the actual version @@ -481,6 +482,13 @@ AX=000Ah [2.00] Get Derivative-Specific Information [fs:si+44] PXE return IP <- t.o.s. when PXELINUX invoked [fs:si+46] PXE return CS + GS:DI points to a structure of the following form: + + [gs:di+0] 4 - IPv4 + [gs:di+4] My IP + [gs:di+8] Boot server IP + [gs:di+12] Gateway IP + [gs:di+16] Netmask [ISOLINUX] Input: AX 000Ah |