fernlader2/src/main.c

198 lines
3.7 KiB
C
Raw Normal View History

2026-02-18 13:40:19 +01:00
#include "std.h"
2026-02-18 13:40:19 +01:00
#include <bootboot.h>
2026-02-17 19:44:29 +01:00
#define COM1_BASE_PORT 0x3F8
static inline uint8_t
inb(uint16_t port)
{
uint8_t data;
__asm__ ("inb %%dx, %%al" : "=a"(data) : "d"(port));
return data;
}
static inline void
outb(uint16_t port, uint8_t data)
{
__asm__ ("outb %%al, %%dx" :: "a"(data), "d"(port));
}
2026-02-18 13:40:19 +01:00
extern void bios_write(const char *msg);
extern void *bios_getmap(void *buffer);
2026-02-17 19:44:29 +01:00
2026-02-18 13:40:19 +01:00
extern BOOTBOOT bootboot;
2026-02-18 13:40:19 +01:00
#define E820_TYPE_FREE 0x1
#define E820_TYPE_RESERVED 0x2
#define E820_TYPE_RECLAIMABLE 0x3
#define E820_TYPE_NONVOLATILE 0x4
#define E820_TYPE_BADMEM 0x5
struct e820_entry {
uint64_t base;
uint64_t length;
uint32_t type;
uint32_t xattr;
};
struct e820_entry memmap[128];
2026-02-18 01:27:49 +01:00
2026-02-18 13:40:19 +01:00
struct vesa_info {
char signature[4];
uint16_t version;
uint16_t oem_name[2];
uint8_t capab[4];
uint16_t video_mode_offset;
uint16_t video_mode_segment;
uint16_t num_64k_blocks;
uint8_t reserved[492];
};
2026-02-21 16:45:39 +01:00
extern uint16_t bios_func(uint8_t inum, uint32_t reg[]);
void
blank_screen(uint16_t attr)
{
uint32_t reg[7];
reg[0] = (0x06 << 8);
reg[1] = 0;
reg[2] = 0xFFFF;
reg[3] = attr << 8;
reg[4] = 0;
reg[5] = 0;
reg[6] = 0;
bios_func(0x10, reg);
}
void
move_cursor(uint8_t row, uint8_t col)
{
uint32_t reg[7];
reg[0] = (0x02 << 8);
reg[1] = 0;
reg[2] = (row << 8) | col;
reg[3] = 0;
reg[4] = 0;
reg[5] = 0;
reg[6] = 0;
bios_func(0x10, reg);
}
void
display_string(uint16_t attr, const char *str)
{
uint32_t reg[7];
reg[0] = (0x13 << 8) | 0x01;
reg[1] = strlen(str);
reg[2] = 0xFFFF;
reg[3] = attr;
reg[4] = (uint32_t)str;
reg[5] = 0;
reg[6] = 0;
bios_func(0x10, reg);
}
2026-02-21 14:13:24 +01:00
#define PG_PRESENT 0x001
#define PG_WRITE 0x002
#define PG_USER 0x004
#define PG_SIZE 0x080
#define PG_GLOBAL 0x100
__attribute__((aligned(4096))) uint64_t pml4[512];
__attribute__((aligned(4096))) uint64_t pdp[512];
__attribute__((aligned(4096))) uint64_t pd[512];
uint64_t
pg_setup()
{
pml4[0] = (uint64_t)(uint32_t)pdp | PG_WRITE | PG_PRESENT;
pdp[0] = (uint64_t)(uint32_t)pd | PG_WRITE | PG_PRESENT;
for (unsigned i = 0; i < 512; i++) {
pd[i] = (i * (uint64_t)0x200000) | PG_WRITE | PG_PRESENT | PG_SIZE;
}
uint64_t cr3 = (uint64_t)(uint32_t)pml4;
return cr3;
}
struct PXENV {
uint8_t signature[6];
uint16_t version;
uint8_t length;
uint8_t checksum;
uint32_t rmentry;
uint32_t pmoffset;
};
struct exPXE {
uint8_t signature[4];
uint8_t length;
uint8_t checksum;
uint8_t revision;
uint8_t reserved;
uint32_t undiromid;
uint32_t bcromid;
uint32_t rmentry;
uint32_t pmentry;
};
//extern uint32_t pxe_call(uint16_t func, offset, segment);
extern struct PXENV *PXENV;
extern struct exPXE *exPXE;
2026-02-17 19:44:29 +01:00
void
main()
{
blank_screen(0x10);
move_cursor(0, 0);
//display_string(0x14, "Netboot via fernlader v2 ...\r\n");
2026-02-21 16:45:39 +01:00
bios_write("Going well ...\r\n");
2026-02-18 13:40:19 +01:00
if (memcmp(PXENV->signature, "PXENV+", 6) != 0) {
bios_write("missing PXENV+ signature\r\n");
}
if (PXENV->version >= 0x0201) {
bios_write("!PXE version\r\n");
if (memcmp(exPXE->signature, "!PXE", 4) != 0) {
bios_write("missing !PXE signature\r\n");
}
}
2026-02-18 13:40:19 +01:00
memcpy(bootboot.magic, BOOTBOOT_MAGIC, sizeof bootboot.magic);
bootboot.size = 128;
bootboot.protocol = PROTOCOL_MINIMAL | LOADER_BIOS;
bootboot.numcores = 1;
//display_string(0x0E, "init\r\n");
2026-02-18 13:40:19 +01:00
struct e820_entry *end = bios_getmap(memmap);
//display_string(0x0E, "karlos\r\n");
2026-02-18 01:27:49 +01:00
for (int i = 0; ; i++) {
2026-02-18 13:40:19 +01:00
if (&memmap[i] >= end) break;
char buf[2];
buf[0] = memmap[i].type < 10 ? memmap[i].type + '0' : '?';
buf[1] = 0;
bios_write(buf);
2026-02-18 01:27:49 +01:00
}
2026-02-18 13:40:19 +01:00
2026-02-21 14:13:24 +01:00
pg_setup();
2026-02-18 13:40:19 +01:00
#if 0
2026-02-21 16:45:39 +01:00
uint32_t reg[7];
2026-02-18 13:40:19 +01:00
reg[0] = (0x0E << 8) + 'J';
reg[1] = 0;
reg[2] = 0;
reg[3] = 0;
reg[4] = 0;
reg[5] = 0;
reg[6] = 0;
bios_func(0x10, reg);
2026-02-21 14:13:24 +01:00
bios_write("what?\r\n");
2026-02-21 16:45:39 +01:00
#endif
2026-02-21 14:13:24 +01:00
2026-02-17 19:44:29 +01:00
for (;;) {
2026-02-18 13:40:19 +01:00
__asm__ ("hlt");
2026-02-17 19:44:29 +01:00
}
}