intwrap grub_pxe_scan
This commit is contained in:
parent
65936631e4
commit
1b8cb8573b
3 changed files with 53 additions and 69 deletions
|
@ -27,6 +27,7 @@
|
||||||
#include <grub/env.h>
|
#include <grub/env.h>
|
||||||
|
|
||||||
#include <grub/machine/pxe.h>
|
#include <grub/machine/pxe.h>
|
||||||
|
#include <grub/machine/int.h>
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
|
|
||||||
#define SEGMENT(x) ((x) >> 4)
|
#define SEGMENT(x) ((x) >> 4)
|
||||||
|
@ -55,6 +56,45 @@ struct grub_pxe_data
|
||||||
char filename[0];
|
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
|
static int
|
||||||
grub_pxe_iterate (int (*hook) (const char *name))
|
grub_pxe_iterate (int (*hook) (const char *name))
|
||||||
{
|
{
|
||||||
|
@ -202,14 +242,14 @@ grub_pxefs_open (struct grub_file *file, const char *name)
|
||||||
|
|
||||||
if (curr_file != 0)
|
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;
|
curr_file = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.c1.server_ip = disk_data->server_ip;
|
c.c1.server_ip = disk_data->server_ip;
|
||||||
c.c1.gateway_ip = disk_data->gateway_ip;
|
c.c1.gateway_ip = disk_data->gateway_ip;
|
||||||
grub_strcpy ((char *)&c.c1.filename[0], name);
|
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)
|
if (c.c1.status)
|
||||||
return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
|
return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
|
||||||
|
|
||||||
|
@ -217,7 +257,7 @@ grub_pxefs_open (struct grub_file *file, const char *name)
|
||||||
|
|
||||||
c.c2.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
|
c.c2.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
|
||||||
c.c2.packet_size = grub_pxe_blksize;
|
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)
|
if (c.c2.status)
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "open fails");
|
return grub_error (GRUB_ERR_BAD_FS, "open fails");
|
||||||
|
|
||||||
|
@ -275,14 +315,14 @@ grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
struct grub_pxenv_tftp_open o;
|
struct grub_pxenv_tftp_open o;
|
||||||
|
|
||||||
if (curr_file != 0)
|
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.server_ip = disk_data->server_ip;
|
||||||
o.gateway_ip = disk_data->gateway_ip;
|
o.gateway_ip = disk_data->gateway_ip;
|
||||||
grub_strcpy ((char *)&o.filename[0], data->filename);
|
grub_strcpy ((char *)&o.filename[0], data->filename);
|
||||||
o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
|
o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
|
||||||
o.packet_size = grub_pxe_blksize;
|
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)
|
if (o.status)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_BAD_FS, "open fails");
|
grub_error (GRUB_ERR_BAD_FS, "open fails");
|
||||||
|
@ -297,7 +337,7 @@ grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
while (pn >= data->packet_number)
|
while (pn >= data->packet_number)
|
||||||
{
|
{
|
||||||
c.buffer_size = data->block_size;
|
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)
|
if (c.status)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_BAD_FS, "read fails");
|
grub_error (GRUB_ERR_BAD_FS, "read fails");
|
||||||
|
@ -318,7 +358,7 @@ grub_pxefs_close (grub_file_t file)
|
||||||
|
|
||||||
if (curr_file == file)
|
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;
|
curr_file = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,7 +494,7 @@ grub_pxe_detect (void)
|
||||||
ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK;
|
ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK;
|
||||||
ci.buffer = 0;
|
ci.buffer = 0;
|
||||||
ci.buffer_size = 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)
|
if (ci.status)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -168,6 +168,8 @@
|
||||||
|
|
||||||
#ifndef ASM_FILE
|
#ifndef ASM_FILE
|
||||||
|
|
||||||
|
#define GRUB_PXE_SIGNATURE "PXENV+"
|
||||||
|
|
||||||
struct grub_pxenv
|
struct grub_pxenv
|
||||||
{
|
{
|
||||||
grub_uint8_t signature[6]; /* 'PXENV+'. */
|
grub_uint8_t signature[6]; /* 'PXENV+'. */
|
||||||
|
@ -302,8 +304,7 @@ struct grub_pxenv_unload_stack
|
||||||
grub_uint8_t reserved[10];
|
grub_uint8_t reserved[10];
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct grub_pxenv * EXPORT_FUNC(grub_pxe_scan) (void);
|
int EXPORT_FUNC(grub_pxe_call) (int func, void * data, grub_uint32_t pxe_rm_entry);
|
||||||
int EXPORT_FUNC(grub_pxe_call) (int func, void * data);
|
|
||||||
|
|
||||||
extern struct grub_pxenv *grub_pxe_pxenv;
|
extern struct grub_pxenv *grub_pxe_pxenv;
|
||||||
|
|
||||||
|
|
|
@ -1434,65 +1434,8 @@ FUNCTION(grub_get_rtc)
|
||||||
popl %ebp
|
popl %ebp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
pxe_rm_entry:
|
|
||||||
.long 0
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* struct grub_pxenv *grub_pxe_scan (void);
|
* int grub_pxe_call (int func, void* data, grub_uint32_t pxe_rm_entry);
|
||||||
*/
|
|
||||||
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);
|
|
||||||
*/
|
*/
|
||||||
FUNCTION(grub_pxe_call)
|
FUNCTION(grub_pxe_call)
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
|
@ -1501,13 +1444,13 @@ FUNCTION(grub_pxe_call)
|
||||||
pushl %edi
|
pushl %edi
|
||||||
pushl %ebx
|
pushl %ebx
|
||||||
|
|
||||||
|
movl %ecx, %ebx
|
||||||
movl %eax, %ecx
|
movl %eax, %ecx
|
||||||
movl %edx, %eax
|
movl %edx, %eax
|
||||||
andl $0xF, %eax
|
andl $0xF, %eax
|
||||||
shrl $4, %edx
|
shrl $4, %edx
|
||||||
shll $16, %edx
|
shll $16, %edx
|
||||||
addl %eax, %edx
|
addl %eax, %edx
|
||||||
movl pxe_rm_entry, %ebx
|
|
||||||
|
|
||||||
call prot_to_real
|
call prot_to_real
|
||||||
.code16
|
.code16
|
||||||
|
|
Loading…
Reference in a new issue