Drop down to real mode for PXE call
This commit is contained in:
parent
89bb0903fe
commit
b047e34dcb
4 changed files with 117 additions and 11 deletions
88
src/main.c
88
src/main.c
|
|
@ -21,6 +21,15 @@ outb(uint16_t port, uint8_t data)
|
|||
extern void bios_write(const char *msg);
|
||||
extern void *bios_getmap(void *buffer);
|
||||
|
||||
void
|
||||
debug_write(const char *msg)
|
||||
{
|
||||
for (const char *c = msg; *c; c++) {
|
||||
outb(0xE9, *c);
|
||||
}
|
||||
bios_write(msg);
|
||||
}
|
||||
|
||||
extern BOOTBOOT bootboot;
|
||||
|
||||
#define E820_TYPE_FREE 0x1
|
||||
|
|
@ -93,6 +102,20 @@ display_string(uint16_t attr, const char *str)
|
|||
bios_func(0x10, reg);
|
||||
}
|
||||
|
||||
void
|
||||
debug_write_uint(unsigned v)
|
||||
{
|
||||
char buf[20], *p = buf + sizeof buf;
|
||||
p--;
|
||||
*p = 0;
|
||||
do {
|
||||
p--;
|
||||
*p = (v % 10) + '0';
|
||||
v /= 10;
|
||||
} while (v);
|
||||
debug_write(p);
|
||||
}
|
||||
|
||||
#define PG_PRESENT 0x001
|
||||
#define PG_WRITE 0x002
|
||||
#define PG_USER 0x004
|
||||
|
|
@ -136,27 +159,51 @@ struct exPXE {
|
|||
uint32_t pmentry;
|
||||
};
|
||||
|
||||
//extern uint32_t pxe_call(uint16_t func, offset, segment);
|
||||
extern uint32_t pxe_entry;
|
||||
extern uint32_t pxe_call(uint16_t func, uint16_t segment, uint16_t offset);
|
||||
|
||||
extern unsigned char pxe_cmd_buf[512];
|
||||
extern struct PXENV *PXENV;
|
||||
extern struct exPXE *exPXE;
|
||||
|
||||
#define PXENV_GET_CACHED 0x0071
|
||||
#define PXENV_TFTP_OPEN 0x0020
|
||||
|
||||
typedef struct __attribute__((packed)) s_PXENV_GET_CACHED {
|
||||
uint16_t status;
|
||||
uint16_t packet_type;
|
||||
uint16_t buffer_size;
|
||||
uint16_t buffer_offset;
|
||||
uint16_t buffer_seg;
|
||||
uint16_t buffer_limit;
|
||||
} t_PXENV_GET_CACHED;
|
||||
|
||||
typedef struct __attribute__((packed)) s_PXENV_TFTP_OPEN {
|
||||
uint16_t status;
|
||||
uint32_t server_ip;
|
||||
uint32_t gateway_ip;
|
||||
unsigned char filename[128];
|
||||
uint16_t tftp_port;
|
||||
uint16_t packet_size;
|
||||
} t_PXENV_TFTP_OPEN;
|
||||
|
||||
void
|
||||
main()
|
||||
{
|
||||
blank_screen(0x10);
|
||||
move_cursor(0, 0);
|
||||
//display_string(0x14, "Netboot via fernlader v2 ...\r\n");
|
||||
bios_write("Going well ...\r\n");
|
||||
debug_write("Going well ...\r\n");
|
||||
|
||||
if (memcmp(PXENV->signature, "PXENV+", 6) != 0) {
|
||||
bios_write("missing PXENV+ signature\r\n");
|
||||
debug_write("missing PXENV+ signature\r\n");
|
||||
}
|
||||
if (PXENV->version >= 0x0201) {
|
||||
bios_write("!PXE version\r\n");
|
||||
debug_write("!PXE version\r\n");
|
||||
if (memcmp(exPXE->signature, "!PXE", 4) != 0) {
|
||||
bios_write("missing !PXE signature\r\n");
|
||||
debug_write("missing !PXE signature\r\n");
|
||||
}
|
||||
pxe_entry = exPXE->rmentry;
|
||||
}
|
||||
|
||||
memcpy(bootboot.magic, BOOTBOOT_MAGIC, sizeof bootboot.magic);
|
||||
|
|
@ -172,11 +219,38 @@ main()
|
|||
char buf[2];
|
||||
buf[0] = memmap[i].type < 10 ? memmap[i].type + '0' : '?';
|
||||
buf[1] = 0;
|
||||
bios_write(buf);
|
||||
debug_write(buf);
|
||||
}
|
||||
|
||||
pg_setup();
|
||||
|
||||
#if 0
|
||||
t_PXENV_TFTP_OPEN *t_open = (void *)pxe_cmd_buf;
|
||||
t_open->status = 0;
|
||||
t_open->server_ip = 0x0100000Au;
|
||||
t_open->gateway_ip = 0;
|
||||
memcpy(t_open->filename, "/initrd", 8);
|
||||
t_open->tftp_port = 69 << 8;
|
||||
t_open->packet_size = 512;
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
t_PXENV_GET_CACHED *t_get = (void *)pxe_cmd_buf;
|
||||
t_get->status = 0;
|
||||
t_get->packet_type = 2;
|
||||
t_get->buffer_size = 0;
|
||||
t_get->buffer_offset = 0;
|
||||
t_get->buffer_seg = 0;
|
||||
t_get->buffer_limit = 0xFFFFu;
|
||||
debug_write("Performing PXE call\r\n");
|
||||
unsigned ret = pxe_call(PXENV_GET_CACHED, (uint16_t)(uintptr_t)pxe_cmd_buf, 0x0000);
|
||||
debug_write("Still alive!\r\n");
|
||||
debug_write("ret=");
|
||||
debug_write_uint(ret);
|
||||
debug_write("\r\nstatus=");
|
||||
debug_write_uint(t_get->status);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
uint32_t reg[7];
|
||||
reg[0] = (0x0E << 8) + 'J';
|
||||
|
|
@ -188,7 +262,7 @@ main()
|
|||
reg[6] = 0;
|
||||
bios_func(0x10, reg);
|
||||
|
||||
bios_write("what?\r\n");
|
||||
debug_write("what?\r\n");
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ _start: cli
|
|||
mov %ss, %ax
|
||||
mov %ax, %cs:real_ss
|
||||
|
||||
mov %es, %ax
|
||||
mov %ax, %cs:real_es
|
||||
|
||||
xor %eax, %eax
|
||||
mov %es, %ax
|
||||
shl $4, %eax
|
||||
|
|
@ -71,6 +74,12 @@ exPXE: .long 0
|
|||
.global real_ss
|
||||
real_ss: .word 0
|
||||
|
||||
.global real_es
|
||||
real_es: .word 0
|
||||
|
||||
.global pxe_cmd_buf
|
||||
pxe_cmd_buf:.space 512, 0
|
||||
|
||||
.global GDT
|
||||
GDT: // entry 0: null descriptor
|
||||
.space 8, 0
|
||||
|
|
|
|||
29
src/pxe.S
29
src/pxe.S
|
|
@ -4,21 +4,42 @@
|
|||
|
||||
.data
|
||||
|
||||
pxe_entry: .word 0
|
||||
.global pxe_entry
|
||||
pxe_entry: .long 0
|
||||
pxe_retval: .word 0
|
||||
|
||||
.text
|
||||
.global pxe_call
|
||||
.code32
|
||||
pxe_call: push %ebp
|
||||
mov %esp, %ebp
|
||||
push %ebx
|
||||
|
||||
mov 0x08(%ebp), %ebx # op
|
||||
mov 0x0C(%ebp), %ecx # off
|
||||
mov 0x10(%ebp), %edx # seg
|
||||
|
||||
PROT16
|
||||
REAL
|
||||
|
||||
call (pxe_entry)
|
||||
push %eax
|
||||
mov %cs:(real_es), %ax
|
||||
mov %ax, %es
|
||||
|
||||
push %dx
|
||||
push %cx
|
||||
push %bx
|
||||
|
||||
lcall *(pxe_entry)
|
||||
mov %ax, pxe_retval
|
||||
|
||||
add $6, %sp
|
||||
|
||||
PROT
|
||||
PROT32
|
||||
|
||||
pop %eax
|
||||
mov pxe_retval, %ax
|
||||
movzwl %ax, %eax
|
||||
|
||||
pop %ebx
|
||||
leave
|
||||
ret
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ typedef unsigned short uint16_t;
|
|||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
typedef unsigned int uintptr_t;
|
||||
|
||||
// stdbool.h
|
||||
|
||||
#define true ((_Bool)1)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue