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_write(const char *msg);
|
||||||
extern void *bios_getmap(void *buffer);
|
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;
|
extern BOOTBOOT bootboot;
|
||||||
|
|
||||||
#define E820_TYPE_FREE 0x1
|
#define E820_TYPE_FREE 0x1
|
||||||
|
|
@ -93,6 +102,20 @@ display_string(uint16_t attr, const char *str)
|
||||||
bios_func(0x10, reg);
|
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_PRESENT 0x001
|
||||||
#define PG_WRITE 0x002
|
#define PG_WRITE 0x002
|
||||||
#define PG_USER 0x004
|
#define PG_USER 0x004
|
||||||
|
|
@ -136,27 +159,51 @@ struct exPXE {
|
||||||
uint32_t pmentry;
|
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 PXENV *PXENV;
|
||||||
extern struct exPXE *exPXE;
|
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
|
void
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
blank_screen(0x10);
|
blank_screen(0x10);
|
||||||
move_cursor(0, 0);
|
move_cursor(0, 0);
|
||||||
//display_string(0x14, "Netboot via fernlader v2 ...\r\n");
|
//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) {
|
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) {
|
if (PXENV->version >= 0x0201) {
|
||||||
bios_write("!PXE version\r\n");
|
debug_write("!PXE version\r\n");
|
||||||
if (memcmp(exPXE->signature, "!PXE", 4) != 0) {
|
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);
|
memcpy(bootboot.magic, BOOTBOOT_MAGIC, sizeof bootboot.magic);
|
||||||
|
|
@ -172,11 +219,38 @@ main()
|
||||||
char buf[2];
|
char buf[2];
|
||||||
buf[0] = memmap[i].type < 10 ? memmap[i].type + '0' : '?';
|
buf[0] = memmap[i].type < 10 ? memmap[i].type + '0' : '?';
|
||||||
buf[1] = 0;
|
buf[1] = 0;
|
||||||
bios_write(buf);
|
debug_write(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
pg_setup();
|
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
|
#if 0
|
||||||
uint32_t reg[7];
|
uint32_t reg[7];
|
||||||
reg[0] = (0x0E << 8) + 'J';
|
reg[0] = (0x0E << 8) + 'J';
|
||||||
|
|
@ -188,7 +262,7 @@ main()
|
||||||
reg[6] = 0;
|
reg[6] = 0;
|
||||||
bios_func(0x10, reg);
|
bios_func(0x10, reg);
|
||||||
|
|
||||||
bios_write("what?\r\n");
|
debug_write("what?\r\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,9 @@ _start: cli
|
||||||
mov %ss, %ax
|
mov %ss, %ax
|
||||||
mov %ax, %cs:real_ss
|
mov %ax, %cs:real_ss
|
||||||
|
|
||||||
|
mov %es, %ax
|
||||||
|
mov %ax, %cs:real_es
|
||||||
|
|
||||||
xor %eax, %eax
|
xor %eax, %eax
|
||||||
mov %es, %ax
|
mov %es, %ax
|
||||||
shl $4, %eax
|
shl $4, %eax
|
||||||
|
|
@ -71,6 +74,12 @@ exPXE: .long 0
|
||||||
.global real_ss
|
.global real_ss
|
||||||
real_ss: .word 0
|
real_ss: .word 0
|
||||||
|
|
||||||
|
.global real_es
|
||||||
|
real_es: .word 0
|
||||||
|
|
||||||
|
.global pxe_cmd_buf
|
||||||
|
pxe_cmd_buf:.space 512, 0
|
||||||
|
|
||||||
.global GDT
|
.global GDT
|
||||||
GDT: // entry 0: null descriptor
|
GDT: // entry 0: null descriptor
|
||||||
.space 8, 0
|
.space 8, 0
|
||||||
|
|
|
||||||
29
src/pxe.S
29
src/pxe.S
|
|
@ -4,21 +4,42 @@
|
||||||
|
|
||||||
.data
|
.data
|
||||||
|
|
||||||
pxe_entry: .word 0
|
.global pxe_entry
|
||||||
|
pxe_entry: .long 0
|
||||||
|
pxe_retval: .word 0
|
||||||
|
|
||||||
.text
|
.text
|
||||||
.global pxe_call
|
.global pxe_call
|
||||||
.code32
|
.code32
|
||||||
pxe_call: push %ebp
|
pxe_call: push %ebp
|
||||||
mov %esp, %ebp
|
mov %esp, %ebp
|
||||||
|
push %ebx
|
||||||
|
|
||||||
|
mov 0x08(%ebp), %ebx # op
|
||||||
|
mov 0x0C(%ebp), %ecx # off
|
||||||
|
mov 0x10(%ebp), %edx # seg
|
||||||
|
|
||||||
PROT16
|
PROT16
|
||||||
|
REAL
|
||||||
|
|
||||||
call (pxe_entry)
|
mov %cs:(real_es), %ax
|
||||||
push %eax
|
mov %ax, %es
|
||||||
|
|
||||||
|
push %dx
|
||||||
|
push %cx
|
||||||
|
push %bx
|
||||||
|
|
||||||
|
lcall *(pxe_entry)
|
||||||
|
mov %ax, pxe_retval
|
||||||
|
|
||||||
|
add $6, %sp
|
||||||
|
|
||||||
|
PROT
|
||||||
PROT32
|
PROT32
|
||||||
|
|
||||||
pop %eax
|
mov pxe_retval, %ax
|
||||||
|
movzwl %ax, %eax
|
||||||
|
|
||||||
|
pop %ebx
|
||||||
leave
|
leave
|
||||||
ret
|
ret
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ typedef unsigned short uint16_t;
|
||||||
typedef unsigned int uint32_t;
|
typedef unsigned int uint32_t;
|
||||||
typedef unsigned long long uint64_t;
|
typedef unsigned long long uint64_t;
|
||||||
|
|
||||||
|
typedef unsigned int uintptr_t;
|
||||||
|
|
||||||
// stdbool.h
|
// stdbool.h
|
||||||
|
|
||||||
#define true ((_Bool)1)
|
#define true ((_Bool)1)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue