Drop down to real mode for PXE call

This commit is contained in:
Thomas Oltmann 2026-05-21 14:44:16 +02:00
parent 89bb0903fe
commit b047e34dcb
4 changed files with 117 additions and 11 deletions

View file

@ -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 (;;) {

View file

@ -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

View file

@ -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

View file

@ -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)