#include "std.h" #include #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)); } extern void bios_write(const char *msg); extern void *bios_getmap(void *buffer); extern BOOTBOOT bootboot; #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]; 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]; }; extern uint16_t bios_func(uint8_t inum, uint16_t reg[]); #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; } void main() { bios_write("Netboot via fernlader v2 ...\r\n"); memcpy(bootboot.magic, BOOTBOOT_MAGIC, sizeof bootboot.magic); bootboot.size = 128; bootboot.protocol = PROTOCOL_MINIMAL | LOADER_BIOS; bootboot.numcores = 1; bios_write("init\r\n"); struct e820_entry *end = bios_getmap(memmap); bios_write("karlos\r\n"); for (int i = 0; ; i++) { if (&memmap[i] >= end) break; char buf[2]; buf[0] = memmap[i].type < 10 ? memmap[i].type + '0' : '?'; buf[1] = 0; bios_write(buf); } pg_setup(); #if 0 char foo[24]; bios_write("bios_func():\r\n"); uint32_t reg[6]; reg[0] = 0xE820; reg[1] = 24; reg[2] = 0x534D4150; reg[3] = 0; reg[4] = (uint32_t)&foo; reg[5] = 0; uint16_t flags = bios_func(0x15, reg); const char *hex_digits = "0123456789ABCDEF"; char buf[100]; buf[0] = hex_digits[(flags >> 12) & 0xF]; buf[1] = hex_digits[(flags >> 8) & 0xF]; buf[2] = hex_digits[(flags >> 4) & 0xF]; buf[3] = hex_digits[(flags >> 0) & 0xF]; buf[4] = ' '; buf[5] = hex_digits[(foo[16] >> 0) & 0xF]; buf[6] = ' '; buf[7] = 0; bios_write(buf); #endif uint16_t reg[7]; 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); bios_write("what?\r\n"); for (;;) { __asm__ ("hlt"); } }