diff --git a/core/fs/pxe/dnsresolv.c b/core/fs/pxe/dnsresolv.c
index b2c36b7..4fb7bef 100644
--- a/core/fs/pxe/dnsresolv.c
+++ b/core/fs/pxe/dnsresolv.c
@@ -53,9 +53,10 @@ uint32_t dns_server[DNS_MAX_SERVERS] = {0, };
  * Turn a string in _src_ into a DNS "label set" in _dst_; returns the 
  * number of dots encountered. On return, *dst is updated.
  */
-int dns_mangle(char **dst, const char *p)
+int dns_mangle(char **dst, const char **src)
 {
     char *q = *dst;
+    const char *p = *src;
     char *count_ptr;
     char c;
     int dots = 0;    
@@ -82,6 +83,7 @@ int dns_mangle(char **dst, const char *p)
         *q++ = 0;
 
     /* update the strings */
+    *src = p;
     *dst = q;
     return dots;
 }
@@ -169,7 +171,7 @@ static char *dns_skiplabel(char *label)
  * If _ip_ = 0 on exit, the lookup failed. _name_ will be updated
  *
  */
-uint32_t dns_resolv(const char *name)
+uint32_t dns_resolv(const char **name)
 {
     char *p;
     int err;
@@ -223,8 +225,7 @@ uint32_t dns_resolv(const char *name)
         uw_pkt.lport      = DNS_LOCAL_PORT;
         uw_pkt.rport      = DNS_PORT;
         uw_pkt.buffersize = p - DNSSendBuf;
-        uw_pkt.buffer[0]  = OFFS_WRT(DNSSendBuf, 0);
-        uw_pkt.buffer[1]  = 0;
+        uw_pkt.buffer     = FAR_PTR(DNSSendBuf);
         err = pxe_call(PXENV_UDP_WRITE, &uw_pkt);
         if (err || uw_pkt.status != 0)
             continue;
@@ -237,8 +238,7 @@ uint32_t dns_resolv(const char *name)
             ur_pkt.rport      = DNS_PORT;
             ur_pkt.lport      = DNS_LOCAL_PORT;
             ur_pkt.buffersize = DNS_MAX_PACKET;
-            ur_pkt.buffer[0]  = OFFS_WRT(DNSRecvBuf, 0);
-            ur_pkt.buffer[1]  = 0;
+            ur_pkt.buffer     = FAR_PTR(DNSRecvBuf);
             err = pxe_call(PXENV_UDP_READ, &ur_pkt);
             if (err || ur_pkt.status)
                 continue;
@@ -335,5 +335,5 @@ void pxe_dns_resolv(com32sys_t *regs)
 {
     const char *name = MK_PTR(regs->ds, regs->esi.w[0]);
 
-    regs->eax.l = dns_resolv(name);
+    regs->eax.l = dns_resolv(&name);
 }
diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c
index 87d03eb..55c29a2 100644
--- a/core/fs/pxe/pxe.c
+++ b/core/fs/pxe/pxe.c
@@ -29,6 +29,9 @@ static const struct tftp_options tftp_options[] =
 };
 static const int tftp_nopts = sizeof tftp_options / sizeof tftp_options[0];
 
+/* Buffer for a single packet */
+static __lowmem char packet_buf[PKTBUF_SIZE];
+
 /*
  * Initialize the Files structure
  */
@@ -36,13 +39,10 @@ static void files_init(void)
 {
     int i;
     struct open_file_t *socket = Files;
-    uint16_t pktbuf = 0;
     uint16_t nextport = 49152;
 
     for (i = 0; i < MAX_OPEN; i++) {
-	socket->tftp_pktbuf = pktbuf;
 	socket->tftp_nextport = nextport;
-	pktbuf += PKTBUF_SIZE;
 	nextport++;
 	socket++;
     }
@@ -85,7 +85,7 @@ static struct open_file_t *allocate_socket(void)
  */
 static void free_socket(struct open_file_t *file)
 {
-    /* tftp_nextport and tftp_pktbuf are not cleared */
+    /* tftp_nextport and tftp_packet are not cleared */
     memset(file, 0, offsetof(struct open_file_t, tftp_nextport));
 }
 
@@ -263,8 +263,7 @@ static void ack_packet(struct open_file_t *file, uint16_t ack_num)
     uw_pkt.rport      = file->tftp_remoteport;
     uw_pkt.sip        = file->tftp_remoteip;
     uw_pkt.gip        = ((uw_pkt.sip ^ MyIP) & Netmask) ? Gateway : 0;
-    uw_pkt.buffer[0]  = OFFS_WRT(ack_packet_buf, 0);
-    uw_pkt.buffer[1]  = 0;    /* seems SEG and OFFS stuff doesn't work here */
+    uw_pkt.buffer     = FAR_PTR(ack_packet_buf);
     uw_pkt.buffersize = 4;
 
     err = pxe_call(PXENV_UDP_WRITE, &uw_pkt);
@@ -290,8 +289,7 @@ static int pxe_get_cached_info(int type)
     bq_pkt.status     = 0;
     bq_pkt.packettype = type;
     bq_pkt.buffersize = 8192;
-    bq_pkt.buffer[0]  = OFFS_WRT(trackbuf, 0);
-    bq_pkt.buffer[1]  = 0;    
+    bq_pkt.buffer     = FAR_PTR(trackbuf);
     err = pxe_call(PXENV_GET_CACHED_INFO, &bq_pkt);
     if (err) {
         printf("PXE API call failed, error  %04x\n", err);
@@ -366,8 +364,7 @@ static void get_packet_gpxe(struct open_file_t *file)
  
     while (1) {
         fr.filehandle = file->tftp_remoteport;
-        fr.buffer[0]  = file->tftp_pktbuf;
-        fr.buffer[1]  = PKTBUF_SEG;
+        fr.buffer     = FAR_PTR(packet_buf);
         fr.buffersize = PKTBUF_SIZE;
         err = pxe_call(PXENV_FILE_READ, &fr);
         if (!err)  /* successed */
@@ -377,6 +374,9 @@ static void get_packet_gpxe(struct open_file_t *file)
 	    kaboom();
     }
 
+    memcpy(file->tftp_packet, packet_buf, fr.buffersize);
+
+    file->tftp_dataptr   = file->tftp_packet;
     file->tftp_bytesleft = fr.buffersize;
     file->tftp_filepos  += fr.buffersize;
     
@@ -516,8 +516,7 @@ static void fill_buffer(struct open_file_t *file)
     timeout = *timeout_ptr++;
     old_time = BIOS_timer;
     while (timeout) {
-        pkt.buffer[0]  = file->tftp_pktbuf;
-        pkt.buffer[1]  = PKTBUF_SEG;
+        pkt.buffer     = FAR_PTR(packet_buf);
         pkt.buffersize = PKTBUF_SIZE;
         pkt.sip        = file->tftp_remoteip;
         pkt.dip        = MyIP;
@@ -541,8 +540,7 @@ static void fill_buffer(struct open_file_t *file)
         if (pkt.buffersize < 4)  /* Bad size for a DATA packet */
             continue;    
 
-        data = MK_PTR(PKTBUF_SEG, file->tftp_pktbuf);
-        if (*(uint16_t *)data != TFTP_DATA)    /* Not a data packet */
+        if (*(uint16_t *)packet_buf != TFTP_DATA)    /* Not a data packet */
             continue;
                 
         /* If goes here, recevie OK, break */
@@ -553,11 +551,13 @@ static void fill_buffer(struct open_file_t *file)
     if (timeout == 0)
 	kaboom();
     
+    
+    
     last_pkt = file->tftp_lastpkt;
     last_pkt = ntohs(last_pkt);       /* Host byte order */
     last_pkt++;
     last_pkt = htons(last_pkt);       /* Network byte order */
-    if (*(uint16_t *)(data + 2) != last_pkt) {
+    if (*(uint16_t *)(packet_buf + 2) != last_pkt) {
         /*
          * Wrong packet, ACK the packet and try again.
          * This is presumably because the ACK got lost,
@@ -569,11 +569,12 @@ static void fill_buffer(struct open_file_t *file)
 #endif
         goto ack_again;
     }
-    
+
     /* It's the packet we want.  We're also EOF if the size < blocksize */
     file->tftp_lastpkt = last_pkt;    /* Update last packet number */
     buffersize = pkt.buffersize - 4;  /* Skip TFTP header */
-    file->tftp_dataptr = file->tftp_pktbuf + 4;
+    memcpy(file->tftp_packet, packet_buf + 4, buffersize);
+    file->tftp_dataptr = file->tftp_packet;
     file->tftp_filepos += buffersize;
     file->tftp_bytesleft = buffersize;
     if (buffersize < file->tftp_blksize) {
@@ -617,7 +618,7 @@ static uint32_t pxe_getfssec(struct file *gfile, char *buf,
         if (chunk > file->tftp_bytesleft)
             chunk = file->tftp_bytesleft;
         file->tftp_bytesleft -= chunk;
-        memcpy(buf, MK_PTR(PKTBUF_SEG, file->tftp_dataptr), chunk);
+        memcpy(buf, file->tftp_dataptr, chunk);
 	file->tftp_dataptr += chunk;
         buf += chunk;
         bytes_read += chunk;
@@ -697,8 +698,7 @@ static void pxe_searchdir(char *filename, struct file *file)
     timeout_ptr = TimeoutTable;   /* Reset timeout */
 
  sendreq:
-    uw_pkt.buffer[0] = OFFS_WRT(buf, 0);
-    uw_pkt.buffer[1] = 0;
+    uw_pkt.buffer    = FAR_PTR(buf);
     *(uint16_t *)buf = TFTP_RRQ;  /* TFTP opcode */
     buf += 2;
     
@@ -717,8 +717,8 @@ static void pxe_searchdir(char *filename, struct file *file)
 #if GPXE
     if (is_gpxe(packet_buf + 2)) {
         fo.status = PXENV_STATUS_BAD_FUNC;
-        fo.filename[0] = OFFS_WRT(packet_buf + 2, 0);
-        fo.filename[1] = 0;
+        fo.filename.offs = OFFS(packet_buf) + 2;
+        fo.filename.seg  = SEG(packet_buf);
         err = pxe_call(PXENV_FILE_OPEN, &fo);
         if (err) 
             goto done;
@@ -765,9 +765,8 @@ static void pxe_searchdir(char *filename, struct file *file)
     oldtime = BIOS_timer;
     while (timeout) {
         buf = packet_buf;
-        ur_pkt.buffer[0] = OFFS_WRT(buf, 0);
-        ur_pkt.buffer[1] = 0;
-        ur_pkt.buffersize = 2048;
+        ur_pkt.buffer     = FAR_PTR(buf);
+        ur_pkt.buffersize = PKTBUF_SIZE;
         ur_pkt.dip = MyIP;
         ur_pkt.lport = tid;
         err = pxe_call(PXENV_UDP_READ, &ur_pkt);
@@ -839,8 +838,8 @@ static void pxe_searchdir(char *filename, struct file *file)
         }
 
         open_file->tftp_bytesleft = buffersize;
-        open_file->tftp_dataptr = open_file->tftp_pktbuf;
-        memcpy(MK_PTR(PKTBUF_SEG, open_file->tftp_pktbuf), data, buffersize);
+        open_file->tftp_dataptr = open_file->tftp_packet;
+        memcpy(open_file->tftp_packet, data, buffersize);
 	break;
 
     case TFTP_OACK:
@@ -932,8 +931,7 @@ done:
 
 err_reply:
     uw_pkt.rport = open_file->tftp_remoteport;
-    uw_pkt.buffer[0] = OFFS_WRT(tftp_proto_err, 0);
-    uw_pkt.buffer[1] = 0;
+    uw_pkt.buffer = FAR_PTR(tftp_proto_err);
     uw_pkt.buffersize = 24;
     pxe_call(PXENV_UDP_WRITE, &uw_pkt);
     printf("TFTP server sent an incomprehesible reply\n");
diff --git a/core/fs/pxe/pxe.h b/core/fs/pxe/pxe.h
index c2b905f..50ea47a 100644
--- a/core/fs/pxe/pxe.h
+++ b/core/fs/pxe/pxe.h
@@ -24,11 +24,10 @@
 /*
  * Some basic defines...
  */
-#define PKTBUF_SIZE        (65536 / MAX_OPEN)
+#define PKTBUF_SIZE        2048
 
 #define TFTP_BLOCKSIZE_LG2 9
 #define TFTP_BLOCKSIZE     (1 << TFTP_BLOCKSIZE_LG2)
-#define PKTBUF_SEG 0x4000
 
 #define is_digit(c) (((c) >= '0') && ((c) <= '9'))
 
@@ -141,17 +140,18 @@ struct open_file_t {
     uint16_t tftp_localport;   /* Local port number  (0=not in us)*/
     uint16_t tftp_remoteport;  /* Remote port number */
     uint32_t tftp_remoteip;    /* Remote IP address */
-    uint32_t tftp_filepos;     /* bytes downloaded (includeing buffer) */
+    uint32_t tftp_filepos;     /* Bytes downloaded (including buffer) */
     uint32_t tftp_filesize;    /* Total file size(*) */
     uint32_t tftp_blksize;     /* Block size for this connection(*) */
     uint16_t tftp_bytesleft;   /* Unclaimed data bytes */
     uint16_t tftp_lastpkt;     /* Sequence number of last packet (NBO) */
-    uint16_t tftp_dataptr;     /* Pointer to available data */
+    char    *tftp_dataptr;     /* Pointer to available data */
     uint8_t  tftp_goteof;      /* 1 if the EOF packet received */
     uint8_t  tftp_unused;      /* Currently unused */
     /* These values are preinitialized and not zeroed on close */
     uint16_t tftp_nextport;    /* Next port number for this slot (HBO) */
-    uint16_t tftp_pktbuf;      /* Packet buffer offset */
+    /* Packet data buffer */
+    char     tftp_packet[PKTBUF_SIZE];
 } __attribute__ ((packed));
 
 struct pxe_udp_write_pkt {
@@ -161,7 +161,7 @@ struct pxe_udp_write_pkt {
     uint16_t lport;
     uint16_t rport;
     uint16_t buffersize;
-    uint16_t buffer[2];
+    far_ptr_t buffer;
 } __attribute__ ((packed));
 
 struct pxe_udp_read_pkt {
@@ -171,14 +171,14 @@ struct pxe_udp_read_pkt {
     uint16_t rport;
     uint16_t lport;
     uint16_t buffersize;
-    uint16_t buffer[2];
+    far_ptr_t buffer;
 } __attribute__ ((packed));
 
 struct pxe_bootp_query_pkt {
     uint16_t status;
     uint16_t packettype;
     uint16_t buffersize;
-    uint16_t buffer[2];
+    far_ptr_t buffer;
     uint16_t bufferlimit;
 } __attribute__ ((packed));
 
@@ -197,10 +197,10 @@ struct gpxe_file_api_check {
 } __attribute__ ((packed));
 
 struct gpxe_file_open {
-    uint16_t status;
-    uint16_t filehandle;
-    uint16_t filename[2];
-    uint32_t reserved;
+    uint16_t  status;
+    uint16_t  filehandle;
+    far_ptr_t filename;
+    uint32_t  reserved;
 } __attribute__ ((packed));
 
 struct gpxe_get_file_size {
@@ -213,7 +213,7 @@ struct gpxe_file_read {
     uint16_t status;
     uint16_t filehandle;
     uint16_t buffersize;
-    uint16_t buffer[2];
+    far_ptr_t buffer;
 } __attribute__ ((packed));
 
 /*
@@ -229,8 +229,7 @@ void parse_dhcp(int);
 void parse_dhcp_options(void *, int, int);
 
 /* dnsresolv.c */
-int dns_mangle(char **, const char *);
-uint32_t dns_resolve(char **);
-
+int dns_mangle(char **, const char **);
+uint32_t dns_resolv(const char **);
 
 #endif /* pxe.h */
diff --git a/core/include/core.h b/core/include/core.h
index f8be691..4461f8f 100644
--- a/core/include/core.h
+++ b/core/include/core.h
@@ -66,8 +66,6 @@ extern char BootFile[];
 extern char PathPrefix[];
 extern char LocalDomain[];
 
-extern char packet_buf[];
-
 extern char IPOption[];
 extern char DotQuadBuf[];
 
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index ed67518..2613253 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -137,15 +137,6 @@ pxe_unload_stack_pkt:
 .reserved:	resb 10			; Reserved
 pxe_unload_stack_pkt_len	equ $-pxe_unload_stack_pkt
 
-		alignb 16
-		; BOOTP/DHCP packet buffer
-
-		section .bss16
-                global packet_buf
-		alignb 16
-packet_buf	resb 2048		; Transfer packet
-packet_buf_size	equ $-packet_buf
-
 		section .text16
 		;
 		; PXELINUX needs more BSS than the other derivatives;
