#include <grub/env.h>
#include <grub/machine/pxe.h>
+#include <grub/machine/int.h>
#include <grub/machine/memory.h>
#define SEGMENT(x) ((x) >> 4)
char filename[0];
};
+static grub_uint32_t pxe_rm_entry = 0;
+
+static struct grub_pxenv *
+grub_pxe_scan (void)
+{
+ struct grub_bios_int_registers regs;
+ struct grub_pxenv *ret;
+ void *pxe;
+
+ regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
+
+ regs.ebx = 0;
+ regs.ecx = 0;
+ regs.eax = 0x5650;
+
+ grub_bios_interrupt (0x1a, ®s);
+
+ if ((regs.eax & 0xffff) != 0x564e)
+ return NULL;
+ ret = (struct grub_pxenv *) ((regs.es << 4) + (regs.ebx & 0xffff));
+ if (grub_memcmp (ret->signature, GRUB_PXE_SIGNATURE, sizeof (ret->signature))
+ != 0)
+ return NULL;
+ if (ret->version < 0x201)
+ return NULL;
+
+ pxe = (void *) ((((ret->pxe_ptr & 0xffff0000) >> 16) << 4)
+ + (ret->pxe_ptr & 0xffff));
+ if (!pxe)
+ return NULL;
+
+ /* !PXE */
+ if (*(grub_uint32_t *) pxe != 0x45585021)
+ return NULL;
+
+ pxe_rm_entry = ret->rm_entry;
+ return ret;
+}
+
static int
grub_pxe_iterate (int (*hook) (const char *name))
{
if (curr_file != 0)
{
- grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c.c2);
+ grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c.c2, pxe_rm_entry);
curr_file = 0;
}
c.c1.server_ip = disk_data->server_ip;
c.c1.gateway_ip = disk_data->gateway_ip;
grub_strcpy ((char *)&c.c1.filename[0], name);
- grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1);
+ grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1, pxe_rm_entry);
if (c.c1.status)
return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
c.c2.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
c.c2.packet_size = grub_pxe_blksize;
- grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &c.c2);
+ grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &c.c2, pxe_rm_entry);
if (c.c2.status)
return grub_error (GRUB_ERR_BAD_FS, "open fails");
struct grub_pxenv_tftp_open o;
if (curr_file != 0)
- grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o);
+ grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o, pxe_rm_entry);
o.server_ip = disk_data->server_ip;
o.gateway_ip = disk_data->gateway_ip;
grub_strcpy ((char *)&o.filename[0], data->filename);
o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
o.packet_size = grub_pxe_blksize;
- grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o);
+ grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o, pxe_rm_entry);
if (o.status)
{
grub_error (GRUB_ERR_BAD_FS, "open fails");
while (pn >= data->packet_number)
{
c.buffer_size = data->block_size;
- grub_pxe_call (GRUB_PXENV_TFTP_READ, &c);
+ grub_pxe_call (GRUB_PXENV_TFTP_READ, &c, pxe_rm_entry);
if (c.status)
{
grub_error (GRUB_ERR_BAD_FS, "read fails");
if (curr_file == file)
{
- grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c);
+ grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c, pxe_rm_entry);
curr_file = 0;
}
ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK;
ci.buffer = 0;
ci.buffer_size = 0;
- grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci);
+ grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci, pxe_rm_entry);
if (ci.status)
return;
popl %ebp
ret
-pxe_rm_entry:
- .long 0
-
-/*
- * struct grub_pxenv *grub_pxe_scan (void);
- */
-FUNCTION(grub_pxe_scan)
- pushl %ebp
- pushl %ebx
-
- xorl %ebx, %ebx
- xorl %ecx, %ecx
-
- call prot_to_real
- .code16
-
- pushw %es
-
- movw $0x5650, %ax
- int $0x1A
- cmpw $0x564E, %ax
- jnz 1f
- cmpl $0x4E455850, %es:(%bx) /* PXEN(V+) */
- jnz 1f
- cmpw $0x201, %es:6(%bx) /* API version */
- jb 1f
- lesw %es:0x28(%bx), %bx /* !PXE structure */
- cmpl $0x45585021, %es:(%bx) /* !PXE */
- jnz 1f
- movw %es, %cx
- jmp 2f
-1:
- xorw %bx, %bx
- xorw %cx, %cx
-2:
-
- popw %es
-
- DATA32 call real_to_prot
- .code32
-
- xorl %eax, %eax
- leal (%eax, %ecx, 4), %ecx
- leal (%ebx, %ecx, 4), %eax /* eax = ecx * 16 + ebx */
-
- orl %eax, %eax
- jz 1f
-
- movl 0x10(%eax), %ecx
- movl %ecx, pxe_rm_entry
-
-1:
-
- popl %ebx
- popl %ebp
- ret
-
/*
- * int grub_pxe_call (int func, void* data);
+ * int grub_pxe_call (int func, void* data, grub_uint32_t pxe_rm_entry);
*/
FUNCTION(grub_pxe_call)
pushl %ebp
pushl %edi
pushl %ebx
+ movl %ecx, %ebx
movl %eax, %ecx
movl %edx, %eax
andl $0xF, %eax
shrl $4, %edx
shll $16, %edx
addl %eax, %edx
- movl pxe_rm_entry, %ebx
call prot_to_real
.code16