Initial Commit
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
#include "ata.h"
|
||||
#include "io.h" // your existing inb/outb/insw
|
||||
#include "stdio.h"
|
||||
#include "memory.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define ATA_PRIMARY_DATA 0x1F0
|
||||
#define ATA_PRIMARY_ERROR 0x1F1
|
||||
#define ATA_PRIMARY_SECCOUNT 0x1F2
|
||||
#define ATA_PRIMARY_LBALOW 0x1F3
|
||||
#define ATA_PRIMARY_LBAMID 0x1F4
|
||||
#define ATA_PRIMARY_LBAHIGH 0x1F5
|
||||
#define ATA_PRIMARY_DRIVE 0x1F6
|
||||
#define ATA_PRIMARY_STATUS 0x1F7
|
||||
#define ATA_PRIMARY_COMMAND 0x1F7
|
||||
|
||||
#define ATA_STATUS_BSY 0x80
|
||||
#define ATA_STATUS_DRDY 0x40
|
||||
#define ATA_STATUS_DRQ 0x08
|
||||
#define ATA_STATUS_ERR 0x01
|
||||
|
||||
#define ATA_CMD_IDENTIFY 0xEC
|
||||
#define ATA_CMD_READ_SECTORS 0x20
|
||||
|
||||
static void ata_wait_ready(void)
|
||||
{
|
||||
while (x86_64_inb(ATA_PRIMARY_STATUS) & ATA_STATUS_BSY) {}
|
||||
while (!(x86_64_inb(ATA_PRIMARY_STATUS) & ATA_STATUS_DRDY)) {}
|
||||
}
|
||||
|
||||
static bool ata_poll(void)
|
||||
{
|
||||
// 400 ns delay
|
||||
for (int i = 0; i < 4; i++)
|
||||
x86_64_inb(ATA_PRIMARY_STATUS);
|
||||
|
||||
uint8_t status;
|
||||
|
||||
while ((status = x86_64_inb(ATA_PRIMARY_STATUS)) & ATA_STATUS_BSY);
|
||||
if (status & ATA_STATUS_ERR) return false;
|
||||
|
||||
while (!(status & ATA_STATUS_DRQ)) {
|
||||
status = x86_64_inb(ATA_PRIMARY_STATUS);
|
||||
if (status & ATA_STATUS_ERR) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ata_init(void)
|
||||
{
|
||||
x86_64_outb(0x3F6, 0x02); // disable interrupts on primary controller
|
||||
ata_wait_ready();
|
||||
x86_64_outb(ATA_PRIMARY_DRIVE, 0xA0); // select master
|
||||
ata_wait_ready();
|
||||
printf("ATA: Primary master (hda) initialized\n");
|
||||
}
|
||||
|
||||
void ata_identify(void)
|
||||
{
|
||||
static uint16_t buffer[256];
|
||||
|
||||
x86_64_outb(ATA_PRIMARY_DRIVE, 0xA0);
|
||||
x86_64_outb(ATA_PRIMARY_SECCOUNT, 0);
|
||||
x86_64_outb(ATA_PRIMARY_LBALOW, 0);
|
||||
x86_64_outb(ATA_PRIMARY_LBAMID, 0);
|
||||
x86_64_outb(ATA_PRIMARY_LBAHIGH, 0);
|
||||
x86_64_outb(ATA_PRIMARY_COMMAND, ATA_CMD_IDENTIFY);
|
||||
|
||||
if (x86_64_inb(ATA_PRIMARY_STATUS) == 0) {
|
||||
printf("ATA: No primary master drive detected\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ata_poll()) {
|
||||
printf("ATA poll failed at ATA_IDENTIFY\n");
|
||||
}
|
||||
|
||||
if (x86_64_inb(ATA_PRIMARY_STATUS) & ATA_STATUS_ERR) {
|
||||
printf("ATA: Identify error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
x86_64_insw(ATA_PRIMARY_DATA, buffer, 256);
|
||||
|
||||
printf("ATA: Disk model: ");
|
||||
for (int i = 27; i <= 46; i++) {
|
||||
uint16_t w = buffer[i];
|
||||
char high = w >> 8;
|
||||
char low = w & 0xFF;
|
||||
printf("%c%c", high, low); // swap bytes
|
||||
}
|
||||
printf("\n");
|
||||
printf("ATA: Total sectors: %lu\n", (uint64_t)buffer[60] | ((uint64_t)buffer[61] << 16));
|
||||
}
|
||||
|
||||
bool ata_read_sectors(uint64_t lba, uint8_t sector_count, void* buffer)
|
||||
{
|
||||
if (sector_count == 0) return true;
|
||||
|
||||
ata_wait_ready();
|
||||
|
||||
x86_64_outb(ATA_PRIMARY_DRIVE, 0xE0 | ((lba >> 24) & 0x0F));
|
||||
x86_64_outb(ATA_PRIMARY_SECCOUNT, sector_count);
|
||||
x86_64_outb(ATA_PRIMARY_LBALOW, (uint8_t)lba);
|
||||
x86_64_outb(ATA_PRIMARY_LBAMID, (uint8_t)(lba >> 8));
|
||||
x86_64_outb(ATA_PRIMARY_LBAHIGH, (uint8_t)(lba >> 16));
|
||||
|
||||
x86_64_outb(ATA_PRIMARY_COMMAND, ATA_CMD_READ_SECTORS);
|
||||
|
||||
uint16_t* buf = buffer;
|
||||
for (uint8_t i = 0; i < sector_count; i++) {
|
||||
if (!ata_poll()) {
|
||||
printf("ATA poll failed at ATA_read_sectors\n");
|
||||
}
|
||||
|
||||
if (x86_64_inb(ATA_PRIMARY_STATUS) & ATA_STATUS_ERR) {
|
||||
printf("ATA read error at LBA %lu\n", lba + i);
|
||||
return false;
|
||||
}
|
||||
|
||||
x86_64_insw(ATA_PRIMARY_DATA, buf, 256); // 512 bytes
|
||||
buf += 256;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ata_write_sectors(uint64_t lba, uint8_t sector_count, const void* buffer) {
|
||||
if (sector_count == 0) return true;
|
||||
|
||||
|
||||
|
||||
ata_wait_ready();
|
||||
x86_64_outb(ATA_PRIMARY_DRIVE, 0xE0 | ((lba >> 24) & 0x0F));
|
||||
x86_64_outb(ATA_PRIMARY_SECCOUNT, sector_count);
|
||||
x86_64_outb(ATA_PRIMARY_LBALOW, (uint8_t)lba);
|
||||
x86_64_outb(ATA_PRIMARY_LBAMID, (uint8_t)(lba >> 8));
|
||||
x86_64_outb(ATA_PRIMARY_LBAHIGH, (uint8_t)(lba >> 16));
|
||||
x86_64_outb(ATA_PRIMARY_COMMAND, 0x30); // write sectors
|
||||
|
||||
const uint16_t* buf = buffer;
|
||||
for (uint8_t i = 0; i < sector_count; i++) {
|
||||
if (!ata_poll()) {
|
||||
|
||||
return false;
|
||||
}
|
||||
x86_64_outsw(ATA_PRIMARY_DATA, buf, 256);
|
||||
buf += 256;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void ata_init(void);
|
||||
void ata_identify(void);
|
||||
|
||||
// Read `sector_count` 512-byte sectors starting at LBA `lba` into `buffer`.
|
||||
// Buffer must be large enough (sector_count * 512).
|
||||
bool ata_read_sectors(uint64_t lba, uint8_t sector_count, void* buffer);
|
||||
|
||||
bool ata_write_sectors(uint64_t lba, uint8_t sector_count, const void* buffer);
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "e9.h"
|
||||
#include <arch/x86_64/io.h>
|
||||
|
||||
void e9_putc(char c)
|
||||
{
|
||||
x86_64_outb(0xE9, c);
|
||||
}
|
||||
|
||||
void e9_puts(const char* str) {
|
||||
while (*str) {
|
||||
e9_putc(*str++);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void e9_putc(char c);
|
||||
@@ -0,0 +1,88 @@
|
||||
#include "gdt.h"
|
||||
#include "mm/memory.h"
|
||||
#include "mp/spinlock.h"
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
|
||||
struct gdt_desc {
|
||||
uint16_t limit;
|
||||
uint16_t base_low;
|
||||
uint8_t base_mid;
|
||||
uint8_t access;
|
||||
uint8_t granularity;
|
||||
uint8_t base_hi;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct tss_desc {
|
||||
uint16_t length;
|
||||
uint16_t base_low;
|
||||
uint8_t base_mid;
|
||||
uint8_t flags1;
|
||||
uint8_t flags2;
|
||||
uint8_t base_hi;
|
||||
uint32_t base_upper32;
|
||||
uint32_t reserved;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct gdt_ptr {
|
||||
uint16_t limit;
|
||||
uint64_t ptr;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct gdtr {
|
||||
struct gdt_desc entries[5];
|
||||
struct tss_desc tss;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct gdtr gdt = {0};
|
||||
struct gdt_ptr gdt_pointer = {0};
|
||||
struct tss kernel_tss = {0};
|
||||
spinlock_t s_gdt_lock = SPINLOCK_INIT;
|
||||
|
||||
extern void gdt_reload(void);
|
||||
extern void tss_reload(void);
|
||||
|
||||
|
||||
void x86_64_GDT_Initialize(void) {
|
||||
uint64_t flags;
|
||||
spinlock_acquire_irqsave(&s_gdt_lock, &flags);
|
||||
// Kernel code
|
||||
gdt.entries[1].access = 0b10011010;
|
||||
gdt.entries[1].granularity = 0b00100000;
|
||||
|
||||
// Kernel data
|
||||
gdt.entries[2].access = 0b10010010;
|
||||
|
||||
// User data
|
||||
gdt.entries[3].access = 0b11110010;
|
||||
|
||||
// User code
|
||||
gdt.entries[4].access = 0b11111010;
|
||||
gdt.entries[4].granularity = 0b00100000;
|
||||
|
||||
// TSS
|
||||
gdt.tss.length = sizeof(struct tss);
|
||||
gdt.tss.flags1 = 0b10001001;
|
||||
|
||||
// Set the pointer
|
||||
gdt_pointer.limit = sizeof(gdt) - 1;
|
||||
gdt_pointer.ptr = (uint64_t)&gdt;
|
||||
|
||||
gdt_reload();
|
||||
tss_reload();
|
||||
spinlock_release_irqrestore(&s_gdt_lock, flags);
|
||||
}
|
||||
|
||||
void gdt_load_tss(size_t addr) {
|
||||
uint64_t flags;
|
||||
spinlock_acquire_irqsave(&s_gdt_lock, &flags);
|
||||
gdt.tss.base_low = (uint16_t)addr;
|
||||
gdt.tss.base_mid = (uint8_t)(addr >> 16);
|
||||
gdt.tss.flags1 = 0b10001001;
|
||||
gdt.tss.base_hi = (uint8_t)(addr >> 24);
|
||||
gdt.tss.base_upper32 = (uint32_t)(addr >> 32);
|
||||
|
||||
tss_reload();
|
||||
spinlock_release_irqrestore(&s_gdt_lock, flags);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
|
||||
#define GDT_KERNEL_BASE 0x0
|
||||
#define GDT_KERNEL_CODE64 0x8
|
||||
#define GDT_KERNEL_DATA64 0x10
|
||||
#define GDT_USER_BASE 0x18
|
||||
#define GDT_USER_DATA64 0x18
|
||||
#define GDT_USER_CODE64 0x20
|
||||
#define GDT_TSS 0x28
|
||||
|
||||
struct tss {
|
||||
uint32_t reserved;
|
||||
uint64_t rsp0;
|
||||
uint64_t rsp1;
|
||||
uint64_t rsp2;
|
||||
uint64_t reserved2;
|
||||
uint64_t ist1;
|
||||
uint64_t ist2;
|
||||
uint64_t ist3;
|
||||
uint64_t ist4;
|
||||
uint64_t ist5;
|
||||
uint64_t ist6;
|
||||
uint64_t ist7;
|
||||
uint64_t reserved3;
|
||||
uint16_t reserved4;
|
||||
uint16_t iomap_base;
|
||||
} __attribute__((packed));
|
||||
|
||||
void x86_64_GDT_Initialize(void);
|
||||
void gdt_load_tss(size_t addr);
|
||||
@@ -0,0 +1,27 @@
|
||||
.intel_syntax noprefix
|
||||
.global x86_64_GDT_Load
|
||||
.extern gdt_pointer
|
||||
|
||||
.global gdt_reload
|
||||
gdt_reload:
|
||||
lgdt [rip + gdt_pointer]
|
||||
|
||||
push 8
|
||||
lea rax, [rip + .flush]
|
||||
push rax
|
||||
lretq
|
||||
|
||||
.flush:
|
||||
mov eax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
ret
|
||||
|
||||
.global tss_reload
|
||||
tss_reload:
|
||||
mov ax, 0x2B
|
||||
ltr ax
|
||||
ret
|
||||
@@ -0,0 +1,167 @@
|
||||
#include "pic.h"
|
||||
#include "io.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define PIC1_COMMAND_PORT 0x20
|
||||
#define PIC1_DATA_PORT 0x21
|
||||
#define PIC2_COMMAND_PORT 0xA0
|
||||
#define PIC2_DATA_PORT 0xA1
|
||||
|
||||
// Initialization Control Word 1
|
||||
// -----------------------------
|
||||
// 0 IC4 if set, the PIC expects to receive ICW4 during initialization
|
||||
// 1 SGNL if set, only 1 PIC in the system; if unset, the PIC is cascaded with slave PICs
|
||||
// and ICW3 must be sent to controller
|
||||
// 2 ADI call address interval, set: 4, not set: 8; ignored on x86, set to 0
|
||||
// 3 LTIM if set, operate in level triggered mode; if unset, operate in edge triggered mode
|
||||
// 4 INIT set to 1 to initialize PIC
|
||||
// 5-7 ignored on x86, set to 0
|
||||
|
||||
enum {
|
||||
PIC_ICW1_ICW4 = 0x01,
|
||||
PIC_ICW1_SINGLE = 0x02,
|
||||
PIC_ICW1_INTERVAL4 = 0x04,
|
||||
PIC_ICW1_LEVEL = 0x08,
|
||||
PIC_ICW1_INITIALIZE = 0x10
|
||||
} PIC_ICW1;
|
||||
|
||||
|
||||
// Initialization Control Word 4
|
||||
// -----------------------------
|
||||
// 0 uPM if set, PIC is in 80x86 mode; if cleared, in MCS-80/85 mode
|
||||
// 1 AEOI if set, on last interrupt acknowledge pulse, controller automatically performs
|
||||
// end of interrupt operation
|
||||
// 2 M/S only use if BUF is set; if set, selects buffer master; otherwise, selects buffer slave
|
||||
// 3 BUF if set, controller operates in buffered mode
|
||||
// 4 SFNM specially fully nested mode; used in systems with large number of cascaded controllers
|
||||
// 5-7 reserved, set to 0
|
||||
enum {
|
||||
PIC_ICW4_8086 = 0x1,
|
||||
PIC_ICW4_AUTO_EOI = 0x2,
|
||||
PIC_ICW4_BUFFER_MASTER = 0x4,
|
||||
PIC_ICW4_BUFFER_SLAVE = 0x0,
|
||||
PIC_ICW4_BUFFERRED = 0x8,
|
||||
PIC_ICW4_SFNM = 0x10,
|
||||
} PIC_ICW4;
|
||||
|
||||
|
||||
enum {
|
||||
PIC_CMD_END_OF_INTERRUPT = 0x20,
|
||||
PIC_CMD_READ_IRR = 0x0A,
|
||||
PIC_CMD_READ_ISR = 0x0B,
|
||||
} PIC_CMD;
|
||||
|
||||
|
||||
static uint16_t g_PicMask = 0xffff;
|
||||
static bool g_AutoEoi = false;
|
||||
|
||||
void i8259_SetMask(uint16_t newMask)
|
||||
{
|
||||
g_PicMask = newMask;
|
||||
x86_64_outb(PIC1_DATA_PORT, g_PicMask & 0xFF);
|
||||
x86_64_iowait();
|
||||
x86_64_outb(PIC2_DATA_PORT, g_PicMask >> 8);
|
||||
x86_64_iowait();
|
||||
}
|
||||
|
||||
uint16_t i8259_GetMask()
|
||||
{
|
||||
return x86_64_inb(PIC1_DATA_PORT) | (x86_64_inb(PIC2_DATA_PORT) << 8);
|
||||
}
|
||||
|
||||
void i8259_Configure(uint8_t offsetPic1, uint8_t offsetPic2, bool autoEoi)
|
||||
{
|
||||
// Mask everything
|
||||
i8259_SetMask(0xFFFF);
|
||||
|
||||
// initialization control word 1
|
||||
x86_64_outb(PIC1_COMMAND_PORT, PIC_ICW1_ICW4 | PIC_ICW1_INITIALIZE);
|
||||
x86_64_iowait();
|
||||
x86_64_outb(PIC2_COMMAND_PORT, PIC_ICW1_ICW4 | PIC_ICW1_INITIALIZE);
|
||||
x86_64_iowait();
|
||||
|
||||
// initialization control word 2 - the offsets
|
||||
x86_64_outb(PIC1_DATA_PORT, offsetPic1);
|
||||
x86_64_iowait();
|
||||
x86_64_outb(PIC2_DATA_PORT, offsetPic2);
|
||||
x86_64_iowait();
|
||||
|
||||
// initialization control word 3
|
||||
x86_64_outb(PIC1_DATA_PORT, 0x4); // tell PIC1 that it has a slave at IRQ2 (0000 0100)
|
||||
x86_64_iowait();
|
||||
x86_64_outb(PIC2_DATA_PORT, 0x2); // tell PIC2 its cascade identity (0000 0010)
|
||||
x86_64_iowait();
|
||||
|
||||
// initialization control word 4
|
||||
uint8_t icw4 = PIC_ICW4_8086;
|
||||
if (autoEoi) {
|
||||
icw4 |= PIC_ICW4_AUTO_EOI;
|
||||
}
|
||||
|
||||
x86_64_outb(PIC1_DATA_PORT, icw4);
|
||||
x86_64_iowait();
|
||||
x86_64_outb(PIC2_DATA_PORT, icw4);
|
||||
x86_64_iowait();
|
||||
|
||||
// mask all interrupts until they are enabled by the device driver
|
||||
i8259_SetMask(0xFFFF);
|
||||
}
|
||||
|
||||
void i8259_SendEndOfInterrupt(int irq)
|
||||
{
|
||||
if (irq >= 8)
|
||||
x86_64_outb(PIC2_COMMAND_PORT, PIC_CMD_END_OF_INTERRUPT);
|
||||
x86_64_outb(PIC1_COMMAND_PORT, PIC_CMD_END_OF_INTERRUPT);
|
||||
}
|
||||
|
||||
void i8259_Disable()
|
||||
{
|
||||
i8259_SetMask(0xFFFF);
|
||||
}
|
||||
|
||||
void i8259_Mask(int irq)
|
||||
{
|
||||
i8259_SetMask(g_PicMask | (1 << irq));
|
||||
}
|
||||
|
||||
void i8259_Unmask(int irq)
|
||||
{
|
||||
i8259_SetMask(g_PicMask & ~(1 << irq));
|
||||
}
|
||||
|
||||
uint16_t i8259_ReadIrqRequestRegister()
|
||||
{
|
||||
x86_64_outb(PIC1_COMMAND_PORT, PIC_CMD_READ_IRR);
|
||||
x86_64_outb(PIC2_COMMAND_PORT, PIC_CMD_READ_IRR);
|
||||
return ((uint16_t)x86_64_inb(PIC2_COMMAND_PORT)) | (((uint16_t)x86_64_inb(PIC2_COMMAND_PORT)) << 8);
|
||||
}
|
||||
|
||||
uint16_t i8259_ReadInServiceRegister()
|
||||
{
|
||||
x86_64_outb(PIC1_COMMAND_PORT, PIC_CMD_READ_ISR);
|
||||
x86_64_outb(PIC2_COMMAND_PORT, PIC_CMD_READ_ISR);
|
||||
return ((uint16_t)x86_64_inb(PIC2_COMMAND_PORT)) | (((uint16_t)x86_64_inb(PIC2_COMMAND_PORT)) << 8);
|
||||
}
|
||||
|
||||
bool i8259_Probe()
|
||||
{
|
||||
i8259_Disable();
|
||||
i8259_SetMask(0x1337);
|
||||
return i8259_GetMask() == 0x1337;
|
||||
}
|
||||
|
||||
static const PICDriver g_PicDriver = {
|
||||
.Name = "8259 PIC",
|
||||
.Probe = &i8259_Probe,
|
||||
.Initialize = &i8259_Configure,
|
||||
.Disable = &i8259_Disable,
|
||||
.SendEndOfInterrupt = &i8259_SendEndOfInterrupt,
|
||||
.Mask = &i8259_Mask,
|
||||
.Unmask = &i8259_Unmask,
|
||||
};
|
||||
|
||||
const PICDriver* i8259_GetDriver()
|
||||
{
|
||||
return &g_PicDriver;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "pic.h"
|
||||
|
||||
const PICDriver* i8259_GetDriver();
|
||||
uint16_t i8259_GetMask();
|
||||
void i8259_SetMask(uint16_t newMask);
|
||||
|
||||
void i8259_Configure(uint8_t offsetPic1, uint8_t offsetPic2, bool autoEoi);
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "idt.h"
|
||||
#include "util/binary.h"
|
||||
|
||||
|
||||
IDTEntry g_IDT[256];
|
||||
IDTDescriptor g_IDTDescriptor = { sizeof(g_IDT) - 1, g_IDT };
|
||||
|
||||
extern void x86_64_IDT_Load(IDTDescriptor* descriptor);
|
||||
|
||||
void x86_64_IDT_SetGate(int interrupt, void* base, uint16_t segmentDescriptor, uint8_t flags)
|
||||
{
|
||||
uintptr_t addr = (uintptr_t)base;
|
||||
g_IDT[interrupt].BaseLow = addr & 0xFFFF;
|
||||
g_IDT[interrupt].SegmentSelector = segmentDescriptor;
|
||||
g_IDT[interrupt].IST = 0;
|
||||
g_IDT[interrupt].Flags = flags;
|
||||
g_IDT[interrupt].BaseMid = (addr >> 16) & 0xFFFF;
|
||||
g_IDT[interrupt].BaseHigh = (addr >> 32) & 0xFFFFFFFF;
|
||||
g_IDT[interrupt].Reserved = 0;
|
||||
}
|
||||
void x86_64_IDT_EnableGate(int interrupt)
|
||||
{
|
||||
FLAG_SET(g_IDT[interrupt].Flags, IDT_FLAG_PRESENT);
|
||||
}
|
||||
|
||||
void x86_64_IDT_DisableGate(int interrupt)
|
||||
{
|
||||
FLAG_UNSET(g_IDT[interrupt].Flags, IDT_FLAG_PRESENT);
|
||||
}
|
||||
|
||||
|
||||
void x86_64_IDT_Initialize(void)
|
||||
{
|
||||
x86_64_IDT_Load(&g_IDTDescriptor);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
IDT_FLAG_GATE_TASK = 0x5,
|
||||
IDT_FLAG_GATE_16BIT_INT = 0x6,
|
||||
IDT_FLAG_GATE_16BIT_TRAP = 0x7,
|
||||
IDT_FLAG_GATE_32BIT_INT = 0xE,
|
||||
IDT_FLAG_GATE_32BIT_TRAP = 0xF,
|
||||
|
||||
IDT_FLAG_RING0 = (0 << 5),
|
||||
IDT_FLAG_RING1 = (1 << 5),
|
||||
IDT_FLAG_RING2 = (2 << 5),
|
||||
IDT_FLAG_RING3 = (3 << 5),
|
||||
|
||||
IDT_FLAG_PRESENT = 0x80,
|
||||
|
||||
} IDT_FLAGS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t BaseLow;
|
||||
uint16_t SegmentSelector;
|
||||
uint8_t IST; // Interrupt Stack Table (0 = default)
|
||||
uint8_t Flags;
|
||||
uint16_t BaseMid;
|
||||
uint32_t BaseHigh;
|
||||
uint32_t Reserved;
|
||||
} __attribute__((packed)) IDTEntry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t Limit;
|
||||
IDTEntry* Ptr;
|
||||
} __attribute__((packed)) IDTDescriptor;
|
||||
|
||||
|
||||
void x86_64_IDT_Initialize(void);
|
||||
void x86_64_IDT_SetGate(int interrupt, void* base, uint16_t segmentDescriptor, uint8_t flags);
|
||||
void x86_64_IDT_EnableGate(int interrupt);
|
||||
void x86_64_IDT_DisableGate(int interrupt);
|
||||
@@ -0,0 +1,6 @@
|
||||
.intel_syntax noprefix
|
||||
.global x86_64_IDT_Load
|
||||
|
||||
x86_64_IDT_Load:
|
||||
lidt [rdi] # descriptor in RDI
|
||||
ret
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
void x86_64_outb(uint16_t port, uint8_t value);
|
||||
uint8_t x86_64_inb(uint16_t port);
|
||||
uint16_t x86_64_inw(uint16_t port);
|
||||
void x86_64_outw(uint16_t port, uint16_t value);
|
||||
void x86_64_insw(uint16_t port, uint16_t* buffer, uint32_t count);
|
||||
void x86_64_outl(uint16_t port, uint32_t value);
|
||||
uint32_t x86_64_inl(uint16_t port);
|
||||
void x86_64_outsw(uint16_t port, uint16_t* buffer, uint32_t count);
|
||||
void x86_64_iowait(void);
|
||||
void x86_64_Panic(void) __attribute__((noreturn));
|
||||
void x86_64_EnableInterrupts(void);
|
||||
void x86_64_DisableInterrupts(void);
|
||||
void x86_64_crashme(void);
|
||||
@@ -0,0 +1,96 @@
|
||||
.intel_syntax noprefix
|
||||
|
||||
.global x86_64_outb
|
||||
x86_64_outb:
|
||||
mov dx, di
|
||||
mov al, sil
|
||||
out dx, al
|
||||
ret
|
||||
|
||||
.global x86_64_inb
|
||||
x86_64_inb:
|
||||
mov dx, di
|
||||
xor eax, eax
|
||||
in al, dx
|
||||
ret
|
||||
|
||||
.global x86_64_inw
|
||||
x86_64_inw:
|
||||
mov dx, di
|
||||
xor eax, eax
|
||||
in ax, dx
|
||||
ret
|
||||
|
||||
.global x86_64_outw
|
||||
x86_64_outw:
|
||||
mov dx, di
|
||||
mov ax, si
|
||||
out dx, ax
|
||||
ret
|
||||
|
||||
.global x86_64_outl
|
||||
x86_64_outl:
|
||||
mov dx, di
|
||||
mov eax, esi
|
||||
out dx, eax
|
||||
ret
|
||||
|
||||
.global x86_64_inl
|
||||
x86_64_inl:
|
||||
mov dx, di
|
||||
xor eax, eax
|
||||
in eax, dx
|
||||
ret
|
||||
|
||||
.global x86_64_insw
|
||||
x86_64_insw:
|
||||
test rdx, rdx
|
||||
jz .inswdone
|
||||
mov rcx, rdx
|
||||
mov dx, di
|
||||
mov rdi, rsi
|
||||
cld
|
||||
rep insw
|
||||
.inswdone:
|
||||
ret
|
||||
|
||||
.global x86_64_outsw
|
||||
x86_64_outsw:
|
||||
test rdx, rdx
|
||||
jz .outswdone
|
||||
mov rcx, rdx
|
||||
mov dx, di
|
||||
mov rsi, rsi
|
||||
cld
|
||||
rep outsw
|
||||
.outswdone:
|
||||
ret
|
||||
|
||||
.global x86_64_Panic
|
||||
x86_64_Panic:
|
||||
cli
|
||||
hlt
|
||||
1: jmp 1b
|
||||
|
||||
.global x86_64_EnableInterrupts
|
||||
x86_64_EnableInterrupts:
|
||||
sti
|
||||
ret
|
||||
|
||||
.global x86_64_DisableInterrupts
|
||||
x86_64_DisableInterrupts:
|
||||
cli
|
||||
ret
|
||||
|
||||
.global x86_64_iowait
|
||||
x86_64_iowait:
|
||||
out 0x80, al // classic I/O wait
|
||||
ret
|
||||
|
||||
.global x86_64_crashme
|
||||
x86_64_crashme:
|
||||
xor rdx, rdx
|
||||
mov rax, 1
|
||||
mov rbx, 0
|
||||
div rbx
|
||||
ret
|
||||
@@ -0,0 +1,65 @@
|
||||
#include "irq.h"
|
||||
#include "i8259.h"
|
||||
#include "io.h"
|
||||
#include <stddef.h>
|
||||
#include <util/arrays.h>
|
||||
#include "stdio.h"
|
||||
#include <debug.h>
|
||||
|
||||
#define PIC_REMAP_OFFSET 0x20
|
||||
#define MODULE "PIC"
|
||||
|
||||
IRQHandler g_IRQHandlers[16];
|
||||
static const PICDriver* g_Driver = NULL;
|
||||
|
||||
void x86_64_IRQ_Handler(Registers *regs)
|
||||
{
|
||||
int irq = regs->interrupt - PIC_REMAP_OFFSET;
|
||||
|
||||
if (g_IRQHandlers[irq] != NULL)
|
||||
{
|
||||
// handle IRQ
|
||||
g_IRQHandlers[irq](regs);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_warn(MODULE, "Unhandled IRQ %d...", irq);
|
||||
}
|
||||
|
||||
// send EOI
|
||||
g_Driver->SendEndOfInterrupt(irq);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void x86_64_IRQ_Initialize(void)
|
||||
{
|
||||
const PICDriver* drivers[] = {
|
||||
i8259_GetDriver(),
|
||||
};
|
||||
|
||||
for (int i = 0; i < SIZE(drivers); i++) {
|
||||
if (drivers[i]->Probe()) {
|
||||
g_Driver = drivers[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Driver == NULL) {
|
||||
log_warn(MODULE, "No PIC found!");
|
||||
return;
|
||||
}
|
||||
|
||||
log_info(MODULE, "Found %s PIC.", g_Driver->Name);
|
||||
g_Driver->Initialize(PIC_REMAP_OFFSET, PIC_REMAP_OFFSET + 8, false);
|
||||
|
||||
// register ISR handlers for each of the 16 irq lines
|
||||
for (int i = 0; i < 16; i++)
|
||||
x86_64_ISR_RegisterHandler(PIC_REMAP_OFFSET + i, x86_64_IRQ_Handler);
|
||||
|
||||
x86_64_EnableInterrupts();
|
||||
}
|
||||
|
||||
void x86_64_IRQ_RegisterHandler(int irq, IRQHandler handler)
|
||||
{
|
||||
g_IRQHandlers[irq] = handler;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "isr.h"
|
||||
|
||||
|
||||
typedef void (*IRQHandler)(Registers* regs);
|
||||
|
||||
void x86_64_IRQ_Initialize();
|
||||
void x86_64_IRQ_RegisterHandler(int irq, IRQHandler handler);
|
||||
@@ -0,0 +1,82 @@
|
||||
// ... includes ...
|
||||
#include "io.h"
|
||||
#include "debug.h"
|
||||
#include "arch/x86_64/isr.h"
|
||||
#include "idt.h"
|
||||
#define MODULE "ISR"
|
||||
|
||||
|
||||
ISRHandler g_ISRHandlers[256];
|
||||
static const char* const g_Exceptions[] = {
|
||||
"Divide by zero error",
|
||||
"Debug",
|
||||
"Non-maskable Interrupt",
|
||||
"Breakpoint",
|
||||
"Overflow",
|
||||
"Bound Range Exceeded",
|
||||
"Invalid Opcode",
|
||||
"Device Not Available",
|
||||
"Double Fault",
|
||||
"Coprocessor Segment Overrun",
|
||||
"Invalid TSS",
|
||||
"Segment Not Present",
|
||||
"Stack-Segment Fault",
|
||||
"General Protection Fault",
|
||||
"Page Fault",
|
||||
"",
|
||||
"x87 Floating-Point Exception",
|
||||
"Alignment Check",
|
||||
"Machine Check",
|
||||
"SIMD Floating-Point Exception",
|
||||
"Virtualization Exception",
|
||||
"Control Protection Exception ",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Hypervisor Injection Exception",
|
||||
"VMM Communication Exception",
|
||||
"Security Exception",
|
||||
""
|
||||
};
|
||||
|
||||
extern void x86_64_ISR_InitializeGates(void); // defined in isrs_gen.c
|
||||
|
||||
void x86_64_ISR_Initialize(void)
|
||||
{
|
||||
x86_64_ISR_InitializeGates();
|
||||
for (int i = 0; i < 256; i++)
|
||||
x86_64_IDT_EnableGate(i);
|
||||
x86_64_IDT_DisableGate(0x80); // syscall gate if you want
|
||||
}
|
||||
|
||||
void __attribute__((used)) x86_64_ISR_Handler(Registers* regs)
|
||||
{
|
||||
if (g_ISRHandlers[regs->interrupt])
|
||||
g_ISRHandlers[regs->interrupt](regs);
|
||||
else if (regs->interrupt >= 32)
|
||||
log_err(MODULE, "Unhandled interrupt %d!", regs->interrupt);
|
||||
else {
|
||||
// panic log (use regs->rax etc. now)
|
||||
log_crit(MODULE, "KERNEL PANIC! Exception %d (%s)", regs->interrupt, g_Exceptions[regs->interrupt]);
|
||||
// ... print registers with rax/rbx etc. ...
|
||||
log_crit(MODULE, " rax=%x rbx=%x rcx=%x rdx=%x rsi=%x rdi=%x",
|
||||
regs->rax, regs->rbx, regs->rcx, regs->rdx, regs->rsi, regs->rdi);
|
||||
|
||||
log_crit(MODULE, " rsp=%x rbp=%x rip=%x rflags=%x cs=%x ss=%x",
|
||||
regs->rsp, regs->rbp, regs->rip, regs->rflags, regs->cs, regs->ss);
|
||||
|
||||
log_crit(MODULE, " interrupt=%x errorcode=%x", regs->interrupt, regs->error);
|
||||
|
||||
log_crit(MODULE, "KERNEL PANIC!");
|
||||
x86_64_Panic();
|
||||
}
|
||||
}
|
||||
|
||||
void x86_64_ISR_RegisterHandler(int interrupt, ISRHandler handler)
|
||||
{
|
||||
g_ISRHandlers[interrupt] = handler;
|
||||
x86_64_IDT_EnableGate(interrupt);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
|
||||
uint64_t rdi, rsi, rbp, rdx, rcx, rbx, rax;
|
||||
uint64_t interrupt, error;
|
||||
uint64_t rip, cs, rflags, rsp, ss;
|
||||
} __attribute__((packed)) Registers;
|
||||
|
||||
typedef void (*ISRHandler)(Registers* regs);
|
||||
|
||||
void x86_64_ISR_Initialize(void);
|
||||
void x86_64_ISR_RegisterHandler(int interrupt, ISRHandler handler);
|
||||
@@ -0,0 +1,58 @@
|
||||
.intel_syntax noprefix
|
||||
.extern x86_64_ISR_Handler
|
||||
|
||||
.macro ISR_NOERRORCODE num
|
||||
.global x86_64_ISR\num
|
||||
x86_64_ISR\num:
|
||||
push 0
|
||||
push \num
|
||||
jmp isr_common
|
||||
.endm
|
||||
|
||||
.macro ISR_ERRORCODE num
|
||||
.global x86_64_ISR\num
|
||||
x86_64_ISR\num:
|
||||
push \num
|
||||
jmp isr_common
|
||||
.endm
|
||||
|
||||
.include "arch/x86_64/isrs_gen.inc" // ← update path if needed
|
||||
|
||||
isr_common:
|
||||
push rax
|
||||
push rbx
|
||||
push rcx
|
||||
push rdx
|
||||
push rbp
|
||||
push rsi
|
||||
push rdi
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
|
||||
mov rdi, rsp // Registers* in RDI
|
||||
call x86_64_ISR_Handler
|
||||
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rdi
|
||||
pop rsi
|
||||
pop rbp
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rbx
|
||||
pop rax
|
||||
|
||||
add rsp, 16 // pop interrupt + error code
|
||||
iretq
|
||||
@@ -0,0 +1,520 @@
|
||||
// !!! THIS FILE IS AUTOGENERATED !!!
|
||||
#include "idt.h"
|
||||
#include "gdt.h"
|
||||
|
||||
void x86_64_ISR0();
|
||||
void x86_64_ISR1();
|
||||
void x86_64_ISR2();
|
||||
void x86_64_ISR3();
|
||||
void x86_64_ISR4();
|
||||
void x86_64_ISR5();
|
||||
void x86_64_ISR6();
|
||||
void x86_64_ISR7();
|
||||
void x86_64_ISR8();
|
||||
void x86_64_ISR9();
|
||||
void x86_64_ISR10();
|
||||
void x86_64_ISR11();
|
||||
void x86_64_ISR12();
|
||||
void x86_64_ISR13();
|
||||
void x86_64_ISR14();
|
||||
void x86_64_ISR15();
|
||||
void x86_64_ISR16();
|
||||
void x86_64_ISR17();
|
||||
void x86_64_ISR18();
|
||||
void x86_64_ISR19();
|
||||
void x86_64_ISR20();
|
||||
void x86_64_ISR21();
|
||||
void x86_64_ISR22();
|
||||
void x86_64_ISR23();
|
||||
void x86_64_ISR24();
|
||||
void x86_64_ISR25();
|
||||
void x86_64_ISR26();
|
||||
void x86_64_ISR27();
|
||||
void x86_64_ISR28();
|
||||
void x86_64_ISR29();
|
||||
void x86_64_ISR30();
|
||||
void x86_64_ISR31();
|
||||
void x86_64_ISR32();
|
||||
void x86_64_ISR33();
|
||||
void x86_64_ISR34();
|
||||
void x86_64_ISR35();
|
||||
void x86_64_ISR36();
|
||||
void x86_64_ISR37();
|
||||
void x86_64_ISR38();
|
||||
void x86_64_ISR39();
|
||||
void x86_64_ISR40();
|
||||
void x86_64_ISR41();
|
||||
void x86_64_ISR42();
|
||||
void x86_64_ISR43();
|
||||
void x86_64_ISR44();
|
||||
void x86_64_ISR45();
|
||||
void x86_64_ISR46();
|
||||
void x86_64_ISR47();
|
||||
void x86_64_ISR48();
|
||||
void x86_64_ISR49();
|
||||
void x86_64_ISR50();
|
||||
void x86_64_ISR51();
|
||||
void x86_64_ISR52();
|
||||
void x86_64_ISR53();
|
||||
void x86_64_ISR54();
|
||||
void x86_64_ISR55();
|
||||
void x86_64_ISR56();
|
||||
void x86_64_ISR57();
|
||||
void x86_64_ISR58();
|
||||
void x86_64_ISR59();
|
||||
void x86_64_ISR60();
|
||||
void x86_64_ISR61();
|
||||
void x86_64_ISR62();
|
||||
void x86_64_ISR63();
|
||||
void x86_64_ISR64();
|
||||
void x86_64_ISR65();
|
||||
void x86_64_ISR66();
|
||||
void x86_64_ISR67();
|
||||
void x86_64_ISR68();
|
||||
void x86_64_ISR69();
|
||||
void x86_64_ISR70();
|
||||
void x86_64_ISR71();
|
||||
void x86_64_ISR72();
|
||||
void x86_64_ISR73();
|
||||
void x86_64_ISR74();
|
||||
void x86_64_ISR75();
|
||||
void x86_64_ISR76();
|
||||
void x86_64_ISR77();
|
||||
void x86_64_ISR78();
|
||||
void x86_64_ISR79();
|
||||
void x86_64_ISR80();
|
||||
void x86_64_ISR81();
|
||||
void x86_64_ISR82();
|
||||
void x86_64_ISR83();
|
||||
void x86_64_ISR84();
|
||||
void x86_64_ISR85();
|
||||
void x86_64_ISR86();
|
||||
void x86_64_ISR87();
|
||||
void x86_64_ISR88();
|
||||
void x86_64_ISR89();
|
||||
void x86_64_ISR90();
|
||||
void x86_64_ISR91();
|
||||
void x86_64_ISR92();
|
||||
void x86_64_ISR93();
|
||||
void x86_64_ISR94();
|
||||
void x86_64_ISR95();
|
||||
void x86_64_ISR96();
|
||||
void x86_64_ISR97();
|
||||
void x86_64_ISR98();
|
||||
void x86_64_ISR99();
|
||||
void x86_64_ISR100();
|
||||
void x86_64_ISR101();
|
||||
void x86_64_ISR102();
|
||||
void x86_64_ISR103();
|
||||
void x86_64_ISR104();
|
||||
void x86_64_ISR105();
|
||||
void x86_64_ISR106();
|
||||
void x86_64_ISR107();
|
||||
void x86_64_ISR108();
|
||||
void x86_64_ISR109();
|
||||
void x86_64_ISR110();
|
||||
void x86_64_ISR111();
|
||||
void x86_64_ISR112();
|
||||
void x86_64_ISR113();
|
||||
void x86_64_ISR114();
|
||||
void x86_64_ISR115();
|
||||
void x86_64_ISR116();
|
||||
void x86_64_ISR117();
|
||||
void x86_64_ISR118();
|
||||
void x86_64_ISR119();
|
||||
void x86_64_ISR120();
|
||||
void x86_64_ISR121();
|
||||
void x86_64_ISR122();
|
||||
void x86_64_ISR123();
|
||||
void x86_64_ISR124();
|
||||
void x86_64_ISR125();
|
||||
void x86_64_ISR126();
|
||||
void x86_64_ISR127();
|
||||
void x86_64_ISR128();
|
||||
void x86_64_ISR129();
|
||||
void x86_64_ISR130();
|
||||
void x86_64_ISR131();
|
||||
void x86_64_ISR132();
|
||||
void x86_64_ISR133();
|
||||
void x86_64_ISR134();
|
||||
void x86_64_ISR135();
|
||||
void x86_64_ISR136();
|
||||
void x86_64_ISR137();
|
||||
void x86_64_ISR138();
|
||||
void x86_64_ISR139();
|
||||
void x86_64_ISR140();
|
||||
void x86_64_ISR141();
|
||||
void x86_64_ISR142();
|
||||
void x86_64_ISR143();
|
||||
void x86_64_ISR144();
|
||||
void x86_64_ISR145();
|
||||
void x86_64_ISR146();
|
||||
void x86_64_ISR147();
|
||||
void x86_64_ISR148();
|
||||
void x86_64_ISR149();
|
||||
void x86_64_ISR150();
|
||||
void x86_64_ISR151();
|
||||
void x86_64_ISR152();
|
||||
void x86_64_ISR153();
|
||||
void x86_64_ISR154();
|
||||
void x86_64_ISR155();
|
||||
void x86_64_ISR156();
|
||||
void x86_64_ISR157();
|
||||
void x86_64_ISR158();
|
||||
void x86_64_ISR159();
|
||||
void x86_64_ISR160();
|
||||
void x86_64_ISR161();
|
||||
void x86_64_ISR162();
|
||||
void x86_64_ISR163();
|
||||
void x86_64_ISR164();
|
||||
void x86_64_ISR165();
|
||||
void x86_64_ISR166();
|
||||
void x86_64_ISR167();
|
||||
void x86_64_ISR168();
|
||||
void x86_64_ISR169();
|
||||
void x86_64_ISR170();
|
||||
void x86_64_ISR171();
|
||||
void x86_64_ISR172();
|
||||
void x86_64_ISR173();
|
||||
void x86_64_ISR174();
|
||||
void x86_64_ISR175();
|
||||
void x86_64_ISR176();
|
||||
void x86_64_ISR177();
|
||||
void x86_64_ISR178();
|
||||
void x86_64_ISR179();
|
||||
void x86_64_ISR180();
|
||||
void x86_64_ISR181();
|
||||
void x86_64_ISR182();
|
||||
void x86_64_ISR183();
|
||||
void x86_64_ISR184();
|
||||
void x86_64_ISR185();
|
||||
void x86_64_ISR186();
|
||||
void x86_64_ISR187();
|
||||
void x86_64_ISR188();
|
||||
void x86_64_ISR189();
|
||||
void x86_64_ISR190();
|
||||
void x86_64_ISR191();
|
||||
void x86_64_ISR192();
|
||||
void x86_64_ISR193();
|
||||
void x86_64_ISR194();
|
||||
void x86_64_ISR195();
|
||||
void x86_64_ISR196();
|
||||
void x86_64_ISR197();
|
||||
void x86_64_ISR198();
|
||||
void x86_64_ISR199();
|
||||
void x86_64_ISR200();
|
||||
void x86_64_ISR201();
|
||||
void x86_64_ISR202();
|
||||
void x86_64_ISR203();
|
||||
void x86_64_ISR204();
|
||||
void x86_64_ISR205();
|
||||
void x86_64_ISR206();
|
||||
void x86_64_ISR207();
|
||||
void x86_64_ISR208();
|
||||
void x86_64_ISR209();
|
||||
void x86_64_ISR210();
|
||||
void x86_64_ISR211();
|
||||
void x86_64_ISR212();
|
||||
void x86_64_ISR213();
|
||||
void x86_64_ISR214();
|
||||
void x86_64_ISR215();
|
||||
void x86_64_ISR216();
|
||||
void x86_64_ISR217();
|
||||
void x86_64_ISR218();
|
||||
void x86_64_ISR219();
|
||||
void x86_64_ISR220();
|
||||
void x86_64_ISR221();
|
||||
void x86_64_ISR222();
|
||||
void x86_64_ISR223();
|
||||
void x86_64_ISR224();
|
||||
void x86_64_ISR225();
|
||||
void x86_64_ISR226();
|
||||
void x86_64_ISR227();
|
||||
void x86_64_ISR228();
|
||||
void x86_64_ISR229();
|
||||
void x86_64_ISR230();
|
||||
void x86_64_ISR231();
|
||||
void x86_64_ISR232();
|
||||
void x86_64_ISR233();
|
||||
void x86_64_ISR234();
|
||||
void x86_64_ISR235();
|
||||
void x86_64_ISR236();
|
||||
void x86_64_ISR237();
|
||||
void x86_64_ISR238();
|
||||
void x86_64_ISR239();
|
||||
void x86_64_ISR240();
|
||||
void x86_64_ISR241();
|
||||
void x86_64_ISR242();
|
||||
void x86_64_ISR243();
|
||||
void x86_64_ISR244();
|
||||
void x86_64_ISR245();
|
||||
void x86_64_ISR246();
|
||||
void x86_64_ISR247();
|
||||
void x86_64_ISR248();
|
||||
void x86_64_ISR249();
|
||||
void x86_64_ISR250();
|
||||
void x86_64_ISR251();
|
||||
void x86_64_ISR252();
|
||||
void x86_64_ISR253();
|
||||
void x86_64_ISR254();
|
||||
void x86_64_ISR255();
|
||||
|
||||
void x86_64_ISR_InitializeGates()
|
||||
{
|
||||
x86_64_IDT_SetGate(0, x86_64_ISR0, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(1, x86_64_ISR1, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(2, x86_64_ISR2, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(3, x86_64_ISR3, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(4, x86_64_ISR4, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(5, x86_64_ISR5, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(6, x86_64_ISR6, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(7, x86_64_ISR7, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(8, x86_64_ISR8, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(9, x86_64_ISR9, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(10, x86_64_ISR10, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(11, x86_64_ISR11, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(12, x86_64_ISR12, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(13, x86_64_ISR13, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(14, x86_64_ISR14, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(15, x86_64_ISR15, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(16, x86_64_ISR16, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(17, x86_64_ISR17, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(18, x86_64_ISR18, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(19, x86_64_ISR19, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(20, x86_64_ISR20, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(21, x86_64_ISR21, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(22, x86_64_ISR22, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(23, x86_64_ISR23, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(24, x86_64_ISR24, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(25, x86_64_ISR25, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(26, x86_64_ISR26, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(27, x86_64_ISR27, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(28, x86_64_ISR28, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(29, x86_64_ISR29, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(30, x86_64_ISR30, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(31, x86_64_ISR31, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(32, x86_64_ISR32, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(33, x86_64_ISR33, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(34, x86_64_ISR34, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(35, x86_64_ISR35, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(36, x86_64_ISR36, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(37, x86_64_ISR37, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(38, x86_64_ISR38, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(39, x86_64_ISR39, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(40, x86_64_ISR40, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(41, x86_64_ISR41, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(42, x86_64_ISR42, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(43, x86_64_ISR43, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(44, x86_64_ISR44, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(45, x86_64_ISR45, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(46, x86_64_ISR46, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(47, x86_64_ISR47, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(48, x86_64_ISR48, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(49, x86_64_ISR49, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(50, x86_64_ISR50, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(51, x86_64_ISR51, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(52, x86_64_ISR52, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(53, x86_64_ISR53, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(54, x86_64_ISR54, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(55, x86_64_ISR55, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(56, x86_64_ISR56, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(57, x86_64_ISR57, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(58, x86_64_ISR58, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(59, x86_64_ISR59, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(60, x86_64_ISR60, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(61, x86_64_ISR61, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(62, x86_64_ISR62, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(63, x86_64_ISR63, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(64, x86_64_ISR64, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(65, x86_64_ISR65, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(66, x86_64_ISR66, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(67, x86_64_ISR67, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(68, x86_64_ISR68, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(69, x86_64_ISR69, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(70, x86_64_ISR70, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(71, x86_64_ISR71, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(72, x86_64_ISR72, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(73, x86_64_ISR73, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(74, x86_64_ISR74, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(75, x86_64_ISR75, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(76, x86_64_ISR76, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(77, x86_64_ISR77, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(78, x86_64_ISR78, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(79, x86_64_ISR79, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(80, x86_64_ISR80, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(81, x86_64_ISR81, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(82, x86_64_ISR82, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(83, x86_64_ISR83, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(84, x86_64_ISR84, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(85, x86_64_ISR85, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(86, x86_64_ISR86, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(87, x86_64_ISR87, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(88, x86_64_ISR88, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(89, x86_64_ISR89, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(90, x86_64_ISR90, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(91, x86_64_ISR91, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(92, x86_64_ISR92, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(93, x86_64_ISR93, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(94, x86_64_ISR94, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(95, x86_64_ISR95, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(96, x86_64_ISR96, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(97, x86_64_ISR97, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(98, x86_64_ISR98, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(99, x86_64_ISR99, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(100, x86_64_ISR100, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(101, x86_64_ISR101, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(102, x86_64_ISR102, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(103, x86_64_ISR103, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(104, x86_64_ISR104, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(105, x86_64_ISR105, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(106, x86_64_ISR106, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(107, x86_64_ISR107, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(108, x86_64_ISR108, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(109, x86_64_ISR109, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(110, x86_64_ISR110, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(111, x86_64_ISR111, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(112, x86_64_ISR112, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(113, x86_64_ISR113, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(114, x86_64_ISR114, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(115, x86_64_ISR115, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(116, x86_64_ISR116, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(117, x86_64_ISR117, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(118, x86_64_ISR118, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(119, x86_64_ISR119, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(120, x86_64_ISR120, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(121, x86_64_ISR121, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(122, x86_64_ISR122, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(123, x86_64_ISR123, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(124, x86_64_ISR124, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(125, x86_64_ISR125, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(126, x86_64_ISR126, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(127, x86_64_ISR127, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(128, x86_64_ISR128, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(129, x86_64_ISR129, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(130, x86_64_ISR130, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(131, x86_64_ISR131, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(132, x86_64_ISR132, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(133, x86_64_ISR133, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(134, x86_64_ISR134, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(135, x86_64_ISR135, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(136, x86_64_ISR136, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(137, x86_64_ISR137, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(138, x86_64_ISR138, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(139, x86_64_ISR139, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(140, x86_64_ISR140, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(141, x86_64_ISR141, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(142, x86_64_ISR142, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(143, x86_64_ISR143, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(144, x86_64_ISR144, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(145, x86_64_ISR145, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(146, x86_64_ISR146, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(147, x86_64_ISR147, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(148, x86_64_ISR148, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(149, x86_64_ISR149, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(150, x86_64_ISR150, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(151, x86_64_ISR151, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(152, x86_64_ISR152, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(153, x86_64_ISR153, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(154, x86_64_ISR154, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(155, x86_64_ISR155, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(156, x86_64_ISR156, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(157, x86_64_ISR157, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(158, x86_64_ISR158, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(159, x86_64_ISR159, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(160, x86_64_ISR160, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(161, x86_64_ISR161, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(162, x86_64_ISR162, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(163, x86_64_ISR163, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(164, x86_64_ISR164, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(165, x86_64_ISR165, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(166, x86_64_ISR166, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(167, x86_64_ISR167, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(168, x86_64_ISR168, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(169, x86_64_ISR169, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(170, x86_64_ISR170, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(171, x86_64_ISR171, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(172, x86_64_ISR172, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(173, x86_64_ISR173, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(174, x86_64_ISR174, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(175, x86_64_ISR175, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(176, x86_64_ISR176, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(177, x86_64_ISR177, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(178, x86_64_ISR178, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(179, x86_64_ISR179, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(180, x86_64_ISR180, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(181, x86_64_ISR181, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(182, x86_64_ISR182, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(183, x86_64_ISR183, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(184, x86_64_ISR184, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(185, x86_64_ISR185, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(186, x86_64_ISR186, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(187, x86_64_ISR187, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(188, x86_64_ISR188, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(189, x86_64_ISR189, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(190, x86_64_ISR190, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(191, x86_64_ISR191, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(192, x86_64_ISR192, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(193, x86_64_ISR193, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(194, x86_64_ISR194, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(195, x86_64_ISR195, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(196, x86_64_ISR196, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(197, x86_64_ISR197, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(198, x86_64_ISR198, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(199, x86_64_ISR199, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(200, x86_64_ISR200, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(201, x86_64_ISR201, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(202, x86_64_ISR202, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(203, x86_64_ISR203, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(204, x86_64_ISR204, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(205, x86_64_ISR205, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(206, x86_64_ISR206, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(207, x86_64_ISR207, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(208, x86_64_ISR208, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(209, x86_64_ISR209, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(210, x86_64_ISR210, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(211, x86_64_ISR211, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(212, x86_64_ISR212, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(213, x86_64_ISR213, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(214, x86_64_ISR214, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(215, x86_64_ISR215, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(216, x86_64_ISR216, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(217, x86_64_ISR217, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(218, x86_64_ISR218, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(219, x86_64_ISR219, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(220, x86_64_ISR220, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(221, x86_64_ISR221, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(222, x86_64_ISR222, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(223, x86_64_ISR223, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(224, x86_64_ISR224, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(225, x86_64_ISR225, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(226, x86_64_ISR226, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(227, x86_64_ISR227, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(228, x86_64_ISR228, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(229, x86_64_ISR229, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(230, x86_64_ISR230, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(231, x86_64_ISR231, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(232, x86_64_ISR232, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(233, x86_64_ISR233, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(234, x86_64_ISR234, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(235, x86_64_ISR235, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(236, x86_64_ISR236, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(237, x86_64_ISR237, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(238, x86_64_ISR238, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(239, x86_64_ISR239, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(240, x86_64_ISR240, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(241, x86_64_ISR241, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(242, x86_64_ISR242, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(243, x86_64_ISR243, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(244, x86_64_ISR244, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(245, x86_64_ISR245, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(246, x86_64_ISR246, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(247, x86_64_ISR247, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(248, x86_64_ISR248, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(249, x86_64_ISR249, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(250, x86_64_ISR250, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(251, x86_64_ISR251, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(252, x86_64_ISR252, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(253, x86_64_ISR253, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(254, x86_64_ISR254, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
x86_64_IDT_SetGate(255, x86_64_ISR255, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
ISR_NOERRORCODE 0
|
||||
ISR_NOERRORCODE 1
|
||||
ISR_NOERRORCODE 2
|
||||
ISR_NOERRORCODE 3
|
||||
ISR_NOERRORCODE 4
|
||||
ISR_NOERRORCODE 5
|
||||
ISR_NOERRORCODE 6
|
||||
ISR_NOERRORCODE 7
|
||||
ISR_ERRORCODE 8
|
||||
ISR_NOERRORCODE 9
|
||||
ISR_ERRORCODE 10
|
||||
ISR_ERRORCODE 11
|
||||
ISR_ERRORCODE 12
|
||||
ISR_ERRORCODE 13
|
||||
ISR_ERRORCODE 14
|
||||
ISR_NOERRORCODE 15
|
||||
ISR_NOERRORCODE 16
|
||||
ISR_ERRORCODE 17
|
||||
ISR_NOERRORCODE 18
|
||||
ISR_NOERRORCODE 19
|
||||
ISR_NOERRORCODE 20
|
||||
ISR_ERRORCODE 21
|
||||
ISR_NOERRORCODE 22
|
||||
ISR_NOERRORCODE 23
|
||||
ISR_NOERRORCODE 24
|
||||
ISR_NOERRORCODE 25
|
||||
ISR_NOERRORCODE 26
|
||||
ISR_NOERRORCODE 27
|
||||
ISR_NOERRORCODE 28
|
||||
ISR_NOERRORCODE 29
|
||||
ISR_NOERRORCODE 30
|
||||
ISR_NOERRORCODE 31
|
||||
ISR_NOERRORCODE 32
|
||||
ISR_NOERRORCODE 33
|
||||
ISR_NOERRORCODE 34
|
||||
ISR_NOERRORCODE 35
|
||||
ISR_NOERRORCODE 36
|
||||
ISR_NOERRORCODE 37
|
||||
ISR_NOERRORCODE 38
|
||||
ISR_NOERRORCODE 39
|
||||
ISR_NOERRORCODE 40
|
||||
ISR_NOERRORCODE 41
|
||||
ISR_NOERRORCODE 42
|
||||
ISR_NOERRORCODE 43
|
||||
ISR_NOERRORCODE 44
|
||||
ISR_NOERRORCODE 45
|
||||
ISR_NOERRORCODE 46
|
||||
ISR_NOERRORCODE 47
|
||||
ISR_NOERRORCODE 48
|
||||
ISR_NOERRORCODE 49
|
||||
ISR_NOERRORCODE 50
|
||||
ISR_NOERRORCODE 51
|
||||
ISR_NOERRORCODE 52
|
||||
ISR_NOERRORCODE 53
|
||||
ISR_NOERRORCODE 54
|
||||
ISR_NOERRORCODE 55
|
||||
ISR_NOERRORCODE 56
|
||||
ISR_NOERRORCODE 57
|
||||
ISR_NOERRORCODE 58
|
||||
ISR_NOERRORCODE 59
|
||||
ISR_NOERRORCODE 60
|
||||
ISR_NOERRORCODE 61
|
||||
ISR_NOERRORCODE 62
|
||||
ISR_NOERRORCODE 63
|
||||
ISR_NOERRORCODE 64
|
||||
ISR_NOERRORCODE 65
|
||||
ISR_NOERRORCODE 66
|
||||
ISR_NOERRORCODE 67
|
||||
ISR_NOERRORCODE 68
|
||||
ISR_NOERRORCODE 69
|
||||
ISR_NOERRORCODE 70
|
||||
ISR_NOERRORCODE 71
|
||||
ISR_NOERRORCODE 72
|
||||
ISR_NOERRORCODE 73
|
||||
ISR_NOERRORCODE 74
|
||||
ISR_NOERRORCODE 75
|
||||
ISR_NOERRORCODE 76
|
||||
ISR_NOERRORCODE 77
|
||||
ISR_NOERRORCODE 78
|
||||
ISR_NOERRORCODE 79
|
||||
ISR_NOERRORCODE 80
|
||||
ISR_NOERRORCODE 81
|
||||
ISR_NOERRORCODE 82
|
||||
ISR_NOERRORCODE 83
|
||||
ISR_NOERRORCODE 84
|
||||
ISR_NOERRORCODE 85
|
||||
ISR_NOERRORCODE 86
|
||||
ISR_NOERRORCODE 87
|
||||
ISR_NOERRORCODE 88
|
||||
ISR_NOERRORCODE 89
|
||||
ISR_NOERRORCODE 90
|
||||
ISR_NOERRORCODE 91
|
||||
ISR_NOERRORCODE 92
|
||||
ISR_NOERRORCODE 93
|
||||
ISR_NOERRORCODE 94
|
||||
ISR_NOERRORCODE 95
|
||||
ISR_NOERRORCODE 96
|
||||
ISR_NOERRORCODE 97
|
||||
ISR_NOERRORCODE 98
|
||||
ISR_NOERRORCODE 99
|
||||
ISR_NOERRORCODE 100
|
||||
ISR_NOERRORCODE 101
|
||||
ISR_NOERRORCODE 102
|
||||
ISR_NOERRORCODE 103
|
||||
ISR_NOERRORCODE 104
|
||||
ISR_NOERRORCODE 105
|
||||
ISR_NOERRORCODE 106
|
||||
ISR_NOERRORCODE 107
|
||||
ISR_NOERRORCODE 108
|
||||
ISR_NOERRORCODE 109
|
||||
ISR_NOERRORCODE 110
|
||||
ISR_NOERRORCODE 111
|
||||
ISR_NOERRORCODE 112
|
||||
ISR_NOERRORCODE 113
|
||||
ISR_NOERRORCODE 114
|
||||
ISR_NOERRORCODE 115
|
||||
ISR_NOERRORCODE 116
|
||||
ISR_NOERRORCODE 117
|
||||
ISR_NOERRORCODE 118
|
||||
ISR_NOERRORCODE 119
|
||||
ISR_NOERRORCODE 120
|
||||
ISR_NOERRORCODE 121
|
||||
ISR_NOERRORCODE 122
|
||||
ISR_NOERRORCODE 123
|
||||
ISR_NOERRORCODE 124
|
||||
ISR_NOERRORCODE 125
|
||||
ISR_NOERRORCODE 126
|
||||
ISR_NOERRORCODE 127
|
||||
ISR_NOERRORCODE 128
|
||||
ISR_NOERRORCODE 129
|
||||
ISR_NOERRORCODE 130
|
||||
ISR_NOERRORCODE 131
|
||||
ISR_NOERRORCODE 132
|
||||
ISR_NOERRORCODE 133
|
||||
ISR_NOERRORCODE 134
|
||||
ISR_NOERRORCODE 135
|
||||
ISR_NOERRORCODE 136
|
||||
ISR_NOERRORCODE 137
|
||||
ISR_NOERRORCODE 138
|
||||
ISR_NOERRORCODE 139
|
||||
ISR_NOERRORCODE 140
|
||||
ISR_NOERRORCODE 141
|
||||
ISR_NOERRORCODE 142
|
||||
ISR_NOERRORCODE 143
|
||||
ISR_NOERRORCODE 144
|
||||
ISR_NOERRORCODE 145
|
||||
ISR_NOERRORCODE 146
|
||||
ISR_NOERRORCODE 147
|
||||
ISR_NOERRORCODE 148
|
||||
ISR_NOERRORCODE 149
|
||||
ISR_NOERRORCODE 150
|
||||
ISR_NOERRORCODE 151
|
||||
ISR_NOERRORCODE 152
|
||||
ISR_NOERRORCODE 153
|
||||
ISR_NOERRORCODE 154
|
||||
ISR_NOERRORCODE 155
|
||||
ISR_NOERRORCODE 156
|
||||
ISR_NOERRORCODE 157
|
||||
ISR_NOERRORCODE 158
|
||||
ISR_NOERRORCODE 159
|
||||
ISR_NOERRORCODE 160
|
||||
ISR_NOERRORCODE 161
|
||||
ISR_NOERRORCODE 162
|
||||
ISR_NOERRORCODE 163
|
||||
ISR_NOERRORCODE 164
|
||||
ISR_NOERRORCODE 165
|
||||
ISR_NOERRORCODE 166
|
||||
ISR_NOERRORCODE 167
|
||||
ISR_NOERRORCODE 168
|
||||
ISR_NOERRORCODE 169
|
||||
ISR_NOERRORCODE 170
|
||||
ISR_NOERRORCODE 171
|
||||
ISR_NOERRORCODE 172
|
||||
ISR_NOERRORCODE 173
|
||||
ISR_NOERRORCODE 174
|
||||
ISR_NOERRORCODE 175
|
||||
ISR_NOERRORCODE 176
|
||||
ISR_NOERRORCODE 177
|
||||
ISR_NOERRORCODE 178
|
||||
ISR_NOERRORCODE 179
|
||||
ISR_NOERRORCODE 180
|
||||
ISR_NOERRORCODE 181
|
||||
ISR_NOERRORCODE 182
|
||||
ISR_NOERRORCODE 183
|
||||
ISR_NOERRORCODE 184
|
||||
ISR_NOERRORCODE 185
|
||||
ISR_NOERRORCODE 186
|
||||
ISR_NOERRORCODE 187
|
||||
ISR_NOERRORCODE 188
|
||||
ISR_NOERRORCODE 189
|
||||
ISR_NOERRORCODE 190
|
||||
ISR_NOERRORCODE 191
|
||||
ISR_NOERRORCODE 192
|
||||
ISR_NOERRORCODE 193
|
||||
ISR_NOERRORCODE 194
|
||||
ISR_NOERRORCODE 195
|
||||
ISR_NOERRORCODE 196
|
||||
ISR_NOERRORCODE 197
|
||||
ISR_NOERRORCODE 198
|
||||
ISR_NOERRORCODE 199
|
||||
ISR_NOERRORCODE 200
|
||||
ISR_NOERRORCODE 201
|
||||
ISR_NOERRORCODE 202
|
||||
ISR_NOERRORCODE 203
|
||||
ISR_NOERRORCODE 204
|
||||
ISR_NOERRORCODE 205
|
||||
ISR_NOERRORCODE 206
|
||||
ISR_NOERRORCODE 207
|
||||
ISR_NOERRORCODE 208
|
||||
ISR_NOERRORCODE 209
|
||||
ISR_NOERRORCODE 210
|
||||
ISR_NOERRORCODE 211
|
||||
ISR_NOERRORCODE 212
|
||||
ISR_NOERRORCODE 213
|
||||
ISR_NOERRORCODE 214
|
||||
ISR_NOERRORCODE 215
|
||||
ISR_NOERRORCODE 216
|
||||
ISR_NOERRORCODE 217
|
||||
ISR_NOERRORCODE 218
|
||||
ISR_NOERRORCODE 219
|
||||
ISR_NOERRORCODE 220
|
||||
ISR_NOERRORCODE 221
|
||||
ISR_NOERRORCODE 222
|
||||
ISR_NOERRORCODE 223
|
||||
ISR_NOERRORCODE 224
|
||||
ISR_NOERRORCODE 225
|
||||
ISR_NOERRORCODE 226
|
||||
ISR_NOERRORCODE 227
|
||||
ISR_NOERRORCODE 228
|
||||
ISR_NOERRORCODE 229
|
||||
ISR_NOERRORCODE 230
|
||||
ISR_NOERRORCODE 231
|
||||
ISR_NOERRORCODE 232
|
||||
ISR_NOERRORCODE 233
|
||||
ISR_NOERRORCODE 234
|
||||
ISR_NOERRORCODE 235
|
||||
ISR_NOERRORCODE 236
|
||||
ISR_NOERRORCODE 237
|
||||
ISR_NOERRORCODE 238
|
||||
ISR_NOERRORCODE 239
|
||||
ISR_NOERRORCODE 240
|
||||
ISR_NOERRORCODE 241
|
||||
ISR_NOERRORCODE 242
|
||||
ISR_NOERRORCODE 243
|
||||
ISR_NOERRORCODE 244
|
||||
ISR_NOERRORCODE 245
|
||||
ISR_NOERRORCODE 246
|
||||
ISR_NOERRORCODE 247
|
||||
ISR_NOERRORCODE 248
|
||||
ISR_NOERRORCODE 249
|
||||
ISR_NOERRORCODE 250
|
||||
ISR_NOERRORCODE 251
|
||||
ISR_NOERRORCODE 252
|
||||
ISR_NOERRORCODE 253
|
||||
ISR_NOERRORCODE 254
|
||||
ISR_NOERRORCODE 255
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct {
|
||||
const char* Name;
|
||||
bool (*Probe)();
|
||||
void (*Initialize)(uint8_t offsetPic1, uint8_t offsetPic2, bool autoEoi);
|
||||
void (*Disable)();
|
||||
void (*SendEndOfInterrupt)(int irq);
|
||||
void (*Mask)(int irq);
|
||||
void (*Unmask)(int irq);
|
||||
} PICDriver;
|
||||
@@ -0,0 +1,104 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "mm/pmm.h"
|
||||
#include "mm/vmm.h"
|
||||
#include "mm/memory.h"
|
||||
#include "stdio.h"
|
||||
#include "fs/elf.h"
|
||||
|
||||
extern uintptr_t g_hhdm_offset;
|
||||
|
||||
#define USER_STACK_TOP 0x00007FFFFFFFE000ULL
|
||||
#define USER_STACK_PAGES 4
|
||||
#define USER_STACK_SIZE (USER_STACK_PAGES * PAGE_SIZE)
|
||||
|
||||
#define PTE_PRESENT (1ULL << 0)
|
||||
#define PTE_WRITABLE (1ULL << 1)
|
||||
#define PTE_USER (1ULL << 2)
|
||||
|
||||
|
||||
|
||||
static uint64_t user_stack_phys_base = 0;
|
||||
|
||||
extern struct pagemap *kernel_pagemap;
|
||||
|
||||
static void setup_user_stack()
|
||||
{
|
||||
// Allocate contiguous physical pages for the stack
|
||||
user_stack_phys_base = (uint64_t)pmm_alloc(USER_STACK_PAGES);
|
||||
if (!user_stack_phys_base) {
|
||||
printf("Failed to allocate user stack pages!\n");
|
||||
for (;;);
|
||||
}
|
||||
|
||||
// Map each page individually into the current pagemap
|
||||
// Stack grows downward, so start from the bottom
|
||||
uintptr_t virt = USER_STACK_TOP - USER_STACK_SIZE;
|
||||
|
||||
for (int i = 0; i < USER_STACK_PAGES; i++) {
|
||||
uint64_t phys = user_stack_phys_base + (i * PAGE_SIZE);
|
||||
|
||||
bool success = vmm_map_page(
|
||||
kernel_pagemap, // Use kernel_pagemap for now (later: process->process_pagemap)
|
||||
virt,
|
||||
phys,
|
||||
PAGE_READ | PAGE_WRITE | PAGE_USER, // RW + User
|
||||
Size4KiB
|
||||
);
|
||||
|
||||
if (!success) {
|
||||
printf("Failed to map user stack page at 0x%lx\n", virt);
|
||||
// TODO: cleanup previous pages if partial failure
|
||||
for (;;);
|
||||
}
|
||||
|
||||
virt += PAGE_SIZE;
|
||||
}
|
||||
|
||||
// Optional: zero the stack (good practice)
|
||||
// memset((void*)(USER_STACK_TOP - USER_STACK_SIZE), 0, USER_STACK_SIZE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// usermode.c
|
||||
__attribute__((naked))
|
||||
void enter_user_mode(uint64_t rip, uint64_t rsp)
|
||||
{
|
||||
asm volatile(
|
||||
"cli\n"
|
||||
"mov $0x1B, %ax\n" // Use User Data Selector (0x1B)
|
||||
"mov %ax, %ds\n"
|
||||
"mov %ax, %es\n"
|
||||
"mov %ax, %fs\n"
|
||||
"mov %ax, %gs\n"
|
||||
|
||||
"pushq $0x1B\n" // SS (User Data)
|
||||
"pushq %rsi\n" // RSP
|
||||
"pushfq\n"
|
||||
// Optional: manually set IF bit in pushed RFLAGS if you want interrupts enabled
|
||||
"pop %rax\n"
|
||||
"or $0x200, %rax\n"
|
||||
"push %rax\n"
|
||||
"pushq $0x23\n" // CS (User Code)
|
||||
"pushq %rdi\n" // RIP
|
||||
"iretq\n"
|
||||
);
|
||||
}
|
||||
|
||||
void start_userspace(void)
|
||||
{
|
||||
void *entry = NULL;
|
||||
|
||||
if (!ELF_Read("init.elf", &entry)) {
|
||||
printf("Failed to load init.elf\n");
|
||||
for(;;);
|
||||
}
|
||||
|
||||
setup_user_stack();
|
||||
|
||||
printf("Jumping to user entry: 0x%lx with stack top 0x%lx\n",
|
||||
(uint64_t)entry, USER_STACK_TOP);
|
||||
|
||||
enter_user_mode((uint64_t)entry, USER_STACK_TOP);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
void start_userspace(void);
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
#include "debug.h"
|
||||
#include <stdint.h>
|
||||
#include "stdio.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
static const uint32_t g_LogSeverityColors[] =
|
||||
{
|
||||
[LVL_DEBUG] = 0xAAAAAA, // light gray
|
||||
[LVL_INFO] = 0xFFFFFF, // white
|
||||
[LVL_WARN] = 0xFFFF00, // yellow
|
||||
[LVL_ERROR] = 0xFF0000, // red
|
||||
[LVL_CRITICAL] = 0xFFFFFF, // white (can do red background separately if you want)
|
||||
};
|
||||
|
||||
|
||||
static const char* const g_ColorReset = "\033[0m";
|
||||
|
||||
void logf(const char* module, DebugLevel level, const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
uint32_t color = g_LogSeverityColors[level];
|
||||
|
||||
fputs_colored("[", color);
|
||||
fputs_colored(module, color);
|
||||
fputs_colored("] ", color);
|
||||
|
||||
// print formatted text in same color
|
||||
vfprintf(fmt, args); // or adapt vfprintf to take a color
|
||||
|
||||
fputc('\n');
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#define MIN_LOG_LEVEL LVL_DEBUG
|
||||
|
||||
typedef enum {
|
||||
LVL_DEBUG = 0,
|
||||
LVL_INFO = 1,
|
||||
LVL_WARN = 2,
|
||||
LVL_ERROR = 3,
|
||||
LVL_CRITICAL = 4
|
||||
} DebugLevel;
|
||||
|
||||
|
||||
|
||||
void logf(const char* module, DebugLevel level, const char* fmt, ...);
|
||||
#define log_debug(module, ...) logf(module, LVL_DEBUG, __VA_ARGS__)
|
||||
#define log_info(module, ...) logf(module, LVL_INFO, __VA_ARGS__)
|
||||
#define log_warn(module, ...) logf(module, LVL_WARN, __VA_ARGS__)
|
||||
#define log_err(module, ...) logf(module, LVL_ERROR, __VA_ARGS__)
|
||||
#define log_crit(module, ...) logf(module, LVL_CRITICAL, __VA_ARGS__)
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
#include "elf.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "mm/pmm.h"
|
||||
#include "mm/vmm.h"
|
||||
#include "mm/memory.h"
|
||||
#include "fs/ext2.h"
|
||||
|
||||
extern uintptr_t g_hhdm_offset;
|
||||
extern struct pagemap *kernel_pagemap;
|
||||
|
||||
#define ELF_BUFFER_SIZE (1024 * 1024)
|
||||
|
||||
|
||||
#define PTE_PRESENT (1ULL << 0)
|
||||
#define PTE_WRITABLE (1ULL << 1)
|
||||
#define PTE_USER (1ULL << 2)
|
||||
|
||||
bool ELF_Read(const char* path, void** entryPoint)
|
||||
{
|
||||
uint32_t size;
|
||||
|
||||
uint8_t* elf_buffer = kmalloc(ELF_BUFFER_SIZE);
|
||||
if (!elf_buffer) {
|
||||
printf("ELF: kmalloc failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// ── load file ─────────────────────────────────────
|
||||
if (!ext2_read_file_from_root(path, elf_buffer, &size)) {
|
||||
printf("ELF: failed to read file\n");
|
||||
kfree(elf_buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (size < sizeof(ELFHeader)) {
|
||||
printf("ELF: file too small\n");
|
||||
kfree(elf_buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
ELFHeader* header = (ELFHeader*)elf_buffer;
|
||||
|
||||
// ── validate ELF ──────────────────────────────────
|
||||
if (memcmp(header->Magic, ELF_MAGIC, 4) != 0) {
|
||||
printf("ELF: bad magic\n");
|
||||
kfree(elf_buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (header->Bitness != ELF_BITNESS_64BIT) {
|
||||
printf("ELF: not 64-bit\n");
|
||||
kfree(elf_buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (header->Endianness != ELF_ENDIANNESS_LITTLE) {
|
||||
printf("ELF: wrong endianness\n");
|
||||
kfree(elf_buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (header->Type != ELF_TYPE_EXECUTABLE) {
|
||||
printf("ELF: not executable\n");
|
||||
kfree(elf_buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (header->InstructionSet != ELF_INSTRUCTION_SET_X64) {
|
||||
printf("ELF: wrong arch\n");
|
||||
kfree(elf_buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
*entryPoint = (void*)header->ProgramEntryPosition;
|
||||
|
||||
// ── program headers ───────────────────────────────
|
||||
uint8_t* ph_table = elf_buffer + header->ProgramHeaderTablePosition;
|
||||
|
||||
for (uint32_t i = 0; i < header->ProgramHeaderTableEntryCount; i++)
|
||||
{
|
||||
ELFProgramHeader* ph = (ELFProgramHeader*)(ph_table +
|
||||
i * header->ProgramHeaderTableEntrySize);
|
||||
|
||||
if (ph->Type != ELF_PROGRAM_TYPE_LOAD)
|
||||
continue;
|
||||
|
||||
uint64_t virt = ph->VirtualAddress;
|
||||
uint64_t offset = ph->Offset;
|
||||
uint64_t memsz = ph->MemorySize;
|
||||
uint64_t filesz = ph->FileSize;
|
||||
|
||||
if (memsz == 0)
|
||||
continue;
|
||||
|
||||
// ── align to page boundary ─────────────────────
|
||||
uint64_t aligned_virt = ALIGN_DOWN(virt, PAGE_SIZE);
|
||||
uint64_t page_offset = virt & 0xFFF;
|
||||
uint64_t aligned_memsz = ALIGN_UP(memsz + page_offset, PAGE_SIZE);
|
||||
|
||||
uint64_t pages = aligned_memsz / PAGE_SIZE;
|
||||
|
||||
// Allocate physical pages
|
||||
uint64_t phys_base = (uint64_t)pmm_alloc(pages);
|
||||
if (!phys_base) {
|
||||
printf("ELF: pmm_alloc failed for %lu pages\n", pages);
|
||||
kfree(elf_buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
// ── map each page individually using new vmm_map_page ─────
|
||||
for (uint64_t p = 0; p < pages; p++) {
|
||||
uint64_t virt_addr = aligned_virt + p * PAGE_SIZE;
|
||||
uint64_t phys_addr = phys_base + p * PAGE_SIZE;
|
||||
|
||||
bool success = vmm_map_page(
|
||||
kernel_pagemap,
|
||||
virt_addr,
|
||||
phys_addr,
|
||||
PAGE_READ | PAGE_WRITE | PAGE_USER, // RW + User mode
|
||||
Size4KiB
|
||||
);
|
||||
|
||||
if (!success) {
|
||||
printf("ELF: failed to map page at 0x%lx\n", virt_addr);
|
||||
// TODO: cleanup previously mapped pages + free phys
|
||||
kfree(elf_buffer);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ── copy segment data ───────────────────────────────
|
||||
uint8_t* dst = (uint8_t*)(phys_base + MEM_PHYS_OFFSET); // via HHDM
|
||||
uint8_t* src = elf_buffer + offset;
|
||||
|
||||
memcpy(dst + page_offset, src, filesz);
|
||||
|
||||
// ── zero BSS section ────────────────────────────────
|
||||
if (memsz > filesz) {
|
||||
memset(dst + page_offset + filesz, 0, memsz - filesz);
|
||||
}
|
||||
}
|
||||
|
||||
kfree(elf_buffer);
|
||||
return true;
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define ELF_MAGIC ("\x7F" "ELF")
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Magic[4];
|
||||
uint8_t Bitness; // 1 = 32-bit, 2 = 64-bit
|
||||
uint8_t Endianness; // 1 = little, 2 = big
|
||||
uint8_t ELFHeaderVersion;
|
||||
uint8_t ABI;
|
||||
uint8_t ABIVersion;
|
||||
uint8_t _Padding[7];
|
||||
|
||||
uint16_t Type; // relocatable, executable, shared, core
|
||||
uint16_t InstructionSet; // architecture (was too small for real ELF, but kept)
|
||||
|
||||
uint32_t ELFVersion;
|
||||
|
||||
uint64_t ProgramEntryPosition; // FIXED (was 32-bit)
|
||||
uint64_t ProgramHeaderTablePosition; // FIXED
|
||||
uint64_t SectionHeaderTablePosition; // FIXED
|
||||
|
||||
uint32_t Flags;
|
||||
|
||||
uint16_t HeaderSize;
|
||||
uint16_t ProgramHeaderTableEntrySize;
|
||||
uint16_t ProgramHeaderTableEntryCount;
|
||||
uint16_t SectionHeaderTableEntrySize;
|
||||
uint16_t SectionHeaderTableEntryCount;
|
||||
uint16_t SectionNamesIndex;
|
||||
|
||||
} __attribute__((packed)) ELFHeader;
|
||||
|
||||
enum ELFBitness
|
||||
{
|
||||
ELF_BITNESS_32BIT = 1,
|
||||
ELF_BITNESS_64BIT = 2,
|
||||
};
|
||||
|
||||
enum ELFEndianness
|
||||
{
|
||||
ELF_ENDIANNESS_LITTLE = 1,
|
||||
ELF_ENDIANNESS_BIG = 2,
|
||||
};
|
||||
|
||||
enum ELFInstructionSet
|
||||
{
|
||||
ELF_INSTRUCTION_SET_NONE = 0,
|
||||
ELF_INSTRUCTION_SET_X86 = 3,
|
||||
ELF_INSTRUCTION_SET_ARM = 0x28,
|
||||
ELF_INSTRUCTION_SET_X64 = 0x3E,
|
||||
ELF_INSTRUCTION_SET_ARM64 = 0xB7,
|
||||
ELF_INSTRUCTION_SET_RISCV = 0xF3,
|
||||
};
|
||||
|
||||
enum ELFType
|
||||
{
|
||||
ELF_TYPE_RELOCATABLE = 1,
|
||||
ELF_TYPE_EXECUTABLE = 2,
|
||||
ELF_TYPE_SHARED = 3,
|
||||
ELF_TYPE_CORE = 4,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Type;
|
||||
uint64_t Offset;
|
||||
uint64_t VirtualAddress;
|
||||
uint64_t PhysicalAddress;
|
||||
uint64_t FileSize;
|
||||
uint64_t MemorySize;
|
||||
uint32_t Flags;
|
||||
uint64_t Align;
|
||||
|
||||
} ELFProgramHeader;
|
||||
|
||||
enum ELFProgramType {
|
||||
// Program header table entry unused.
|
||||
ELF_PROGRAM_TYPE_NULL = 0,
|
||||
|
||||
// Loadable segment.
|
||||
ELF_PROGRAM_TYPE_LOAD = 1,
|
||||
|
||||
// Dynamic linking information.
|
||||
ELF_PROGRAM_TYPE_DYNAMIC = 2,
|
||||
|
||||
// Interpreter information.
|
||||
ELF_PROGRAM_TYPE_INTERP = 3,
|
||||
|
||||
// Auxiliary information.
|
||||
ELF_PROGRAM_TYPE_NOTE = 4,
|
||||
|
||||
// Reserved
|
||||
ELF_PROGRAM_TYPE_SHLIB = 5,
|
||||
|
||||
// Segment containing program header table itself.
|
||||
ELF_PROGRAM_TYPE_PHDR = 6,
|
||||
|
||||
// Thread-Local Storage template.
|
||||
ELF_PROGRAM_TYPE_TLS = 7,
|
||||
|
||||
// Reserved inclusive range. Operating system specific.
|
||||
ELF_PROGRAM_TYPE_LOOS = 0x60000000,
|
||||
ELF_PROGRAM_TYPE_HIOS = 0x6FFFFFFF,
|
||||
|
||||
// Reserved inclusive range. Processor specific.
|
||||
ELF_PROGRAM_TYPE_LOPROC = 0x70000000,
|
||||
ELF_PROGRAM_TYPE_HIPROC = 0x7FFFFFFF,
|
||||
};
|
||||
|
||||
|
||||
bool ELF_Read(const char* path, void** entryPoint);
|
||||
+1398
File diff suppressed because it is too large
Load Diff
+220
@@ -0,0 +1,220 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define EXT2_SUPERBLOCK_OFFSET 1024
|
||||
#define EXT2_SUPERBLOCK_SIZE 1024
|
||||
#define EXT2_MAGIC 0xEF53
|
||||
#define EXT2_NAME_LEN 255
|
||||
|
||||
typedef struct ext2_superblock {
|
||||
unsigned int s_inodes_count; /* Inodes count */
|
||||
unsigned int s_blocks_count; /* Blocks count */
|
||||
unsigned int s_r_blocks_count; /* Reserved blocks count */
|
||||
unsigned int s_free_blocks_count; /* Free blocks count */
|
||||
unsigned int s_free_inodes_count; /* Free inodes count */
|
||||
unsigned int s_first_data_block; /* First Data Block */
|
||||
unsigned int s_log_block_size; /* Block size */
|
||||
unsigned int s_log_frag_size; /* Fragment size */
|
||||
unsigned int s_blocks_per_group; /* # Blocks per group */
|
||||
unsigned int s_frags_per_group; /* # Fragments per group */
|
||||
unsigned int s_inodes_per_group; /* # Inodes per group */
|
||||
unsigned int s_mtime; /* Mount time */
|
||||
unsigned int s_wtime; /* Write time */
|
||||
unsigned short s_mnt_count; /* Mount count */
|
||||
unsigned short s_max_mnt_count; /* Maximal mount count */
|
||||
unsigned short s_magic; /* Magic signature */
|
||||
unsigned short s_state; /* File system state */
|
||||
unsigned short s_errors; /* Behaviour when detecting errors */
|
||||
unsigned short s_minor_rev_level; /* minor revision level */
|
||||
unsigned int s_lastcheck; /* time of last check */
|
||||
unsigned int s_checkinterval; /* max. time between checks */
|
||||
unsigned int s_creator_os; /* OS */
|
||||
unsigned int s_rev_level; /* Revision level */
|
||||
unsigned short s_def_resuid; /* Default uid for reserved blocks */
|
||||
unsigned short s_def_resgid; /* Default gid for reserved blocks */
|
||||
/*
|
||||
* These fields are for EXT2_DYNAMIC_REV superblocks only.
|
||||
*
|
||||
* Note: the difference between the compatible feature set and
|
||||
* the incompatible feature set is that if there is a bit set
|
||||
* in the incompatible feature set that the kernel doesn't
|
||||
* know about, it should refuse to mount the filesystem.
|
||||
*
|
||||
* e2fsck's requirements are more strict; if it doesn't know
|
||||
* about a feature in either the compatible or incompatible
|
||||
* feature set, it must abort and not try to meddle with
|
||||
* things it doesn't understand...
|
||||
*/
|
||||
unsigned int s_first_ino; /* First non-reserved inode */
|
||||
unsigned short s_inode_size; /* size of inode structure */
|
||||
unsigned short s_block_group_nr; /* block group # of this superblock */
|
||||
unsigned int s_feature_compat; /* compatible feature set */
|
||||
unsigned int s_feature_incompat; /* incompatible feature set */
|
||||
unsigned int s_feature_ro_compat; /* readonly-compatible feature set */
|
||||
unsigned char s_uuid[16]; /* 128-bit uuid for volume */
|
||||
char s_volume_name[16]; /* volume name */
|
||||
char s_last_mounted[64]; /* directory where last mounted */
|
||||
unsigned int s_algorithm_usage_bitmap; /* For compression */
|
||||
/*
|
||||
* Performance hints. Directory preallocation should only
|
||||
* happen if the EXT2_COMPAT_PREALLOC flag is on.
|
||||
*/
|
||||
unsigned char s_prealloc_blocks; /* Nr of blocks to try to preallocate*/
|
||||
unsigned char s_prealloc_dir_blocks; /* Nr to preallocate for dirs */
|
||||
unsigned short s_padding1;
|
||||
/*
|
||||
* Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set.
|
||||
*/
|
||||
unsigned char s_journal_uuid[16]; /* uuid of journal superblock */
|
||||
unsigned int s_journal_inum; /* inode number of journal file */
|
||||
unsigned int s_journal_dev; /* device number of journal file */
|
||||
unsigned int s_last_orphan; /* start of list of inodes to delete */
|
||||
unsigned int s_hash_seed[4]; /* HTREE hash seed */
|
||||
unsigned char s_def_hash_version; /* Default hash version to use */
|
||||
unsigned char s_reserved_char_pad;
|
||||
unsigned short s_reserved_word_pad;
|
||||
unsigned int s_default_mount_opts;
|
||||
unsigned int s_first_meta_bg; /* First metablock block group */
|
||||
unsigned int s_reserved[190]; /* Padding to the end of the block */
|
||||
} __attribute__((packed)) ext2_superblock_t;
|
||||
|
||||
typedef struct ext2_group_desc {
|
||||
unsigned int bg_block_bitmap; /* Blocks bitmap block */
|
||||
unsigned int bg_inode_bitmap; /* Inodes bitmap block */
|
||||
unsigned int bg_inode_table; /* Inodes table block */
|
||||
unsigned short bg_free_blocks_count; /* Free blocks count */
|
||||
unsigned short bg_free_inodes_count; /* Free inodes count */
|
||||
unsigned short bg_used_dirs_count; /* Directories count */
|
||||
unsigned short bg_pad;
|
||||
unsigned int bg_reserved[3];
|
||||
} __attribute__((packed)) ext2_group_desc_t;
|
||||
|
||||
typedef struct ext2_inode {
|
||||
unsigned short i_mode; /* File mode */
|
||||
unsigned short i_uid; /* Low 16 bits of Owner Uid */
|
||||
unsigned int i_size; /* Size in bytes */
|
||||
unsigned int i_atime; /* Access time */
|
||||
unsigned int i_ctime; /* Creation time */
|
||||
unsigned int i_mtime; /* Modification time */
|
||||
unsigned int i_dtime; /* Deletion Time */
|
||||
unsigned short i_gid; /* Low 16 bits of Group Id */
|
||||
unsigned short i_links_count; /* Links count */
|
||||
unsigned int i_blocks; /* Blocks count IN DISK SECTORS*/
|
||||
unsigned int i_flags; /* File flags */
|
||||
unsigned int osd1; /* OS dependent 1 */
|
||||
unsigned int i_block[15]; /* Pointers to blocks */
|
||||
unsigned int i_generation; /* File version (for NFS) */
|
||||
unsigned int i_file_acl; /* File ACL */
|
||||
unsigned int i_dir_acl; /* Directory ACL */
|
||||
unsigned int i_faddr; /* Fragment address */
|
||||
unsigned int extra[3];
|
||||
} __attribute__((packed)) ext2_inode_t;
|
||||
|
||||
typedef struct ext2_dir_entry {
|
||||
unsigned int inode; /* Inode number */
|
||||
unsigned short rec_len; /* Directory entry length */
|
||||
unsigned char name_len; /* Name length */
|
||||
unsigned char file_type;
|
||||
char name[]; /* File name, up to EXT2_NAME_LEN */
|
||||
} __attribute__((packed)) ext2_dir_entry_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ino;
|
||||
uint16_t mode;
|
||||
uint16_t uid;
|
||||
uint16_t gid;
|
||||
uint32_t size;
|
||||
uint32_t atime;
|
||||
uint32_t mtime;
|
||||
uint32_t ctime;
|
||||
uint32_t nlink;
|
||||
uint32_t blocks;
|
||||
} ext2_stat_t;
|
||||
|
||||
typedef enum {
|
||||
EXT2_WRITE_OVERWRITE,
|
||||
EXT2_WRITE_APPEND,
|
||||
} ext2_write_mode_t;
|
||||
|
||||
// Inode type and permissions
|
||||
#define EXT2_S_IFIFO 0x1000
|
||||
#define EXT2_S_IFCHR 0x2000
|
||||
#define EXT2_S_IFDIR 0x4000
|
||||
#define EXT2_S_IFBLK 0x6000
|
||||
#define EXT2_S_IFREG 0x8000
|
||||
#define EXT2_S_IFLNK 0xA000
|
||||
#define EXT2_S_IFSOCK 0xC000
|
||||
|
||||
#define EXT2_S_IRUSR 0x0100
|
||||
#define EXT2_S_IWUSR 0x0080
|
||||
#define EXT2_S_IXUSR 0x0040
|
||||
#define EXT2_S_IRGRP 0x0020
|
||||
#define EXT2_S_IWGRP 0x0010
|
||||
#define EXT2_S_IXGRP 0x0008
|
||||
#define EXT2_S_IROTH 0x0004
|
||||
#define EXT2_S_IWOTH 0x0002
|
||||
#define EXT2_S_IXOTH 0x0001
|
||||
|
||||
// File types for directory entries
|
||||
#define EXT2_FT_UNKNOWN 0
|
||||
#define EXT2_FT_REG_FILE 1
|
||||
#define EXT2_FT_DIR 2
|
||||
#define EXT2_FT_CHRDEV 3
|
||||
#define EXT2_FT_BLKDEV 4
|
||||
#define EXT2_FT_FIFO 5
|
||||
#define EXT2_FT_SOCK 6
|
||||
#define EXT2_FT_SYMLINK 7
|
||||
|
||||
|
||||
|
||||
|
||||
// ── init ──────────────────────────────────────────────────────────────────────
|
||||
bool ext2_read_superblock(void);
|
||||
bool ext2_read_group_desc_table(void);
|
||||
|
||||
// ── low-level ────────────────────────────────────────────────────────────────
|
||||
bool ext2_read_block(uint32_t block_num, void* buf);
|
||||
bool ext2_write_block(uint32_t block_num, const void* buf);
|
||||
bool ext2_read_inode(uint32_t inode_num, ext2_inode_t* out);
|
||||
bool ext2_write_inode(uint32_t inode_num, ext2_inode_t* inode);
|
||||
|
||||
// ── path / directory ─────────────────────────────────────────────────────────
|
||||
uint32_t ext2_resolve_path(const char* path); // returns inode num, 0 = not found
|
||||
bool ext2_find_in_dir(ext2_inode_t* dir, const char* name, uint32_t* out_inum);
|
||||
bool ext2_read_dir(ext2_inode_t* dir);
|
||||
bool ext2_read_root_dir(void);
|
||||
|
||||
// ── file I/O ─────────────────────────────────────────────────────────────────
|
||||
bool ext2_read_file(ext2_inode_t* inode, uint8_t* buf);
|
||||
bool ext2_write_file(ext2_inode_t* inode, uint32_t inode_num,
|
||||
const uint8_t* data, uint32_t size, ext2_write_mode_t mode);
|
||||
bool ext2_truncate(ext2_inode_t* inode, uint32_t inode_num, uint32_t new_size);
|
||||
|
||||
// ── high-level (operate from a path string) ───────────────────────────────────
|
||||
bool ext2_read_file_from_root(const char* name, uint8_t* buf, uint32_t* size);
|
||||
bool ext2_write_file_from_root(const char* name, const uint8_t* data,
|
||||
uint32_t size, ext2_write_mode_t mode);
|
||||
|
||||
// ── create / delete ───────────────────────────────────────────────────────────
|
||||
bool ext2_create_file(ext2_inode_t* dir, uint32_t dir_inum,
|
||||
const char* name, uint32_t* out_inum);
|
||||
bool ext2_mkdir(ext2_inode_t* parent, uint32_t parent_inum,
|
||||
const char* name, uint32_t* out_inum);
|
||||
bool ext2_unlink(ext2_inode_t* dir, uint32_t dir_inum, const char* name);
|
||||
bool ext2_rmdir(ext2_inode_t* parent, uint32_t parent_inum, const char* name);
|
||||
bool ext2_rename(ext2_inode_t* src_dir, uint32_t src_inum,
|
||||
ext2_inode_t* dst_dir, uint32_t dst_inum,
|
||||
const char* old_name, const char* new_name);
|
||||
|
||||
// ── symlinks ──────────────────────────────────────────────────────────────────
|
||||
bool ext2_symlink(ext2_inode_t* dir, uint32_t dir_inum,
|
||||
const char* name, const char* target);
|
||||
bool ext2_readlink(uint32_t inode_num, char* buf, uint32_t buf_size);
|
||||
|
||||
// ── metadata ─────────────────────────────────────────────────────────────────
|
||||
bool ext2_stat(uint32_t inode_num, ext2_stat_t* st);
|
||||
bool ext2_chmod(uint32_t inode_num, uint16_t mode);
|
||||
bool ext2_chown(uint32_t inode_num, uint16_t uid, uint16_t gid);
|
||||
|
||||
const char* ext2_file_type_string(uint8_t type);
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
#include "vfs.h"
|
||||
#include <video/render.h>
|
||||
#include <arch/x86_64/e9.h>
|
||||
#include "mp/spinlock.h"
|
||||
|
||||
static spinlock_t s_vfs_lock = SPINLOCK_INIT;
|
||||
static vfs_file_t vfs_fd_table[VFS_MAX_FDS];
|
||||
|
||||
fd_t VFS_Open_internal(const char* path)
|
||||
{
|
||||
uint32_t ino = ext2_resolve_path(path);
|
||||
if (ino == 0)
|
||||
return -1;
|
||||
|
||||
// find free fd
|
||||
for (int i = 4; i < VFS_MAX_FDS; i++)
|
||||
{
|
||||
if (!vfs_fd_table[i].used)
|
||||
{
|
||||
vfs_fd_table[i].used = true;
|
||||
vfs_fd_table[i].type = VFS_NODE_EXT2;
|
||||
vfs_fd_table[i].offset = 0;
|
||||
vfs_fd_table[i].ext2.inode_num = ino;
|
||||
|
||||
if (!ext2_read_inode(ino, &vfs_fd_table[i].ext2.inode))
|
||||
return -1;
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd_t VFS_Open(const char* path) {
|
||||
uint64_t flags;
|
||||
spinlock_acquire_irqsave(&s_vfs_lock, &flags);
|
||||
fd_t fd = VFS_Open_internal(path);
|
||||
spinlock_release_irqrestore(&s_vfs_lock, flags);
|
||||
return fd;
|
||||
}
|
||||
|
||||
int VFS_Close_internal(fd_t fd)
|
||||
{
|
||||
if (fd < 0 || fd >= VFS_MAX_FDS)
|
||||
return -1;
|
||||
|
||||
vfs_fd_table[fd].used = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VFS_Close(fd_t fd) {
|
||||
uint64_t flags;
|
||||
spinlock_acquire_irqsave(&s_vfs_lock, &flags);
|
||||
int resp = VFS_Close_internal(fd);
|
||||
spinlock_release_irqrestore(&s_vfs_lock, flags);
|
||||
return resp;
|
||||
}
|
||||
|
||||
int VFS_Read(fd_t fd, uint8_t* buf, size_t size)
|
||||
{
|
||||
if (fd < 0 || fd >= VFS_MAX_FDS)
|
||||
return -1;
|
||||
|
||||
vfs_file_t* file = &vfs_fd_table[fd];
|
||||
|
||||
if (!file->used)
|
||||
return -1;
|
||||
|
||||
switch (file->type)
|
||||
{
|
||||
case VFS_NODE_EXT2:
|
||||
{
|
||||
uint32_t file_size = file->ext2.inode.i_size;
|
||||
|
||||
if (file->offset >= file_size)
|
||||
return 0;
|
||||
|
||||
// clamp read
|
||||
if (file->offset + size > file_size)
|
||||
size = file_size - file->offset;
|
||||
|
||||
// naive: read whole file then slice
|
||||
uint8_t tmp[file_size];
|
||||
if (!ext2_read_file(&file->ext2.inode, tmp))
|
||||
return -1;
|
||||
|
||||
for (size_t i = 0; i < size; i++)
|
||||
buf[i] = tmp[file->offset + i];
|
||||
|
||||
file->offset += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int VFS_Write(fd_t file, uint8_t* data, size_t size)
|
||||
{
|
||||
switch (file)
|
||||
{
|
||||
case VFS_FD_STDIN:
|
||||
return 0;
|
||||
|
||||
case VFS_FD_STDOUT:
|
||||
for (size_t i = 0; i < size; i++)
|
||||
putchar(data[i]);
|
||||
return size;
|
||||
case VFS_FD_STDERR:
|
||||
for (size_t i = 0; i < size; i++)
|
||||
putchar(data[i]);
|
||||
return size;
|
||||
|
||||
case VFS_FD_DEBUG:
|
||||
for (size_t i = 0; i < size; i++)
|
||||
e9_putc(data[i]);
|
||||
return size;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (file < 0 || file >= VFS_MAX_FDS)
|
||||
return -1;
|
||||
|
||||
vfs_file_t* f = &vfs_fd_table[file];
|
||||
|
||||
if (!f->used)
|
||||
return -1;
|
||||
|
||||
if (f->type == VFS_NODE_EXT2)
|
||||
{
|
||||
if (!ext2_write_file(
|
||||
&f->ext2.inode,
|
||||
f->ext2.inode_num,
|
||||
data,
|
||||
size,
|
||||
EXT2_WRITE_APPEND))
|
||||
return -1;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "ext2.h"
|
||||
|
||||
typedef int fd_t;
|
||||
|
||||
#define VFS_MAX_FDS 32
|
||||
|
||||
#define VFS_FD_STDIN 0
|
||||
#define VFS_FD_STDOUT 1
|
||||
#define VFS_FD_STDERR 2
|
||||
#define VFS_FD_DEBUG 3
|
||||
|
||||
typedef enum {
|
||||
VFS_NODE_NONE,
|
||||
VFS_NODE_EXT2,
|
||||
VFS_NODE_DEVICE
|
||||
} vfs_node_type_t;
|
||||
|
||||
typedef struct {
|
||||
vfs_node_type_t type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint32_t inode_num;
|
||||
ext2_inode_t inode;
|
||||
} ext2;
|
||||
};
|
||||
|
||||
size_t offset;
|
||||
bool used;
|
||||
} vfs_file_t;
|
||||
|
||||
// API
|
||||
fd_t VFS_Open(const char* path);
|
||||
int VFS_Read(fd_t fd, uint8_t* buf, size_t size);
|
||||
int VFS_Write(fd_t fd, uint8_t* data, size_t size);
|
||||
int VFS_Close(fd_t fd);
|
||||
+634
@@ -0,0 +1,634 @@
|
||||
/* SPDX-License-Identifier: 0BSD */
|
||||
|
||||
/* Copyright (C) 2022-2026 Mintsuki and contributors.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LIMINE_H
|
||||
#define LIMINE_H 1
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Misc */
|
||||
|
||||
#ifdef LIMINE_NO_POINTERS
|
||||
# define LIMINE_PTR(TYPE) uint64_t
|
||||
#else
|
||||
# define LIMINE_PTR(TYPE) TYPE
|
||||
#endif
|
||||
|
||||
#define LIMINE_REQUESTS_START_MARKER { 0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, \
|
||||
0x785c6ed015d3e316, 0x181e920a7852b9d9 }
|
||||
#define LIMINE_REQUESTS_END_MARKER { 0xadc0e0531bb10d03, 0x9572709f31764c62 }
|
||||
|
||||
#define LIMINE_BASE_REVISION(N) { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) }
|
||||
|
||||
#define LIMINE_BASE_REVISION_SUPPORTED(VAR) ((VAR)[2] == 0)
|
||||
|
||||
#define LIMINE_LOADED_BASE_REVISION_VALID(VAR) ((VAR)[1] != 0x6a7b384944536bdc)
|
||||
#define LIMINE_LOADED_BASE_REVISION(VAR) ((VAR)[1])
|
||||
|
||||
#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b
|
||||
|
||||
struct limine_uuid {
|
||||
uint32_t a;
|
||||
uint16_t b;
|
||||
uint16_t c;
|
||||
uint8_t d[8];
|
||||
};
|
||||
|
||||
#define LIMINE_MEDIA_TYPE_GENERIC 0
|
||||
#define LIMINE_MEDIA_TYPE_OPTICAL 1
|
||||
#define LIMINE_MEDIA_TYPE_TFTP 2
|
||||
|
||||
struct limine_file {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(void *) address;
|
||||
uint64_t size;
|
||||
LIMINE_PTR(char *) path;
|
||||
LIMINE_PTR(char *) string;
|
||||
uint32_t media_type;
|
||||
uint32_t unused;
|
||||
uint32_t tftp_ip;
|
||||
uint32_t tftp_port;
|
||||
uint32_t partition_index;
|
||||
uint32_t mbr_disk_id;
|
||||
struct limine_uuid gpt_disk_uuid;
|
||||
struct limine_uuid gpt_part_uuid;
|
||||
struct limine_uuid part_uuid;
|
||||
};
|
||||
|
||||
/* Boot info */
|
||||
|
||||
#define LIMINE_BOOTLOADER_INFO_REQUEST_ID { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 }
|
||||
|
||||
struct limine_bootloader_info_response {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(char *) name;
|
||||
LIMINE_PTR(char *) version;
|
||||
};
|
||||
|
||||
struct limine_bootloader_info_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_bootloader_info_response *) response;
|
||||
};
|
||||
|
||||
/* Executable command line */
|
||||
|
||||
#define LIMINE_EXECUTABLE_CMDLINE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x4b161536e598651e, 0xb390ad4a2f1f303a }
|
||||
|
||||
struct limine_executable_cmdline_response {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(char *) cmdline;
|
||||
};
|
||||
|
||||
struct limine_executable_cmdline_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_executable_cmdline_response *) response;
|
||||
};
|
||||
|
||||
/* Firmware type */
|
||||
|
||||
#define LIMINE_FIRMWARE_TYPE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x8c2f75d90bef28a8, 0x7045a4688eac00c3 }
|
||||
|
||||
#define LIMINE_FIRMWARE_TYPE_X86BIOS 0
|
||||
#define LIMINE_FIRMWARE_TYPE_EFI32 1
|
||||
#define LIMINE_FIRMWARE_TYPE_EFI64 2
|
||||
#define LIMINE_FIRMWARE_TYPE_SBI 3
|
||||
|
||||
struct limine_firmware_type_response {
|
||||
uint64_t revision;
|
||||
uint64_t firmware_type;
|
||||
};
|
||||
|
||||
struct limine_firmware_type_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_firmware_type_response *) response;
|
||||
};
|
||||
|
||||
/* Stack size */
|
||||
|
||||
#define LIMINE_STACK_SIZE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d }
|
||||
|
||||
struct limine_stack_size_response {
|
||||
uint64_t revision;
|
||||
};
|
||||
|
||||
struct limine_stack_size_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_stack_size_response *) response;
|
||||
uint64_t stack_size;
|
||||
};
|
||||
|
||||
/* HHDM */
|
||||
|
||||
#define LIMINE_HHDM_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b }
|
||||
|
||||
struct limine_hhdm_response {
|
||||
uint64_t revision;
|
||||
uint64_t offset;
|
||||
};
|
||||
|
||||
struct limine_hhdm_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_hhdm_response *) response;
|
||||
};
|
||||
|
||||
/* Framebuffer */
|
||||
|
||||
#define LIMINE_FRAMEBUFFER_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b }
|
||||
|
||||
#define LIMINE_FRAMEBUFFER_RGB 1
|
||||
|
||||
struct limine_video_mode {
|
||||
uint64_t pitch;
|
||||
uint64_t width;
|
||||
uint64_t height;
|
||||
uint16_t bpp;
|
||||
uint8_t memory_model;
|
||||
uint8_t red_mask_size;
|
||||
uint8_t red_mask_shift;
|
||||
uint8_t green_mask_size;
|
||||
uint8_t green_mask_shift;
|
||||
uint8_t blue_mask_size;
|
||||
uint8_t blue_mask_shift;
|
||||
};
|
||||
|
||||
struct limine_framebuffer {
|
||||
LIMINE_PTR(void *) address;
|
||||
uint64_t width;
|
||||
uint64_t height;
|
||||
uint64_t pitch;
|
||||
uint16_t bpp;
|
||||
uint8_t memory_model;
|
||||
uint8_t red_mask_size;
|
||||
uint8_t red_mask_shift;
|
||||
uint8_t green_mask_size;
|
||||
uint8_t green_mask_shift;
|
||||
uint8_t blue_mask_size;
|
||||
uint8_t blue_mask_shift;
|
||||
uint8_t unused[7];
|
||||
uint64_t edid_size;
|
||||
LIMINE_PTR(void *) edid;
|
||||
/* Response revision 1 */
|
||||
uint64_t mode_count;
|
||||
LIMINE_PTR(struct limine_video_mode **) modes;
|
||||
};
|
||||
|
||||
struct limine_framebuffer_response {
|
||||
uint64_t revision;
|
||||
uint64_t framebuffer_count;
|
||||
LIMINE_PTR(struct limine_framebuffer **) framebuffers;
|
||||
};
|
||||
|
||||
struct limine_framebuffer_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_framebuffer_response *) response;
|
||||
};
|
||||
|
||||
/* Flanterm FB init params */
|
||||
|
||||
#define LIMINE_FLANTERM_FB_INIT_PARAMS_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x3259399fe7c5f126, 0xe01c1c8c5db9d1a9 }
|
||||
|
||||
#define LIMINE_FLANTERM_FB_ROTATE_0 0
|
||||
#define LIMINE_FLANTERM_FB_ROTATE_90 1
|
||||
#define LIMINE_FLANTERM_FB_ROTATE_180 2
|
||||
#define LIMINE_FLANTERM_FB_ROTATE_270 3
|
||||
|
||||
struct limine_flanterm_fb_init_params {
|
||||
LIMINE_PTR(uint32_t *) canvas;
|
||||
uint64_t canvas_size;
|
||||
uint32_t ansi_colours[8];
|
||||
uint32_t ansi_bright_colours[8];
|
||||
uint32_t default_bg;
|
||||
uint32_t default_fg;
|
||||
uint32_t default_bg_bright;
|
||||
uint32_t default_fg_bright;
|
||||
LIMINE_PTR(void *) font;
|
||||
uint64_t font_width;
|
||||
uint64_t font_height;
|
||||
uint64_t font_spacing;
|
||||
uint64_t font_scale_x;
|
||||
uint64_t font_scale_y;
|
||||
uint64_t margin;
|
||||
uint64_t rotation;
|
||||
};
|
||||
|
||||
struct limine_flanterm_fb_init_params_response {
|
||||
uint64_t revision;
|
||||
uint64_t entry_count;
|
||||
LIMINE_PTR(struct limine_flanterm_fb_init_params **) entries;
|
||||
};
|
||||
|
||||
struct limine_flanterm_fb_init_params_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_flanterm_fb_init_params_response *) response;
|
||||
};
|
||||
|
||||
/* Paging mode */
|
||||
|
||||
#define LIMINE_PAGING_MODE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a }
|
||||
|
||||
#define LIMINE_PAGING_MODE_X86_64_4LVL 0
|
||||
#define LIMINE_PAGING_MODE_X86_64_5LVL 1
|
||||
#define LIMINE_PAGING_MODE_X86_64_MIN LIMINE_PAGING_MODE_X86_64_4LVL
|
||||
#define LIMINE_PAGING_MODE_X86_64_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL
|
||||
|
||||
#define LIMINE_PAGING_MODE_AARCH64_4LVL 0
|
||||
#define LIMINE_PAGING_MODE_AARCH64_5LVL 1
|
||||
#define LIMINE_PAGING_MODE_AARCH64_MIN LIMINE_PAGING_MODE_AARCH64_4LVL
|
||||
#define LIMINE_PAGING_MODE_AARCH64_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL
|
||||
|
||||
#define LIMINE_PAGING_MODE_RISCV_SV39 0
|
||||
#define LIMINE_PAGING_MODE_RISCV_SV48 1
|
||||
#define LIMINE_PAGING_MODE_RISCV_SV57 2
|
||||
#define LIMINE_PAGING_MODE_RISCV_MIN LIMINE_PAGING_MODE_RISCV_SV39
|
||||
#define LIMINE_PAGING_MODE_RISCV_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48
|
||||
|
||||
#define LIMINE_PAGING_MODE_LOONGARCH_4LVL 0
|
||||
#define LIMINE_PAGING_MODE_LOONGARCH_MIN LIMINE_PAGING_MODE_LOONGARCH_4LVL
|
||||
#define LIMINE_PAGING_MODE_LOONGARCH_DEFAULT LIMINE_PAGING_MODE_LOONGARCH_4LVL
|
||||
|
||||
struct limine_paging_mode_response {
|
||||
uint64_t revision;
|
||||
uint64_t mode;
|
||||
};
|
||||
|
||||
struct limine_paging_mode_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_paging_mode_response *) response;
|
||||
uint64_t mode;
|
||||
uint64_t max_mode;
|
||||
uint64_t min_mode;
|
||||
};
|
||||
|
||||
/* MP */
|
||||
|
||||
#define LIMINE_MP_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 }
|
||||
|
||||
struct limine_mp_info;
|
||||
|
||||
typedef void (*limine_goto_address)(struct limine_mp_info *);
|
||||
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
|
||||
#define LIMINE_MP_RESPONSE_X86_64_X2APIC (1 << 0)
|
||||
|
||||
struct limine_mp_info {
|
||||
uint32_t processor_id;
|
||||
uint32_t lapic_id;
|
||||
uint64_t reserved;
|
||||
LIMINE_PTR(limine_goto_address) goto_address;
|
||||
uint64_t extra_argument;
|
||||
};
|
||||
|
||||
struct limine_mp_response {
|
||||
uint64_t revision;
|
||||
uint32_t flags;
|
||||
uint32_t bsp_lapic_id;
|
||||
uint64_t cpu_count;
|
||||
LIMINE_PTR(struct limine_mp_info **) cpus;
|
||||
};
|
||||
|
||||
#elif defined (__aarch64__)
|
||||
|
||||
struct limine_mp_info {
|
||||
uint32_t processor_id;
|
||||
uint32_t reserved1;
|
||||
uint64_t mpidr;
|
||||
uint64_t reserved;
|
||||
LIMINE_PTR(limine_goto_address) goto_address;
|
||||
uint64_t extra_argument;
|
||||
};
|
||||
|
||||
struct limine_mp_response {
|
||||
uint64_t revision;
|
||||
uint64_t flags;
|
||||
uint64_t bsp_mpidr;
|
||||
uint64_t cpu_count;
|
||||
LIMINE_PTR(struct limine_mp_info **) cpus;
|
||||
};
|
||||
|
||||
#elif defined (__riscv) && (__riscv_xlen == 64)
|
||||
|
||||
struct limine_mp_info {
|
||||
uint64_t processor_id;
|
||||
uint64_t hartid;
|
||||
uint64_t reserved;
|
||||
LIMINE_PTR(limine_goto_address) goto_address;
|
||||
uint64_t extra_argument;
|
||||
};
|
||||
|
||||
struct limine_mp_response {
|
||||
uint64_t revision;
|
||||
uint64_t flags;
|
||||
uint64_t bsp_hartid;
|
||||
uint64_t cpu_count;
|
||||
LIMINE_PTR(struct limine_mp_info **) cpus;
|
||||
};
|
||||
|
||||
#elif defined (__loongarch__) && (__loongarch_grlen == 64)
|
||||
|
||||
struct limine_mp_info {
|
||||
uint64_t processor_id;
|
||||
uint64_t phys_id;
|
||||
uint64_t reserved;
|
||||
LIMINE_PTR(limine_goto_address) goto_address;
|
||||
uint64_t extra_argument;
|
||||
};
|
||||
|
||||
struct limine_mp_response {
|
||||
uint64_t revision;
|
||||
uint64_t flags;
|
||||
uint64_t bsp_phys_id;
|
||||
uint64_t cpu_count;
|
||||
LIMINE_PTR(struct limine_mp_info **) cpus;
|
||||
};
|
||||
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
||||
#define LIMINE_MP_REQUEST_X86_64_X2APIC (1 << 0)
|
||||
|
||||
struct limine_mp_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_mp_response *) response;
|
||||
uint64_t flags;
|
||||
};
|
||||
|
||||
/* Memory map */
|
||||
|
||||
#define LIMINE_MEMMAP_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 }
|
||||
|
||||
#define LIMINE_MEMMAP_USABLE 0
|
||||
#define LIMINE_MEMMAP_RESERVED 1
|
||||
#define LIMINE_MEMMAP_ACPI_RECLAIMABLE 2
|
||||
#define LIMINE_MEMMAP_ACPI_NVS 3
|
||||
#define LIMINE_MEMMAP_BAD_MEMORY 4
|
||||
#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5
|
||||
#define LIMINE_MEMMAP_EXECUTABLE_AND_MODULES 6
|
||||
#define LIMINE_MEMMAP_FRAMEBUFFER 7
|
||||
#define LIMINE_MEMMAP_RESERVED_MAPPED 8
|
||||
|
||||
struct limine_memmap_entry {
|
||||
uint64_t base;
|
||||
uint64_t length;
|
||||
uint64_t type;
|
||||
};
|
||||
|
||||
struct limine_memmap_response {
|
||||
uint64_t revision;
|
||||
uint64_t entry_count;
|
||||
LIMINE_PTR(struct limine_memmap_entry **) entries;
|
||||
};
|
||||
|
||||
struct limine_memmap_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_memmap_response *) response;
|
||||
};
|
||||
|
||||
/* Entry point */
|
||||
|
||||
#define LIMINE_ENTRY_POINT_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a }
|
||||
|
||||
typedef void (*limine_entry_point)(void);
|
||||
|
||||
struct limine_entry_point_response {
|
||||
uint64_t revision;
|
||||
};
|
||||
|
||||
struct limine_entry_point_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_entry_point_response *) response;
|
||||
LIMINE_PTR(limine_entry_point) entry;
|
||||
};
|
||||
|
||||
/* Executable File */
|
||||
|
||||
#define LIMINE_EXECUTABLE_FILE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 }
|
||||
|
||||
struct limine_executable_file_response {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_file *) executable_file;
|
||||
};
|
||||
|
||||
struct limine_executable_file_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_executable_file_response *) response;
|
||||
};
|
||||
|
||||
/* Module */
|
||||
|
||||
#define LIMINE_MODULE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee }
|
||||
|
||||
#define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0)
|
||||
#define LIMINE_INTERNAL_MODULE_COMPRESSED (1 << 1)
|
||||
|
||||
struct limine_internal_module {
|
||||
LIMINE_PTR(const char *) path;
|
||||
LIMINE_PTR(const char *) string;
|
||||
uint64_t flags;
|
||||
};
|
||||
|
||||
struct limine_module_response {
|
||||
uint64_t revision;
|
||||
uint64_t module_count;
|
||||
LIMINE_PTR(struct limine_file **) modules;
|
||||
};
|
||||
|
||||
struct limine_module_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_module_response *) response;
|
||||
|
||||
/* Request revision 1 */
|
||||
uint64_t internal_module_count;
|
||||
LIMINE_PTR(struct limine_internal_module **) internal_modules;
|
||||
};
|
||||
|
||||
/* RSDP */
|
||||
|
||||
#define LIMINE_RSDP_REQUEST_ID { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c }
|
||||
|
||||
struct limine_rsdp_response {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(void *) address;
|
||||
};
|
||||
|
||||
struct limine_rsdp_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_rsdp_response *) response;
|
||||
};
|
||||
|
||||
/* SMBIOS */
|
||||
|
||||
#define LIMINE_SMBIOS_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee }
|
||||
|
||||
struct limine_smbios_response {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(void *) entry_32;
|
||||
LIMINE_PTR(void *) entry_64;
|
||||
};
|
||||
|
||||
struct limine_smbios_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_smbios_response *) response;
|
||||
};
|
||||
|
||||
/* EFI system table */
|
||||
|
||||
#define LIMINE_EFI_SYSTEM_TABLE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc }
|
||||
|
||||
struct limine_efi_system_table_response {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(void *) address;
|
||||
};
|
||||
|
||||
struct limine_efi_system_table_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_efi_system_table_response *) response;
|
||||
};
|
||||
|
||||
/* EFI memory map */
|
||||
|
||||
#define LIMINE_EFI_MEMMAP_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 }
|
||||
|
||||
struct limine_efi_memmap_response {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(void *) memmap;
|
||||
uint64_t memmap_size;
|
||||
uint64_t desc_size;
|
||||
uint64_t desc_version;
|
||||
};
|
||||
|
||||
struct limine_efi_memmap_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_efi_memmap_response *) response;
|
||||
};
|
||||
|
||||
/* Date at boot */
|
||||
|
||||
#define LIMINE_DATE_AT_BOOT_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 }
|
||||
|
||||
struct limine_date_at_boot_response {
|
||||
uint64_t revision;
|
||||
int64_t timestamp;
|
||||
};
|
||||
|
||||
struct limine_date_at_boot_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_date_at_boot_response *) response;
|
||||
};
|
||||
|
||||
/* Executable address */
|
||||
|
||||
#define LIMINE_EXECUTABLE_ADDRESS_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 }
|
||||
|
||||
struct limine_executable_address_response {
|
||||
uint64_t revision;
|
||||
uint64_t physical_base;
|
||||
uint64_t virtual_base;
|
||||
};
|
||||
|
||||
struct limine_executable_address_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_executable_address_response *) response;
|
||||
};
|
||||
|
||||
/* Device Tree Blob */
|
||||
|
||||
#define LIMINE_DTB_REQUEST_ID { LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 }
|
||||
|
||||
struct limine_dtb_response {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(void *) dtb_ptr;
|
||||
};
|
||||
|
||||
struct limine_dtb_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_dtb_response *) response;
|
||||
};
|
||||
|
||||
/* RISC-V Boot Hart ID */
|
||||
|
||||
#define LIMINE_RISCV_BSP_HARTID_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x1369359f025525f9, 0x2ff2a56178391bb6 }
|
||||
|
||||
struct limine_riscv_bsp_hartid_response {
|
||||
uint64_t revision;
|
||||
uint64_t bsp_hartid;
|
||||
};
|
||||
|
||||
struct limine_riscv_bsp_hartid_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_riscv_bsp_hartid_response *) response;
|
||||
};
|
||||
|
||||
/* Bootloader Performance */
|
||||
|
||||
#define LIMINE_BOOTLOADER_PERFORMANCE_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x6b50ad9bf36d13ad, 0xdc4c7e88fc759e17 }
|
||||
|
||||
struct limine_bootloader_performance_response {
|
||||
uint64_t revision;
|
||||
uint64_t reset_usec;
|
||||
uint64_t init_usec;
|
||||
uint64_t exec_usec;
|
||||
};
|
||||
|
||||
struct limine_bootloader_performance_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_bootloader_performance_response *) response;
|
||||
};
|
||||
|
||||
#define LIMINE_KEEP_IOMMU_REQUEST_ID { LIMINE_COMMON_MAGIC, 0x8ebaabe51f490179, 0x2aa86a59ffb4ab0f }
|
||||
|
||||
struct limine_keep_iommu_response {
|
||||
uint64_t revision;
|
||||
};
|
||||
|
||||
struct limine_keep_iommu_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_keep_iommu_response *) response;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+335
@@ -0,0 +1,335 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <limine.h>
|
||||
#include "video/render.h"
|
||||
#include "video/tga.h"
|
||||
#include "stdio.h"
|
||||
#include "arch/x86_64/gdt.h"
|
||||
#include "arch/x86_64/idt.h"
|
||||
#include "arch/x86_64/isr.h"
|
||||
#include "arch/x86_64/irq.h"
|
||||
#include "mm/memory.h"
|
||||
#include "mm/pmm.h"
|
||||
#include "mm/vmm.h"
|
||||
#include "arch/x86_64/ata.h"
|
||||
#include "fs/ext2.h"
|
||||
#include "string.h"
|
||||
#include "arch/x86_64/io.h"
|
||||
#include "arch/x86_64/usermode.h"
|
||||
#include "syscall/syscall.h"
|
||||
#include "fs/vfs.h"
|
||||
|
||||
uintptr_t g_hhdm_offset;
|
||||
#define CPU_STACK_SIZE (64 * 1024)
|
||||
|
||||
// Set the base revision to 6, this is recommended as this is the latest
|
||||
// base revision described by the Limine boot protocol specification.
|
||||
// See specification for further info.
|
||||
|
||||
__attribute__((used, section(".limine_requests")))
|
||||
static volatile uint64_t limine_base_revision[] = LIMINE_BASE_REVISION(6);
|
||||
|
||||
// The Limine requests can be placed anywhere, but it is important that
|
||||
// the compiler does not optimise them away, so, usually, they should
|
||||
// be made volatile or equivalent, _and_ they should be accessed at least
|
||||
// once or marked as used with the "used" attribute as done here.
|
||||
|
||||
__attribute__((used, section(".limine_requests")))
|
||||
static volatile struct limine_framebuffer_request framebuffer_request = {
|
||||
.id = LIMINE_FRAMEBUFFER_REQUEST_ID,
|
||||
.revision = 6
|
||||
};
|
||||
|
||||
__attribute__((used, section(".limine_requests")))
|
||||
static volatile struct limine_memmap_request memmap_request = {
|
||||
.id = LIMINE_MEMMAP_REQUEST_ID,
|
||||
.revision = 6
|
||||
};
|
||||
|
||||
|
||||
|
||||
__attribute__((used, section(".limine_requests")))
|
||||
volatile struct limine_stack_size_request stack_size_request = {
|
||||
.id = LIMINE_STACK_SIZE_REQUEST_ID,
|
||||
.revision = 0,
|
||||
.stack_size = CPU_STACK_SIZE,
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Finally, define the start and end markers for the Limine requests.
|
||||
// These can also be moved anywhere, to any .c file, as seen fit.
|
||||
|
||||
__attribute__((used, section(".limine_requests_start")))
|
||||
static volatile uint64_t limine_requests_start_marker[] = LIMINE_REQUESTS_START_MARKER;
|
||||
|
||||
__attribute__((used, section(".limine_requests_end")))
|
||||
static volatile uint64_t limine_requests_end_marker[] = LIMINE_REQUESTS_END_MARKER;
|
||||
|
||||
// GCC and Clang reserve the right to generate calls to the following
|
||||
// 4 functions even if they are not directly called.
|
||||
// Implement them as the C specification mandates.
|
||||
// DO NOT remove or rename these functions, or stuff will eventually break!
|
||||
// They CAN be moved to a different .c file.
|
||||
|
||||
|
||||
|
||||
// Halt and catch fire function.
|
||||
static void hcf(void) {
|
||||
for (;;) {
|
||||
asm volatile ("pause");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// The following will be our kernel's entry point.
|
||||
// If renaming kmain() to something else, make sure to change the
|
||||
// linker script accordingly.
|
||||
void kmain(void) {
|
||||
// Ensure the bootloader actually understands our base revision (see spec).
|
||||
if (LIMINE_BASE_REVISION_SUPPORTED(limine_base_revision) == false) {
|
||||
hcf();
|
||||
}
|
||||
|
||||
// Ensure we got a framebuffer.
|
||||
if (framebuffer_request.response == NULL
|
||||
|| framebuffer_request.response->framebuffer_count < 1) {
|
||||
hcf();
|
||||
}
|
||||
|
||||
// Fetch the first framebuffer.
|
||||
struct limine_framebuffer *framebuffer = framebuffer_request.response->framebuffers[0];
|
||||
|
||||
struct limine_memmap_response *memmap_response = memmap_request.response;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (!memmap_response) {
|
||||
hcf();
|
||||
}
|
||||
|
||||
|
||||
fb = framebuffer->address;
|
||||
fb_width = framebuffer->width;
|
||||
fb_height = framebuffer->height;
|
||||
fb_pitch = framebuffer->pitch / 4;
|
||||
|
||||
|
||||
printf("Hello, Kernel!\n");
|
||||
printf("Number: %d\n", 1234);
|
||||
printf("Hex: %x\n", 0xBEEF);
|
||||
|
||||
for (size_t i = 0; i < memmap_response->entry_count; i++) {
|
||||
struct limine_memmap_entry *entry = memmap_response->entries[i];
|
||||
|
||||
printf("Base: 0x%x%x, Length: 0x%x%x, Type: %d\n",
|
||||
(uint32_t)(entry->base >> 32), (uint32_t)entry->base,
|
||||
(uint32_t)(entry->length >> 32), (uint32_t)entry->length,
|
||||
entry->type);
|
||||
}
|
||||
x86_64_DisableInterrupts();
|
||||
|
||||
|
||||
|
||||
/*uint32_t msr_lo, msr_hi;
|
||||
asm volatile("rdmsr" : "=a"(msr_lo), "=d"(msr_hi) : "c"(0x1B));
|
||||
msr_lo &= ~(1 << 11);
|
||||
asm volatile("wrmsr" : : "a"(msr_lo), "d"(msr_hi), "c"(0x1B));*/
|
||||
printf("init pmm");
|
||||
pmm_init(memmap_response->entries, memmap_response->entry_count);
|
||||
printf("init slab");
|
||||
slab_init();
|
||||
printf("init vmm");
|
||||
vmm_init(memmap_response->entries, memmap_response->entry_count);
|
||||
printf("init gdt");
|
||||
x86_64_GDT_Initialize();
|
||||
x86_64_IDT_Initialize();
|
||||
x86_64_ISR_Initialize();
|
||||
x86_64_IRQ_Initialize();
|
||||
x86_64_EnableInterrupts();
|
||||
//lapic_timer_start(100);
|
||||
|
||||
ata_init();
|
||||
ata_identify();
|
||||
|
||||
if (!ext2_read_superblock()) {
|
||||
printf("EXT2 failed\n");
|
||||
hcf();
|
||||
}
|
||||
|
||||
if (!ext2_read_group_desc_table()) {
|
||||
printf("GDT failed\n");
|
||||
hcf();
|
||||
}
|
||||
|
||||
ext2_read_root_dir();
|
||||
printf("test");
|
||||
|
||||
|
||||
uint8_t* file_buffer = kmalloc(4096); // adjust if needed
|
||||
uint32_t file_size = 0;
|
||||
|
||||
if (ext2_read_file_from_root("a.txt", file_buffer, &file_size)) {
|
||||
printf("Read file (size %d):\n", file_size);
|
||||
|
||||
for (uint32_t i = 0; i < file_size; i++) {
|
||||
printf("%c", file_buffer[i]); // or printf("%c", ...)
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
} else {
|
||||
printf("Failed to read file\n");
|
||||
}
|
||||
|
||||
kfree(file_buffer);
|
||||
|
||||
uint8_t* file2_buffer = kmalloc(4096); // adjust if needed
|
||||
uint32_t file2_size = 0;
|
||||
|
||||
if (ext2_read_file_from_root("dogcatman.txt", file2_buffer, &file2_size)) {
|
||||
printf("Read file (size %d):\n", file2_size);
|
||||
|
||||
for (uint32_t i = 0; i < file2_size; i++) {
|
||||
printf("%c", file2_buffer[i]); // or printf("%c", ...)
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
} else {
|
||||
printf("Failed to read file\n");
|
||||
}
|
||||
|
||||
kfree(file2_buffer);
|
||||
|
||||
uint8_t* file3_buffer = kmalloc(4096); // adjust if needed
|
||||
uint32_t file3_size = 0;
|
||||
|
||||
if (ext2_read_file_from_root("test.txt", file3_buffer, &file3_size)) {
|
||||
printf("Read file (size %d):\n", file3_size);
|
||||
|
||||
for (uint32_t i = 0; i < file3_size; i++) {
|
||||
printf("%c", file3_buffer[i]); // or printf("%c", ...)
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
} else {
|
||||
printf("Failed to read file\n");
|
||||
}
|
||||
|
||||
kfree(file3_buffer);
|
||||
|
||||
uint8_t* file4_buffer = kmalloc(4096); // adjust if needed
|
||||
uint32_t file4_size = 0;
|
||||
|
||||
if (ext2_read_file_from_root("qwerty.txt", file4_buffer, &file4_size)) {
|
||||
printf("Read file (size %d):\n", file4_size);
|
||||
|
||||
for (uint32_t i = 0; i < file4_size; i++) {
|
||||
printf("%c", file4_buffer[i]); // or printf("%c", ...)
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
} else {
|
||||
printf("Failed to read file\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
kfree(file4_buffer);
|
||||
|
||||
const char* msg = "hello i wrote from kernel!";
|
||||
|
||||
ext2_write_file_from_root("qwerty.txt", (const uint8_t*)msg, strlen(msg), EXT2_WRITE_APPEND);
|
||||
|
||||
uint8_t* file5_buffer = kmalloc(4096); // adjust if needed
|
||||
uint32_t file5_size = 0;
|
||||
|
||||
if (ext2_read_file_from_root("qwerty.txt", file5_buffer, &file5_size)) {
|
||||
printf("Read file (size %d):\n", file5_size);
|
||||
|
||||
for (uint32_t i = 0; i < file5_size; i++) {
|
||||
printf("%c", file5_buffer[i]); // or printf("%c", ...)
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
} else {
|
||||
printf("Failed to read file\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
kfree(file5_buffer);
|
||||
|
||||
uint32_t inum = ext2_resolve_path("charlie.tga");
|
||||
if (!inum) {
|
||||
printf("file not found\n");
|
||||
hcf();
|
||||
}
|
||||
|
||||
ext2_inode_t inode;
|
||||
if (!ext2_read_inode(inum, &inode)) {
|
||||
printf("inode read failed\n");
|
||||
hcf();
|
||||
}
|
||||
|
||||
uint32_t tga_size = inode.i_size;
|
||||
if (!tga_size) {
|
||||
printf("tga file is empty\n");
|
||||
hcf();
|
||||
}
|
||||
|
||||
uint8_t *file_buf = kmalloc(tga_size);
|
||||
if (!file_buf) {
|
||||
printf("OOM allocating tga buffer (%u bytes)\n", tga_size);
|
||||
hcf();
|
||||
}
|
||||
|
||||
if (!ext2_read_file(&inode, file_buf)) {
|
||||
printf("read failed\n");
|
||||
kfree(file_buf);
|
||||
hcf();
|
||||
}
|
||||
|
||||
uint32_t *img = tga_parse(file_buf, tga_size);
|
||||
kfree(file_buf); // free the raw file buffer as soon as parse is done
|
||||
|
||||
if (!img) {
|
||||
printf("tga parse failed\n");
|
||||
hcf();
|
||||
}
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int new_w = img[0] * 5;
|
||||
int new_h = img[1] * 5;
|
||||
clear_screen(0xFF1E1E1E);
|
||||
draw_image_bilinear(img, x, y, new_w, new_h);
|
||||
kfree(img);
|
||||
|
||||
//clear_screen(0xFF1E1E1E);
|
||||
|
||||
fd_t fd = VFS_Open("/a.txt");
|
||||
if (fd < 0) {
|
||||
printf("asudg");
|
||||
}
|
||||
uint8_t buf[128];
|
||||
int n;
|
||||
|
||||
while ((n = VFS_Read(fd, buf, sizeof(buf))) > 0)
|
||||
{
|
||||
VFS_Write(VFS_FD_STDOUT, buf, n);
|
||||
}
|
||||
|
||||
VFS_Close(fd);
|
||||
|
||||
x86_64_EnableInterrupts();
|
||||
syscall_init();
|
||||
start_userspace();
|
||||
printf("tst");
|
||||
|
||||
// We're done, just hang...
|
||||
hcf();
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
#include <stdint.h>
|
||||
#include "stddef.h"
|
||||
|
||||
#include "pmm.h"
|
||||
#include "stdio.h"
|
||||
#include "vmm.h"
|
||||
#include <stdbool.h>
|
||||
#include "mp/spinlock.h"
|
||||
|
||||
|
||||
|
||||
void *memcpy(void *restrict dest, const void *restrict src, size_t n) {
|
||||
uint8_t *restrict pdest = (uint8_t *restrict)dest;
|
||||
const uint8_t *restrict psrc = (const uint8_t *restrict)src;
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
pdest[i] = psrc[i];
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *memset(void *s, int c, size_t n) {
|
||||
uint8_t *p = (uint8_t *)s;
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
p[i] = (uint8_t)c;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void *memmove(void *dest, const void *src, size_t n) {
|
||||
uint8_t *pdest = (uint8_t *)dest;
|
||||
const uint8_t *psrc = (const uint8_t *)src;
|
||||
|
||||
if ((uintptr_t)src > (uintptr_t)dest) {
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
pdest[i] = psrc[i];
|
||||
}
|
||||
} else if ((uintptr_t)src < (uintptr_t)dest) {
|
||||
for (size_t i = n; i > 0; i--) {
|
||||
pdest[i-1] = psrc[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
int memcmp(const void *s1, const void *s2, size_t n) {
|
||||
const uint8_t *p1 = (const uint8_t *)s1;
|
||||
const uint8_t *p2 = (const uint8_t *)s2;
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (p1[i] != p2[i]) {
|
||||
return p1[i] < p2[i] ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "stddef.h"
|
||||
#include "slab.h" // kmalloc/kfree now come from slab
|
||||
|
||||
#define ALIGN_DOWN(x, a) ((x) & ~((a)-1))
|
||||
#define ALIGN_UP(x, a) (((x) + (a)-1) & ~((a)-1))
|
||||
#define SIZEOF_ARRAY(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0]))
|
||||
|
||||
#define DIV_ROUNDUP(A, B) \
|
||||
({ \
|
||||
__auto_type _a_ = A; \
|
||||
__auto_type _b_ = B; \
|
||||
(_a_ + (_b_ - 1)) / _b_; \
|
||||
})
|
||||
|
||||
|
||||
void *memcpy(void *restrict dest, const void *restrict src, size_t n);
|
||||
void *memset(void *s, int c, size_t n);
|
||||
int memcmp(const void *s1, const void *s2, size_t n);
|
||||
void *memmove(void *dest, const void *src, size_t n);
|
||||
#define memzero(a, b) memset(a, 0, b)
|
||||
|
||||
|
||||
|
||||
#define kmalloc slab_alloc
|
||||
#define kfree slab_free
|
||||
#define krealloc slab_realloc
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
#include "pmm.h"
|
||||
#include "vmm.h" // for MEM_PHYS_OFFSET
|
||||
#include "memory.h" // memset
|
||||
#include "stdio.h"
|
||||
|
||||
static spinlock_t memory_lock = SPINLOCK_INIT;
|
||||
static uint8_t *bitmap = NULL;
|
||||
static uint64_t total_page_count = 0;
|
||||
static uint64_t last_used_index = 0;
|
||||
static uint64_t free_pages = 0;
|
||||
|
||||
void pmm_init(struct limine_memmap_entry **memmap, size_t memmapentries) {
|
||||
uint64_t highest_addr = 0;
|
||||
size_t memmap_entries = memmapentries - 1;
|
||||
for (size_t i = 0; i < memmap_entries; i++) {
|
||||
if (memmap[i]->type != LIMINE_MEMMAP_USABLE &&
|
||||
memmap[i]->type != LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE)
|
||||
continue;
|
||||
uint64_t top = memmap[i]->base + memmap[i]->length;
|
||||
if (top > highest_addr) highest_addr = top;
|
||||
}
|
||||
|
||||
total_page_count = highest_addr / PAGE_SIZE;
|
||||
size_t bitmap_size = ALIGN_UP(total_page_count / 8, PAGE_SIZE);
|
||||
printf("MEM_PHYS_OFFSET: %x\n", MEM_PHYS_OFFSET);
|
||||
printf("memmap_entries: %u\n", memmap_entries);
|
||||
// Find place for bitmap
|
||||
for (size_t i = 0; i < memmap_entries; i++) {
|
||||
printf("i: %u\n", i);
|
||||
|
||||
if (memmap[i]->type != LIMINE_MEMMAP_USABLE) continue;
|
||||
if (memmap[i]->length >= bitmap_size) {
|
||||
printf("test\n");
|
||||
bitmap = (uint8_t *)(memmap[i]->base + MEM_PHYS_OFFSET);
|
||||
printf("bitmap: %x\n", bitmap);
|
||||
printf("bitmap_size: %x\n", bitmap_size);
|
||||
memset(bitmap, 0xFF, bitmap_size);
|
||||
printf("test3\n");
|
||||
printf("memmap base: %x\n", memmap[i]->base);
|
||||
printf("memmap length: %x\n", memmap[i]->length);
|
||||
|
||||
memmap[i]->base += bitmap_size;
|
||||
memmap[i]->length -= bitmap_size;
|
||||
printf("test4\n");
|
||||
printf("memmap[7]->type: %u\n", memmap[7]->type);
|
||||
printf("memmap[8]->type: %u\n", memmap[8]->type);
|
||||
printf("memmap[9]->type: %u\n", memmap[9]->type);
|
||||
printf("memmap[10]->type: %u\n", memmap[10]->type); //#define LIMINE_MEMMAP_USABLE 0
|
||||
printf("memmap[11]->type: %u\n", memmap[11]->type); //#define LIMINE_MEMMAP_RESERVED 1
|
||||
printf("memmap[12]->type: %u\n", memmap[12]->type); //#define LIMINE_MEMMAP_ACPI_RECLAIMABLE 2
|
||||
printf("memmap[13]->type: %u\n", memmap[13]->type); //#define LIMINE_MEMMAP_ACPI_NVS 3
|
||||
printf("memmap[14]->type: %u\n", memmap[14]->type); //#define LIMINE_MEMMAP_BAD_MEMORY 4
|
||||
printf("memmap[15]->type: %u\n", memmap[15]->type); //#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5
|
||||
printf("memmap[16]->type: %u\n", memmap[16]->type); //#define LIMINE_MEMMAP_EXECUTABLE_AND_MODULES 6
|
||||
printf("memmap[17]->type: %u\n", memmap[17]->type); //#define LIMINE_MEMMAP_FRAMEBUFFER 7
|
||||
//printf("memmap[18]->type: %u\n", memmap[18]->type); //#define LIMINE_MEMMAP_RESERVED_MAPPED 8, commented out because it triple faults for some reason
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
printf("break");
|
||||
|
||||
// Mark usable pages free
|
||||
for (size_t i = 0; i < memmap_entries; i++) {
|
||||
if (memmap[i]->type != LIMINE_MEMMAP_USABLE) continue;
|
||||
for (uint64_t j = 0; j < memmap[i]->length; j += PAGE_SIZE) {
|
||||
size_t bit = (memmap[i]->base + j) / PAGE_SIZE;
|
||||
bitmap[bit / 8] &= ~(1u << (bit % 8));
|
||||
free_pages++;
|
||||
}
|
||||
}
|
||||
printf("done");
|
||||
}
|
||||
|
||||
static void *inner_alloc(size_t pages, size_t limit) {
|
||||
size_t p = 0;
|
||||
while (last_used_index < limit) {
|
||||
if (!(bitmap[last_used_index / 8] & (1u << (last_used_index % 8)))) {
|
||||
if (++p == pages) {
|
||||
size_t page = last_used_index - pages + 1;
|
||||
for (size_t i = page; i < page + pages; i++)
|
||||
bitmap[i / 8] |= (1u << (i % 8));
|
||||
last_used_index = page + pages;
|
||||
return (void *)(page * PAGE_SIZE);
|
||||
}
|
||||
} else {
|
||||
p = 0;
|
||||
}
|
||||
last_used_index++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *pmm_alloc(size_t pages) {
|
||||
spinlock_acquire_or_wait(&memory_lock);
|
||||
size_t last = last_used_index;
|
||||
void *ret = inner_alloc(pages, total_page_count);
|
||||
if (!ret) {
|
||||
last_used_index = 0;
|
||||
ret = inner_alloc(pages, last);
|
||||
}
|
||||
if (ret) free_pages -= pages;
|
||||
spinlock_drop(&memory_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *pmm_allocz(size_t pages) {
|
||||
void *ret = pmm_alloc(pages);
|
||||
|
||||
if (ret) {
|
||||
memset((void *)((uintptr_t)ret + MEM_PHYS_OFFSET), 0, pages * PAGE_SIZE); // this is at fault for the page fault
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void pmm_free(void *addr, size_t pages) {
|
||||
spinlock_acquire_or_wait(&memory_lock);
|
||||
size_t page = (uintptr_t)addr / PAGE_SIZE;
|
||||
for (size_t i = 0; i < pages; i++)
|
||||
bitmap[(page + i) / 8] &= ~(1u << ((page + i) % 8));
|
||||
free_pages += pages;
|
||||
spinlock_drop(&memory_lock);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <limine.h>
|
||||
|
||||
void pmm_init(struct limine_memmap_entry **memmap, size_t memmap_entries);
|
||||
void *pmm_alloc(size_t pages);
|
||||
void *pmm_allocz(size_t pages);
|
||||
void pmm_free(void *addr, size_t pages);
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
#include "memory.h"
|
||||
#include <mp/spinlock.h>
|
||||
#include <mm/pmm.h>
|
||||
#include <mm/slab.h>
|
||||
#include <mm/vmm.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "stdio.h"
|
||||
|
||||
struct slab {
|
||||
spinlock_t lock;
|
||||
void **first_free;
|
||||
size_t ent_size;
|
||||
};
|
||||
|
||||
struct slab_header {
|
||||
struct slab *slab;
|
||||
};
|
||||
|
||||
struct alloc_metadata {
|
||||
size_t pages;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static struct slab slabs[10] = {0};
|
||||
|
||||
static inline struct slab *slab_for(size_t size) {
|
||||
for (size_t i = 0; i < SIZEOF_ARRAY(slabs); i++) {
|
||||
struct slab *slab = &slabs[i];
|
||||
if (slab->ent_size >= size) {
|
||||
return slab;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void create_slab(struct slab *slab, size_t ent_size) {
|
||||
spinlock_init(&slab->lock);
|
||||
slab->first_free = (void **)((uint64_t)pmm_alloc(1) + MEM_PHYS_OFFSET);
|
||||
slab->ent_size = ent_size;
|
||||
|
||||
size_t header_offset = ALIGN_UP(sizeof(struct slab_header), ent_size);
|
||||
size_t available_size = PAGE_SIZE - header_offset;
|
||||
|
||||
struct slab_header *slab_ptr = (struct slab_header *)slab->first_free;
|
||||
slab_ptr->slab = slab;
|
||||
slab->first_free = (void **)((void *)slab->first_free + header_offset);
|
||||
|
||||
void **arr = (void **)slab->first_free;
|
||||
size_t max = available_size / ent_size - 1;
|
||||
size_t fact = ent_size / sizeof(void *);
|
||||
|
||||
for (size_t i = 0; i < max; i++) {
|
||||
arr[i * fact] = &arr[(i + 1) * fact];
|
||||
}
|
||||
arr[max * fact] = NULL;
|
||||
}
|
||||
|
||||
static void *alloc_from_slab(struct slab *slab) {
|
||||
spinlock_acquire_or_wait(&slab->lock);
|
||||
|
||||
if (slab->first_free == NULL) {
|
||||
create_slab(slab, slab->ent_size);
|
||||
}
|
||||
|
||||
void **old_free = slab->first_free;
|
||||
slab->first_free = *old_free;
|
||||
memset(old_free, 0, slab->ent_size);
|
||||
|
||||
spinlock_drop(&slab->lock);
|
||||
return old_free;
|
||||
}
|
||||
|
||||
static void free_in_slab(struct slab *slab, void *addr) {
|
||||
spinlock_acquire_or_wait(&slab->lock);
|
||||
|
||||
if (addr == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
void **new_head = addr;
|
||||
*new_head = slab->first_free;
|
||||
slab->first_free = new_head;
|
||||
|
||||
cleanup:
|
||||
spinlock_drop(&slab->lock);
|
||||
}
|
||||
|
||||
void slab_init(void) {
|
||||
memzero(slabs, sizeof(struct slab) * 10);
|
||||
create_slab(&slabs[0], 8);
|
||||
create_slab(&slabs[1], 16);
|
||||
create_slab(&slabs[2], 24);
|
||||
create_slab(&slabs[3], 32);
|
||||
create_slab(&slabs[4], 48);
|
||||
create_slab(&slabs[5], 64);
|
||||
create_slab(&slabs[6], 128);
|
||||
create_slab(&slabs[7], 256);
|
||||
create_slab(&slabs[8], 512);
|
||||
create_slab(&slabs[9], 1024);
|
||||
}
|
||||
|
||||
void *slab_alloc(size_t size) {
|
||||
|
||||
struct slab *slab = slab_for(size);
|
||||
if (slab != NULL) {
|
||||
return alloc_from_slab(slab);
|
||||
}
|
||||
|
||||
size_t page_count = DIV_ROUNDUP(size, PAGE_SIZE);
|
||||
|
||||
uint64_t ret = (uint64_t)pmm_allocz(page_count + 1);
|
||||
if ((void *)ret == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret += MEM_PHYS_OFFSET;
|
||||
struct alloc_metadata *metadata = (struct alloc_metadata *)ret;
|
||||
|
||||
metadata->pages = page_count;
|
||||
metadata->size = size;
|
||||
|
||||
return (void *)(ret + PAGE_SIZE);
|
||||
}
|
||||
|
||||
void *slab_realloc(void *addr, size_t new_size) {
|
||||
if (addr == NULL) {
|
||||
return slab_alloc(new_size);
|
||||
}
|
||||
|
||||
if (((uintptr_t)addr & 0xfff) == 0) {
|
||||
struct alloc_metadata *metadata =
|
||||
(struct alloc_metadata *)(addr - PAGE_SIZE);
|
||||
if (DIV_ROUNDUP(metadata->size, PAGE_SIZE) ==
|
||||
DIV_ROUNDUP(new_size, PAGE_SIZE)) {
|
||||
metadata->size = new_size;
|
||||
return addr;
|
||||
}
|
||||
|
||||
void *new_addr = slab_alloc(new_size);
|
||||
if (new_addr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (metadata->size > new_size) {
|
||||
memcpy(new_addr, addr, new_size);
|
||||
} else {
|
||||
memcpy(new_addr, addr, metadata->size);
|
||||
}
|
||||
|
||||
slab_free(addr);
|
||||
return new_addr;
|
||||
}
|
||||
|
||||
struct slab_header *slab_header =
|
||||
(struct slab_header *)((uintptr_t)addr & ~0xfff);
|
||||
struct slab *slab = slab_header->slab;
|
||||
|
||||
if (new_size > slab->ent_size) {
|
||||
void *new_addr = slab_alloc(new_size);
|
||||
if (new_addr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(new_addr, addr, slab->ent_size);
|
||||
free_in_slab(slab, addr);
|
||||
return new_addr;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void slab_free(void *addr) {
|
||||
if (addr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (((uintptr_t)addr & 0xfff) == 0) {
|
||||
struct alloc_metadata *metadata =
|
||||
(struct alloc_metadata *)(addr - PAGE_SIZE);
|
||||
pmm_free((void *)((uintptr_t)metadata - MEM_PHYS_OFFSET),
|
||||
metadata->pages + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
struct slab_header *slab_header =
|
||||
(struct slab_header *)((uintptr_t)addr & ~0xfff);
|
||||
free_in_slab(slab_header->slab, addr);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef SLAB_H
|
||||
#define SLAB_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void slab_init(void);
|
||||
void *slab_alloc(size_t size);
|
||||
void *slab_realloc(void *addr, size_t size);
|
||||
void slab_free(void *addr);
|
||||
|
||||
static inline void *kmalloc(size_t size) {
|
||||
return slab_alloc(size);
|
||||
}
|
||||
|
||||
static inline void *krealloc(void *addr, size_t size) {
|
||||
return slab_realloc(addr, size);
|
||||
}
|
||||
|
||||
static inline void kfree(void *addr) {
|
||||
return slab_free(addr);
|
||||
}
|
||||
|
||||
#define kcalloc(A, B) kmalloc(A * sizeof(B))
|
||||
|
||||
#endif
|
||||
+295
@@ -0,0 +1,295 @@
|
||||
#include "vmm.h"
|
||||
#include "pmm.h"
|
||||
#include "memory.h"
|
||||
#include "stdio.h"
|
||||
|
||||
|
||||
struct pagemap *kernel_pagemap = NULL;
|
||||
|
||||
__attribute__((used, section(".limine_requests")))
|
||||
volatile struct limine_hhdm_request hhdm_request = {
|
||||
.id = LIMINE_HHDM_REQUEST_ID, .revision = 0
|
||||
};
|
||||
|
||||
__attribute__((used, section(".limine_requests")))
|
||||
volatile struct limine_executable_address_request kernel_address_request = {
|
||||
.id = LIMINE_EXECUTABLE_ADDRESS_REQUEST_ID, .revision = 0
|
||||
};
|
||||
|
||||
__attribute__((used, section(".limine_requests")))
|
||||
volatile struct limine_paging_mode_request paging_mode_request = {
|
||||
.id = LIMINE_PAGING_MODE_REQUEST_ID, .revision = 0, .mode = LIMINE_PAGING_MODE_X86_64_4LVL
|
||||
};
|
||||
|
||||
static uint64_t *get_next_level(uint64_t *top_level, size_t idx, bool allocate) {
|
||||
if (top_level[idx] & 1)
|
||||
return (uint64_t *)((top_level[idx] & ~0xFFFULL) + MEM_PHYS_OFFSET);
|
||||
|
||||
if (!allocate) return NULL;
|
||||
|
||||
void *next = pmm_allocz(1);
|
||||
if (!next) return NULL;
|
||||
|
||||
top_level[idx] = (uint64_t)next | 0b111;
|
||||
return (uint64_t *)((uintptr_t)next + MEM_PHYS_OFFSET);
|
||||
}
|
||||
|
||||
void vmm_init(struct limine_memmap_entry **memmap, size_t memmapentries) {
|
||||
if (!hhdm_request.response) {
|
||||
printf("PRAISE BE TO LIMINE WE DON'T HAE HHDM RESP");
|
||||
}
|
||||
size_t memmap_entries = memmapentries - 1;
|
||||
kernel_pagemap = kmalloc(sizeof(struct pagemap));
|
||||
if (!kernel_pagemap) {
|
||||
printf("VMM: OOm allocating kernel_pagemap\n");
|
||||
while(1) asm volatile ("hlt");
|
||||
}
|
||||
spinlock_init(&kernel_pagemap->lock);
|
||||
kernel_pagemap->top_level = (uint64_t *)((uintptr_t)pmm_allocz(1) + MEM_PHYS_OFFSET);
|
||||
if (!kernel_pagemap->top_level) {
|
||||
printf("VMM: OOM allocating PML4\n");
|
||||
while (1) asm volatile ("hlt");
|
||||
}
|
||||
|
||||
// Identity map lower half + HHDM
|
||||
for (uint64_t p = 256; p < 512; p++)
|
||||
get_next_level(kernel_pagemap->top_level, p, true);
|
||||
|
||||
// Map all physical memory (HHDM)
|
||||
for (uint64_t p = 0; p < 0x8000000000ULL; p += 0x200000) // 2 MiB pages up to 256 GiB
|
||||
vmm_map_page(kernel_pagemap, p + MEM_PHYS_OFFSET, p, PAGE_READ | PAGE_WRITE, Size2MiB);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Map kernel sections with correct permissions
|
||||
extern char __text_start_addr[], __text_end_addr[];
|
||||
extern char __rodata_start_addr[], __rodata_end_addr[];
|
||||
extern char __data_start_addr[], __data_end_addr[];
|
||||
extern char __bss_start_addr[], __bss_end_addr[];
|
||||
|
||||
uintptr_t text_start = ALIGN_DOWN((uintptr_t)__text_start_addr, PAGE_SIZE);
|
||||
uintptr_t text_end = ALIGN_UP((uintptr_t)__text_end_addr, PAGE_SIZE);
|
||||
uintptr_t rodata_start = ALIGN_DOWN((uintptr_t)__rodata_start_addr, PAGE_SIZE);
|
||||
uintptr_t rodata_end = ALIGN_UP((uintptr_t)__rodata_end_addr, PAGE_SIZE);
|
||||
uintptr_t data_start = ALIGN_DOWN((uintptr_t)__data_start_addr, PAGE_SIZE);
|
||||
uintptr_t data_end = ALIGN_UP((uintptr_t)__data_end_addr, PAGE_SIZE);
|
||||
uintptr_t bss_start = ALIGN_DOWN((uintptr_t)__bss_start_addr, PAGE_SIZE);
|
||||
uintptr_t bss_end = ALIGN_UP((uintptr_t)__bss_end_addr, PAGE_SIZE);
|
||||
|
||||
uint64_t paddr = kernel_address_request.response->physical_base;
|
||||
uint64_t vaddr = kernel_address_request.response->virtual_base;
|
||||
|
||||
|
||||
// Map everything from kernel load address up to .text (this is the requests section)
|
||||
for (uintptr_t va = vaddr; va < text_start; va += PAGE_SIZE) {
|
||||
uint64_t pa = va - vaddr + paddr;
|
||||
vmm_map_page(kernel_pagemap, va, pa,
|
||||
PAGE_READ | PAGE_WRITE | PAGE_NO_EXECUTE, Size4KiB);
|
||||
}
|
||||
for (uintptr_t va = text_start; va < text_end; va += PAGE_SIZE) {
|
||||
uint64_t pa = va - vaddr + paddr;
|
||||
vmm_map_page(kernel_pagemap, va, pa, PAGE_READ, Size4KiB);
|
||||
}
|
||||
// .rodata : R-- + NX
|
||||
for (uintptr_t va = rodata_start; va < rodata_end; va += PAGE_SIZE) {
|
||||
uint64_t pa = va - vaddr + paddr;
|
||||
vmm_map_page(kernel_pagemap, va, pa, PAGE_READ | PAGE_NO_EXECUTE, Size4KiB);
|
||||
}
|
||||
|
||||
// .data : RW- + NX
|
||||
for (uintptr_t va = data_start; va < data_end; va += PAGE_SIZE) {
|
||||
uint64_t pa = va - vaddr + paddr;
|
||||
vmm_map_page(kernel_pagemap, va, pa, PAGE_READ | PAGE_WRITE | PAGE_NO_EXECUTE, Size4KiB);
|
||||
}
|
||||
|
||||
// .bss : RW- + NX (stack lives here)
|
||||
for (uintptr_t va = bss_start; va < bss_end; va += PAGE_SIZE) {
|
||||
uint64_t pa = va - vaddr + paddr;
|
||||
vmm_map_page(kernel_pagemap, va, pa, PAGE_READ | PAGE_WRITE | PAGE_NO_EXECUTE, Size4KiB);
|
||||
}
|
||||
|
||||
vmm_switch_pagemap(kernel_pagemap);
|
||||
printf("VMM: switched to new kernel pagemap\n");
|
||||
}
|
||||
|
||||
void vmm_switch_pagemap(struct pagemap *pagemap) {
|
||||
uint64_t phys_cr3 = (uintptr_t)pagemap->top_level - MEM_PHYS_OFFSET;
|
||||
printf("VMM: loading CR3 with PML4 @ 0x%lx\n", phys_cr3);
|
||||
asm volatile("mov %0, %%cr3" : : "r"((uint64_t)pagemap->top_level - MEM_PHYS_OFFSET) : "memory");
|
||||
printf("rah");
|
||||
}
|
||||
|
||||
bool vmm_map_page(struct pagemap *pagemap, uint64_t virt, uint64_t phys,
|
||||
uint64_t flags, enum page_size pg_size) {
|
||||
spinlock_acquire_or_wait(&pagemap->lock);
|
||||
|
||||
// Calculate the indices in the various tables using the virtual address
|
||||
size_t pml5_entry = (virt & ((uint64_t)0x1FF << 48)) >> 48;
|
||||
size_t pml4_entry = (virt & ((uint64_t)0x1FF << 39)) >> 39;
|
||||
size_t pml3_entry = (virt & ((uint64_t)0x1FF << 30)) >> 30;
|
||||
size_t pml2_entry = (virt & ((uint64_t)0x1FF << 21)) >> 21;
|
||||
size_t pml1_entry = (virt & ((uint64_t)0x1FF << 12)) >> 12;
|
||||
|
||||
uint64_t *pml5, *pml4, *pml3, *pml2, *pml1;
|
||||
|
||||
if (paging_mode_request.response->mode == LIMINE_PAGING_MODE_X86_64_5LVL) {
|
||||
pml5 = pagemap->top_level;
|
||||
goto level5;
|
||||
} else {
|
||||
pml4 = pagemap->top_level;
|
||||
goto level4;
|
||||
}
|
||||
|
||||
level5:
|
||||
pml4 = get_next_level(pml5, pml5_entry, true);
|
||||
if (pml4 == NULL) {
|
||||
goto die;
|
||||
}
|
||||
level4:
|
||||
pml3 = get_next_level(pml4, pml4_entry, true);
|
||||
if (pml3 == NULL) {
|
||||
goto die;
|
||||
}
|
||||
|
||||
pml2 = get_next_level(pml3, pml3_entry, true);
|
||||
if (pml2 == NULL) {
|
||||
goto die;
|
||||
}
|
||||
|
||||
if (pg_size == Size2MiB) {
|
||||
pml2[pml2_entry] = phys | flags | (1 << 7);
|
||||
spinlock_drop(&pagemap->lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
pml1 = get_next_level(pml2, pml2_entry, true);
|
||||
if (pml1 == NULL) {
|
||||
die:
|
||||
spinlock_drop(&pagemap->lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
pml1[pml1_entry] = phys | flags;
|
||||
|
||||
spinlock_drop(&pagemap->lock);
|
||||
return true; // simplified for this response
|
||||
}
|
||||
|
||||
bool vmm_unmap_page(struct pagemap *pagemap, uintptr_t virt, bool locked) {
|
||||
if (!locked) {
|
||||
spinlock_acquire_or_wait(&pagemap->lock);
|
||||
}
|
||||
|
||||
size_t pml5_entry = (virt & ((uint64_t)0x1FF << 48)) >> 48;
|
||||
size_t pml4_entry = (virt & ((uint64_t)0x1FF << 39)) >> 39;
|
||||
size_t pml3_entry = (virt & ((uint64_t)0x1FF << 30)) >> 30;
|
||||
size_t pml2_entry = (virt & ((uint64_t)0x1FF << 21)) >> 21;
|
||||
size_t pml1_entry = (virt & ((uint64_t)0x1FF << 12)) >> 12;
|
||||
|
||||
uint64_t *pml5, *pml4, *pml3, *pml2, *pml1;
|
||||
|
||||
if (paging_mode_request.response->mode == LIMINE_PAGING_MODE_X86_64_5LVL) {
|
||||
pml5 = pagemap->top_level;
|
||||
goto level5;
|
||||
} else {
|
||||
pml4 = pagemap->top_level;
|
||||
goto level4;
|
||||
}
|
||||
|
||||
level5:
|
||||
pml4 = get_next_level(pml5, pml5_entry, false);
|
||||
if (pml4 == NULL) {
|
||||
goto die;
|
||||
}
|
||||
level4:
|
||||
pml3 = get_next_level(pml4, pml4_entry, false);
|
||||
if (pml3 == NULL) {
|
||||
goto die;
|
||||
}
|
||||
|
||||
pml2 = get_next_level(pml3, pml3_entry, false);
|
||||
if (pml2 == NULL) {
|
||||
goto die;
|
||||
}
|
||||
|
||||
pml1 = get_next_level(pml2, pml2_entry, false);
|
||||
if (pml1 == NULL) {
|
||||
goto die;
|
||||
}
|
||||
|
||||
if ((pml1[pml1_entry] & 1) == 0) {
|
||||
die:
|
||||
if (!locked) {
|
||||
spinlock_drop(&pagemap->lock);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pml1[pml1_entry] = 0;
|
||||
|
||||
asm volatile("invlpg (%0)" : : "r"(virt) : "memory");
|
||||
|
||||
if (!locked) {
|
||||
spinlock_drop(&pagemap->lock);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t *vmm_virt_to_pte(struct pagemap *pagemap, uintptr_t virt_addr,
|
||||
bool allocate) {
|
||||
// spinlock_acquire_or_wait(&pagemap->lock);
|
||||
size_t pml5_entry = (virt_addr & ((uint64_t)0x1FF << 48)) >> 48;
|
||||
size_t pml4_entry = (virt_addr & ((uint64_t)0x1FF << 39)) >> 39;
|
||||
size_t pml3_entry = (virt_addr & ((uint64_t)0x1FF << 30)) >> 30;
|
||||
size_t pml2_entry = (virt_addr & ((uint64_t)0x1FF << 21)) >> 21;
|
||||
size_t pml1_entry = (virt_addr & ((uint64_t)0x1FF << 12)) >> 12;
|
||||
|
||||
uint64_t *pml5, *pml4, *pml3, *pml2, *pml1;
|
||||
|
||||
if (paging_mode_request.response->mode == LIMINE_PAGING_MODE_X86_64_5LVL) {
|
||||
pml5 = pagemap->top_level;
|
||||
goto level5;
|
||||
} else {
|
||||
pml4 = pagemap->top_level;
|
||||
goto level4;
|
||||
}
|
||||
|
||||
level5:
|
||||
pml4 = get_next_level(pml5, pml5_entry, allocate);
|
||||
if (pml4 == NULL) {
|
||||
goto die;
|
||||
}
|
||||
level4:
|
||||
pml3 = get_next_level(pml4, pml4_entry, allocate);
|
||||
if (pml3 == NULL) {
|
||||
goto die;
|
||||
}
|
||||
|
||||
pml2 = get_next_level(pml3, pml3_entry, allocate);
|
||||
if (pml2 == NULL) {
|
||||
goto die;
|
||||
}
|
||||
|
||||
pml1 = get_next_level(pml2, pml2_entry, allocate);
|
||||
if (pml1 == NULL) {
|
||||
die:
|
||||
spinlock_drop(&pagemap->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// spinlock_drop(&pagemap->lock);
|
||||
return &pml1[pml1_entry];
|
||||
}
|
||||
|
||||
|
||||
uint64_t vmm_virt_to_phys(struct pagemap *pagemap, uint64_t virt) {
|
||||
spinlock_acquire_or_wait(&pagemap->lock);
|
||||
uint64_t *pte = vmm_virt_to_pte(pagemap, virt, false);
|
||||
spinlock_drop(&pagemap->lock);
|
||||
if (pte == NULL || (((*pte) & ~0xffffffffff000) & 1) == 0)
|
||||
return INVALID_PHYS;
|
||||
|
||||
return ((*pte) & 0xffffffffff000);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <limine.h>
|
||||
#include <stddef.h>
|
||||
#include <mp/spinlock.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define PAGE_SIZE 4096ULL
|
||||
|
||||
extern volatile struct limine_hhdm_request hhdm_request;
|
||||
|
||||
#define MEM_PHYS_OFFSET (hhdm_request.response->offset)
|
||||
|
||||
|
||||
extern volatile struct limine_executable_address_request kernel_address_request;
|
||||
|
||||
#define INVALID_PHYS 0xffffffffffffffffULL
|
||||
|
||||
#define PAGE_READ (1ULL << 0)
|
||||
#define PAGE_WRITE (1ULL << 1)
|
||||
#define PAGE_USER (1ULL << 2)
|
||||
#define PAGE_NO_EXECUTE (1ULL << 63)
|
||||
|
||||
struct pagemap {
|
||||
spinlock_t lock;
|
||||
uint64_t *top_level;
|
||||
};
|
||||
|
||||
extern struct pagemap *kernel_pagemap;
|
||||
|
||||
enum page_size { Size4KiB, Size2MiB };
|
||||
|
||||
void vmm_init(struct limine_memmap_entry **memmap, size_t memmap_entries);
|
||||
void vmm_switch_pagemap(struct pagemap *pagemap);
|
||||
bool vmm_map_page(struct pagemap *pagemap, uint64_t virt, uint64_t phys,
|
||||
uint64_t flags, enum page_size pg_size);
|
||||
uint64_t vmm_virt_to_phys(struct pagemap *pagemap, uint64_t virt);
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "spinlock.h"
|
||||
|
||||
void spinlock_init(spinlock_t *lock) {
|
||||
atomic_flag_clear(&lock->flag);
|
||||
}
|
||||
|
||||
void spinlock_acquire_or_wait(spinlock_t *lock) {
|
||||
while (atomic_flag_test_and_set_explicit(&lock->flag, memory_order_acquire))
|
||||
asm volatile("pause" ::: "memory");
|
||||
}
|
||||
|
||||
void spinlock_drop(spinlock_t *lock) {
|
||||
atomic_flag_clear_explicit(&lock->flag, memory_order_release);
|
||||
}
|
||||
|
||||
void spinlock_acquire_irqsave(spinlock_t *lock, uint64_t *flags) {
|
||||
uint64_t f;
|
||||
asm volatile("pushfq; pop %0; cli" : "=r"(f) :: "memory");
|
||||
*flags = f;
|
||||
spinlock_acquire_or_wait(lock);
|
||||
}
|
||||
|
||||
void spinlock_release_irqrestore(spinlock_t *lock, uint64_t flags) {
|
||||
spinlock_drop(lock);
|
||||
asm volatile("push %0; popfq" :: "r"(flags) : "memory", "cc");
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include <stdatomic.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
atomic_flag flag;
|
||||
} spinlock_t;
|
||||
|
||||
#define SPINLOCK_INIT ((spinlock_t){ .flag = ATOMIC_FLAG_INIT })
|
||||
|
||||
void spinlock_init(spinlock_t *lock);
|
||||
void spinlock_acquire_or_wait(spinlock_t *lock);
|
||||
void spinlock_drop(spinlock_t *lock);
|
||||
|
||||
// Old IRQ-safe API still available for compatibility
|
||||
void spinlock_acquire_irqsave(spinlock_t *lock, uint64_t *flags);
|
||||
void spinlock_release_irqrestore(spinlock_t *lock, uint64_t flags);
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include "stdio.h"
|
||||
#include "debug.h"
|
||||
#include "video/render.h"
|
||||
#include "arch/x86_64/e9.h"
|
||||
#include "mp/spinlock.h"
|
||||
|
||||
static const uint32_t g_LogSeverityColors[] =
|
||||
{
|
||||
[LVL_DEBUG] = 0xAAAAAA, // light gray
|
||||
[LVL_INFO] = 0xFFFFFF, // white
|
||||
[LVL_WARN] = 0xFFFF00, // yellow
|
||||
[LVL_ERROR] = 0xFF0000, // red
|
||||
[LVL_CRITICAL] = 0xFFFFFF, // white (can do red background separately if you want)
|
||||
};
|
||||
|
||||
static spinlock_t s_printf_lock = SPINLOCK_INIT;
|
||||
|
||||
|
||||
|
||||
void fputc(char c)
|
||||
{
|
||||
putchar(c);
|
||||
e9_putc(c);
|
||||
}
|
||||
|
||||
void fputs(const char* str)
|
||||
{
|
||||
const char* s = str;
|
||||
while (*s) fputc(*s++);
|
||||
}
|
||||
|
||||
void fputs_colored(const char* str, uint32_t color) {
|
||||
while (*str) putchar_colored(*str++, color);
|
||||
while (*str) fputc(*str++);
|
||||
}
|
||||
|
||||
const char g_HexChars[] = "0123456789abcdef";
|
||||
|
||||
void fprintf_unsigned(uint64_t number, int radix)
|
||||
{
|
||||
char buffer[32];
|
||||
int pos = 0;
|
||||
|
||||
do {
|
||||
buffer[pos++] = g_HexChars[number % radix];
|
||||
number /= radix;
|
||||
} while (number > 0);
|
||||
|
||||
while (--pos >= 0) fputc(buffer[pos]);
|
||||
}
|
||||
|
||||
void fprintf_signed(int64_t number, int radix)
|
||||
{
|
||||
if (number < 0) {
|
||||
fputc('-');
|
||||
fprintf_unsigned(-number, radix);
|
||||
} else {
|
||||
fprintf_unsigned(number, radix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void vfprintf(const char* fmt, va_list args)
|
||||
{
|
||||
int state = 0; // normal
|
||||
int length = 0; // default
|
||||
int radix = 10;
|
||||
bool sign = false;
|
||||
bool number = false;
|
||||
|
||||
while (*fmt) {
|
||||
switch (state) {
|
||||
case 0: // normal
|
||||
if (*fmt == '%') state = 1;
|
||||
else fputc(*fmt);
|
||||
break;
|
||||
|
||||
case 1: // length
|
||||
if (*fmt == 'l') { length = 3; state = 4; }
|
||||
else if (*fmt == 'h') { length = 2; state = 4; }
|
||||
else goto spec;
|
||||
break;
|
||||
|
||||
case 4: // spec
|
||||
spec:
|
||||
switch (*fmt) {
|
||||
case 'c': fputc((char)va_arg(args,int)); break;
|
||||
case 's': fputs(va_arg(args,const char*)); break;
|
||||
case 'd':
|
||||
case 'i': sign = true; number = true; radix = 10; break;
|
||||
case 'u': sign = false; number = true; radix = 10; break;
|
||||
case 'x':
|
||||
case 'X': sign = false; number = true; radix = 16; break;
|
||||
case 'p': number = true; sign = false; radix = 16; break;
|
||||
case 'o': sign = false; number = true; radix = 8; break;
|
||||
case '%': fputc('%'); break;
|
||||
}
|
||||
|
||||
if (number) {
|
||||
if (sign) fprintf_signed(va_arg(args,long), radix);
|
||||
else fprintf_unsigned(va_arg(args,unsigned long), radix);
|
||||
}
|
||||
|
||||
state = 0;
|
||||
length = 0;
|
||||
number = false;
|
||||
sign = false;
|
||||
break;
|
||||
}
|
||||
|
||||
fmt++;
|
||||
}
|
||||
}
|
||||
|
||||
void printf(const char* fmt, ...)
|
||||
{
|
||||
uint64_t flags;
|
||||
spinlock_acquire_irqsave(&s_printf_lock, &flags);
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
vfprintf(fmt, args);
|
||||
|
||||
va_end(args);
|
||||
|
||||
spinlock_release_irqrestore(&s_printf_lock, flags);
|
||||
}
|
||||
|
||||
void fprintf(const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vfprintf(fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void printf(const char* fmt, ...);
|
||||
void fputs(const char* str);
|
||||
void fputc(char c);
|
||||
void vfprintf(const char* fmt, va_list args);
|
||||
void fprintf(const char* fmt, ...);
|
||||
void fputs_colored(const char* str, uint32_t color);
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
#include "string.h"
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
const char* strchr(const char* str, char chr)
|
||||
{
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
|
||||
while (*str)
|
||||
{
|
||||
if (*str == chr)
|
||||
return str;
|
||||
|
||||
++str;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* strcpy(char* dst, const char* src)
|
||||
{
|
||||
char* origDst = dst;
|
||||
|
||||
if (dst == NULL)
|
||||
return NULL;
|
||||
|
||||
if (src == NULL)
|
||||
{
|
||||
*dst = '\0';
|
||||
return dst;
|
||||
}
|
||||
|
||||
while (*src)
|
||||
{
|
||||
*dst = *src;
|
||||
++src;
|
||||
++dst;
|
||||
}
|
||||
|
||||
*dst = '\0';
|
||||
return origDst;
|
||||
}
|
||||
|
||||
unsigned strlen(const char* str)
|
||||
{
|
||||
unsigned len = 0;
|
||||
while (*str)
|
||||
{
|
||||
++len;
|
||||
++str;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int strcmp(const char* a, const char* b)
|
||||
{
|
||||
if (a == NULL && b == NULL)
|
||||
return 0;
|
||||
|
||||
if (a == NULL || b == NULL)
|
||||
return -1;
|
||||
|
||||
while (*a && *b && *a == *b)
|
||||
{
|
||||
++a;
|
||||
++b;
|
||||
}
|
||||
return (*a) - (*b);
|
||||
}
|
||||
|
||||
char* strcat(char* dst, const char* src)
|
||||
{
|
||||
char* origDst = dst;
|
||||
|
||||
if (dst == NULL)
|
||||
return NULL;
|
||||
|
||||
if (src == NULL)
|
||||
return dst;
|
||||
|
||||
// move dst pointer to end of existing string
|
||||
while (*dst)
|
||||
{
|
||||
++dst;
|
||||
}
|
||||
|
||||
// copy src into the end
|
||||
while (*src)
|
||||
{
|
||||
*dst = *src;
|
||||
++dst;
|
||||
++src;
|
||||
}
|
||||
|
||||
// null-terminate
|
||||
*dst = '\0';
|
||||
|
||||
return origDst;
|
||||
}
|
||||
|
||||
char* strncpy(char* dst, const char* src, size_t n)
|
||||
{
|
||||
char* origDst = dst;
|
||||
|
||||
if (dst == NULL)
|
||||
return NULL;
|
||||
|
||||
if (src == NULL)
|
||||
{
|
||||
while (n > 0)
|
||||
{
|
||||
*dst = '\0';
|
||||
++dst;
|
||||
--n;
|
||||
}
|
||||
return origDst;
|
||||
}
|
||||
|
||||
while (n > 0 && *src)
|
||||
{
|
||||
*dst = *src;
|
||||
++dst;
|
||||
++src;
|
||||
--n;
|
||||
}
|
||||
|
||||
// pad remaining space with '\0'
|
||||
while (n > 0)
|
||||
{
|
||||
*dst = '\0';
|
||||
++dst;
|
||||
--n;
|
||||
}
|
||||
|
||||
return origDst;
|
||||
}
|
||||
|
||||
int strncmp(const char* a, const char* b, size_t n)
|
||||
{
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
if (a == NULL && b == NULL)
|
||||
return 0;
|
||||
|
||||
if (a == NULL)
|
||||
return -1;
|
||||
|
||||
if (b == NULL)
|
||||
return 1;
|
||||
|
||||
while (n > 0 && *a && *b && (*a == *b))
|
||||
{
|
||||
++a;
|
||||
++b;
|
||||
--n;
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
return ((unsigned char)*a) - ((unsigned char)*b);
|
||||
}
|
||||
|
||||
wchar_t* utf16_to_codepoint(wchar_t* string, int* codepoint)
|
||||
{
|
||||
int c1 = *string;
|
||||
++string;
|
||||
|
||||
if (c1 >= 0xd800 && c1 < 0xdc00) {
|
||||
int c2 = *string;
|
||||
++string;
|
||||
*codepoint = ((c1 & 0x3ff) << 10) + (c2 & 0x3ff) + 0x10000;
|
||||
}
|
||||
*codepoint = c1;
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
/* Encoding
|
||||
The following byte sequences are used to represent a
|
||||
character. The sequence to be used depends on the UCS code
|
||||
number of the character:
|
||||
|
||||
0x00000000 - 0x0000007F:
|
||||
0xxxxxxx
|
||||
|
||||
0x00000080 - 0x000007FF:
|
||||
110xxxxx 10xxxxxx
|
||||
|
||||
0x00000800 - 0x0000FFFF:
|
||||
1110xxxx 10xxxxxx 10xxxxxx
|
||||
|
||||
0x00010000 - 0x001FFFFF:
|
||||
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
|
||||
[... removed obsolete five and six byte forms ...]
|
||||
|
||||
The xxx bit positions are filled with the bits of the
|
||||
character code number in binary representation. Only the
|
||||
shortest possible multibyte sequence which can represent the
|
||||
code number of the character can be used.
|
||||
|
||||
The UCS code values 0xd800–0xdfff (UTF-16 surrogates) as well
|
||||
as 0xfffe and 0xffff (UCS noncharacters) should not appear in
|
||||
conforming UTF-8 streams.
|
||||
*/
|
||||
|
||||
char* codepoint_to_utf8(int codepoint, char* stringOutput)
|
||||
{
|
||||
if (codepoint <= 0x7F) {
|
||||
*stringOutput = (char)codepoint;
|
||||
}
|
||||
else if (codepoint <= 0x7FF) {
|
||||
*stringOutput++ = 0xC0 | ((codepoint >> 6) & 0x1F);
|
||||
*stringOutput++ = 0x80 | (codepoint & 0x3F);
|
||||
}
|
||||
else if (codepoint <= 0xFFFF) {
|
||||
*stringOutput++ = 0xE0 | ((codepoint >> 12) & 0xF);
|
||||
*stringOutput++ = 0x80 | ((codepoint >> 6) & 0x3F);
|
||||
*stringOutput++ = 0x80 | (codepoint & 0x3F);
|
||||
}
|
||||
else if (codepoint <= 0x1FFFFF) {
|
||||
*stringOutput++ = 0xF0 | ((codepoint >> 18) & 0x7);
|
||||
*stringOutput++ = 0x80 | ((codepoint >> 12) & 0x3F);
|
||||
*stringOutput++ = 0x80 | ((codepoint >> 6) & 0x3F);
|
||||
*stringOutput++ = 0x80 | (codepoint & 0x3F);
|
||||
}
|
||||
return stringOutput;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
|
||||
const char* strchr(const char* str, char chr);
|
||||
char* strcpy(char* dst, const char* src);
|
||||
unsigned strlen(const char* str);
|
||||
int strcmp(const char* a, const char* b);
|
||||
char* strncpy(char* dst, const char* src, size_t n);
|
||||
char* strcat(char* dst, const char* src);
|
||||
int strncmp(const char* a, const char* b, size_t n);
|
||||
wchar_t* utf16_to_codepoint(wchar_t* string, int* codepoint);
|
||||
char* codepoint_to_utf8(int codepoint, char* stringOutput);
|
||||
@@ -0,0 +1,76 @@
|
||||
#include <stdint.h>
|
||||
#include "stdio.h"
|
||||
#include "fs/vfs.h"
|
||||
|
||||
#define MSR_EFER 0xC0000080
|
||||
#define MSR_STAR 0xC0000081
|
||||
#define MSR_LSTAR 0xC0000082
|
||||
#define MSR_SFMASK 0xC0000084
|
||||
|
||||
#define EFER_SCE (1 << 0)
|
||||
|
||||
static inline void wrmsr(uint32_t msr, uint64_t value)
|
||||
{
|
||||
uint32_t lo = value & 0xFFFFFFFF;
|
||||
uint32_t hi = value >> 32;
|
||||
|
||||
asm volatile("wrmsr"
|
||||
:
|
||||
: "c"(msr), "a"(lo), "d"(hi));
|
||||
}
|
||||
|
||||
static inline uint64_t rdmsr(uint32_t msr)
|
||||
{
|
||||
uint32_t lo, hi;
|
||||
asm volatile("rdmsr"
|
||||
: "=a"(lo), "=d"(hi)
|
||||
: "c"(msr));
|
||||
return ((uint64_t)hi << 32) | lo;
|
||||
}
|
||||
|
||||
void syscall_handler(uint64_t rax, // syscall num
|
||||
uint64_t rdi, // arg1
|
||||
uint64_t rsi, // arg2
|
||||
uint64_t rdx, // arg3
|
||||
uint64_t r10, // arg4
|
||||
uint64_t r8, // arg5
|
||||
uint64_t r9) // arg6
|
||||
{
|
||||
switch (rax)
|
||||
{
|
||||
case 1: // write (int fd, const void *buf, size_t count);
|
||||
int c = (char)rdi;
|
||||
printf("%c", c);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// exit
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void syscall_init(void)
|
||||
{
|
||||
extern void syscall_entry(void);
|
||||
|
||||
uint64_t kernel_cs = 0x08;
|
||||
uint64_t user_cs = 0x1B;
|
||||
|
||||
uint64_t star =
|
||||
((uint64_t)kernel_cs << 32) |
|
||||
((uint64_t)user_cs << 48);
|
||||
|
||||
wrmsr(MSR_STAR, star);
|
||||
|
||||
wrmsr(MSR_LSTAR, (uint64_t)syscall_entry);
|
||||
|
||||
uint64_t efer = rdmsr(MSR_EFER);
|
||||
efer |= (1 << 0); // SYSCALL/SYSRET enable
|
||||
wrmsr(MSR_EFER, efer);
|
||||
|
||||
// disable interrupts on syscall entry
|
||||
wrmsr(MSR_SFMASK, (1 << 9));
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void syscall_init(void);
|
||||
@@ -0,0 +1,30 @@
|
||||
.global syscall_entry
|
||||
|
||||
syscall_entry:
|
||||
swapgs
|
||||
|
||||
push %rcx
|
||||
push %r11
|
||||
|
||||
# Save original args before we clobber them
|
||||
push %rdi # orig rdi (arg1)
|
||||
push %rsi # orig rsi (arg2)
|
||||
push %rdx # orig rdx (arg3)
|
||||
|
||||
# Handle r8/r9 before r8 gets clobbered
|
||||
mov %r8, %r9 # r9 = orig r8 (6th param)
|
||||
mov %r10, %r8 # r8 = orig r10 (5th param)
|
||||
|
||||
# Pop in reverse order to place into correct SysV registers
|
||||
pop %rcx # rcx = orig rdx (4th param)
|
||||
pop %rdx # rdx = orig rsi (3rd param)
|
||||
pop %rsi # rsi = orig rdi (2nd param)
|
||||
mov %rax, %rdi # rdi = rax (1st param = syscall number)
|
||||
|
||||
call syscall_handler
|
||||
|
||||
pop %r11
|
||||
pop %rcx
|
||||
|
||||
swapgs
|
||||
sysretq
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define SIZE(array) (sizeof(array) / sizeof(array[0]))
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#define FLAG_SET(x, flag) x |= (flag)
|
||||
#define FLAG_UNSET(x, flag) x &= ~(flag)
|
||||
@@ -0,0 +1,457 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
unsigned char zap_light16_psf[] = {
|
||||
0x36, 0x04, 0x02, 0x10, 0x00, 0x00, 0x00, 0x3e, 0x63, 0x5d, 0x7d, 0x7b,
|
||||
0x77, 0x77, 0x7f, 0x77, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7e, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x22, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x7f, 0x04, 0x08, 0x10, 0x7f, 0x20,
|
||||
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x20, 0x40,
|
||||
0x20, 0x10, 0x08, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00, 0x3e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c,
|
||||
0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
|
||||
0x10, 0x11, 0x12, 0x04, 0x08, 0x12, 0x26, 0x4a, 0x0f, 0x02, 0x02, 0x00,
|
||||
0x00, 0x00, 0x10, 0x30, 0x10, 0x11, 0x12, 0x04, 0x08, 0x10, 0x26, 0x49,
|
||||
0x02, 0x04, 0x0f, 0x00, 0x00, 0x00, 0x70, 0x08, 0x30, 0x09, 0x72, 0x04,
|
||||
0x08, 0x12, 0x26, 0x4a, 0x0f, 0x02, 0x02, 0x00, 0x00, 0x00, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
|
||||
0x00, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x30, 0x00, 0x00, 0x07, 0x08,
|
||||
0x08, 0x08, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x70, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x08, 0x08,
|
||||
0x08, 0x08, 0x3e, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
|
||||
0xa4, 0xa4, 0x48, 0x10, 0x10, 0x2a, 0x55, 0x55, 0x8a, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xf1, 0x5b, 0x55, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x49, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x08, 0x10, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x04, 0x08, 0x10, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x24, 0x12, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x24,
|
||||
0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24,
|
||||
0x24, 0x24, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x24, 0x24, 0x24, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x00,
|
||||
0x42, 0x3c, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x40, 0x4e, 0x42, 0x42, 0x42,
|
||||
0x3c, 0x00, 0x00, 0x00, 0x00, 0x42, 0x3c, 0x00, 0x00, 0x3a, 0x46, 0x42,
|
||||
0x42, 0x42, 0x46, 0x3a, 0x02, 0x02, 0x42, 0x3c, 0x08, 0x08, 0x00, 0x3e,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x30,
|
||||
0x0c, 0x02, 0x42, 0x42, 0x3c, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3c, 0x42, 0x40, 0x30, 0x0c, 0x02, 0x42, 0x3c, 0x08, 0x08, 0x30,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x24,
|
||||
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x24, 0x24, 0x24, 0x7e, 0x24, 0x24, 0x7e, 0x24, 0x24,
|
||||
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x49, 0x48, 0x48,
|
||||
0x3e, 0x09, 0x09, 0x49, 0x3e, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x31,
|
||||
0x4a, 0x4a, 0x34, 0x08, 0x08, 0x16, 0x29, 0x29, 0x46, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x24, 0x18, 0x28, 0x45, 0x42, 0x46,
|
||||
0x39, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08,
|
||||
0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x00, 0x00,
|
||||
0x00, 0x00, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10,
|
||||
0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x49, 0x2a,
|
||||
0x1c, 0x2a, 0x49, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
|
||||
0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20,
|
||||
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x4a,
|
||||
0x52, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
|
||||
0x18, 0x28, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
|
||||
0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x02, 0x1c,
|
||||
0x02, 0x02, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
|
||||
0x0c, 0x14, 0x24, 0x44, 0x44, 0x7e, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x02, 0x02, 0x02, 0x42,
|
||||
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x40, 0x40, 0x7c,
|
||||
0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e,
|
||||
0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x42, 0x42, 0x42, 0x42,
|
||||
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42,
|
||||
0x3e, 0x02, 0x02, 0x04, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x08,
|
||||
0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20,
|
||||
0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10,
|
||||
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x02, 0x04,
|
||||
0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
|
||||
0x22, 0x4a, 0x56, 0x52, 0x52, 0x52, 0x4e, 0x20, 0x1e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42,
|
||||
0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c,
|
||||
0x42, 0x42, 0x42, 0x42, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
|
||||
0x42, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x78, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44,
|
||||
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c,
|
||||
0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e,
|
||||
0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x40, 0x4e, 0x42, 0x42, 0x42,
|
||||
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x7e,
|
||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x44,
|
||||
0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x44, 0x48, 0x50, 0x60,
|
||||
0x60, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
|
||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x41, 0x63, 0x63, 0x55, 0x55, 0x49, 0x49, 0x41, 0x41,
|
||||
0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x62, 0x62, 0x52, 0x52,
|
||||
0x4a, 0x4a, 0x46, 0x46, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
|
||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x40,
|
||||
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42,
|
||||
0x42, 0x42, 0x5a, 0x66, 0x3c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
|
||||
0x42, 0x42, 0x42, 0x7c, 0x48, 0x44, 0x44, 0x42, 0x42, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x30, 0x0c, 0x02, 0x42, 0x42,
|
||||
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
|
||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x22, 0x22, 0x22, 0x14, 0x14, 0x08,
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x49, 0x49,
|
||||
0x55, 0x55, 0x63, 0x63, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
|
||||
0x42, 0x24, 0x24, 0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x41, 0x41, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x04, 0x08,
|
||||
0x10, 0x20, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x10,
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1c, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02,
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22,
|
||||
0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7f, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x40, 0x40, 0x40, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x62,
|
||||
0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40,
|
||||
0x40, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02,
|
||||
0x02, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42,
|
||||
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x10, 0x10, 0x7c, 0x10,
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x02, 0x42, 0x3c,
|
||||
0x00, 0x00, 0x40, 0x40, 0x40, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||
0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x18, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04,
|
||||
0x00, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x38,
|
||||
0x00, 0x00, 0x40, 0x40, 0x40, 0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44,
|
||||
0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x76, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||
0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42,
|
||||
0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x62, 0x5c, 0x40, 0x40, 0x40,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x46,
|
||||
0x3a, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x62, 0x40,
|
||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3c, 0x42, 0x40, 0x30, 0x0c, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||
0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42,
|
||||
0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x41, 0x41, 0x41, 0x22, 0x22, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x49, 0x49, 0x49, 0x49, 0x49,
|
||||
0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x24,
|
||||
0x18, 0x18, 0x24, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x02, 0x42, 0x3c,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
|
||||
0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x08, 0x08, 0x08, 0x08, 0x30,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
|
||||
0x00, 0x00, 0x30, 0x08, 0x08, 0x08, 0x08, 0x06, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x30, 0x00, 0x00, 0x00, 0x31, 0x49, 0x46, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x30, 0x0c, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42,
|
||||
0x42, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42,
|
||||
0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x18, 0x24, 0x00, 0x18,
|
||||
0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00,
|
||||
0x32, 0x4c, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42,
|
||||
0x42, 0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x18, 0x24, 0x24, 0x42, 0x42,
|
||||
0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x18,
|
||||
0x24, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x1f, 0x28, 0x48, 0x48, 0x7e, 0x48, 0x48, 0x48, 0x48,
|
||||
0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x40,
|
||||
0x40, 0x40, 0x42, 0x42, 0x3c, 0x08, 0x08, 0x30, 0x30, 0x0c, 0x00, 0x7e,
|
||||
0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00,
|
||||
0x0c, 0x30, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40,
|
||||
0x7e, 0x00, 0x00, 0x00, 0x18, 0x24, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c,
|
||||
0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x7e,
|
||||
0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00,
|
||||
0x30, 0x0c, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x3e, 0x00, 0x00, 0x00, 0x06, 0x18, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x18, 0x24, 0x00, 0x3e,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00,
|
||||
0x22, 0x22, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x44, 0x42, 0x42, 0xf2,
|
||||
0x42, 0x42, 0x42, 0x44, 0x78, 0x00, 0x00, 0x00, 0x32, 0x4c, 0x00, 0x42,
|
||||
0x62, 0x62, 0x52, 0x52, 0x4a, 0x4a, 0x46, 0x46, 0x42, 0x00, 0x00, 0x00,
|
||||
0x30, 0x0c, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||
0x3c, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42,
|
||||
0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x24, 0x00, 0x3c,
|
||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x32, 0x4c, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||
0x3c, 0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42,
|
||||
0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0x3a, 0x44, 0x46, 0x4a, 0x4a, 0x52, 0x52, 0x62, 0x22,
|
||||
0x5c, 0x40, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||
0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x42,
|
||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x18, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||
0x3c, 0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||
0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x06, 0x18, 0x00, 0x41,
|
||||
0x41, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x40,
|
||||
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x4c, 0x50, 0x50,
|
||||
0x4c, 0x42, 0x42, 0x52, 0x4c, 0x00, 0x00, 0x00, 0xaa, 0x55, 0xaa, 0x55,
|
||||
0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55,
|
||||
0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x49, 0x48,
|
||||
0x48, 0x48, 0x48, 0x49, 0x3e, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x1c,
|
||||
0x20, 0x20, 0x20, 0x78, 0x20, 0x20, 0x20, 0x22, 0x7e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0e, 0x11, 0x20, 0x7e, 0x20, 0x7c, 0x20, 0x11,
|
||||
0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x22, 0x14, 0x08,
|
||||
0x3e, 0x08, 0x3e, 0x08, 0x08, 0x00, 0x00, 0x00, 0x24, 0x18, 0x00, 0x3c,
|
||||
0x42, 0x42, 0x40, 0x30, 0x0c, 0x02, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1c, 0x22, 0x20, 0x18, 0x24, 0x22, 0x22, 0x12, 0x0c, 0x02,
|
||||
0x22, 0x1c, 0x00, 0x00, 0x00, 0x24, 0x18, 0x00, 0x00, 0x3c, 0x42, 0x40,
|
||||
0x30, 0x0c, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
|
||||
0x42, 0x99, 0xa5, 0xa1, 0xa1, 0xa5, 0x99, 0x42, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x04, 0x3c, 0x44, 0x3c, 0x00, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x24,
|
||||
0x48, 0x24, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x22,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0xb9, 0xa5, 0xa5,
|
||||
0xb9, 0xa9, 0xa5, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0x08,
|
||||
0x08, 0x08, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44,
|
||||
0x04, 0x18, 0x20, 0x40, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x44, 0x04, 0x38, 0x04, 0x44, 0x38, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x00, 0x7e, 0x02, 0x02, 0x04, 0x08,
|
||||
0x10, 0x20, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x66, 0x5a, 0x40, 0x40, 0x40,
|
||||
0x00, 0x00, 0x00, 0x3e, 0x7a, 0x7a, 0x7a, 0x7a, 0x3a, 0x0a, 0x0a, 0x0a,
|
||||
0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x00,
|
||||
0x00, 0x7e, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x10, 0x30, 0x50, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
|
||||
0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x48, 0x24, 0x12, 0x24, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x37, 0x48, 0x48, 0x48, 0x4e, 0x48, 0x48, 0x48, 0x48,
|
||||
0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x49, 0x49,
|
||||
0x4f, 0x48, 0x48, 0x49, 0x36, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x41,
|
||||
0x41, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x10, 0x10, 0x20, 0x40, 0x42, 0x42,
|
||||
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22,
|
||||
0x88, 0x22, 0x88, 0x22, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
|
||||
0x14, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
|
||||
0x10, 0x17, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xfc, 0x04, 0xf4, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x17, 0x10, 0x1f, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xf4,
|
||||
0x04, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x14, 0x14,
|
||||
0x14, 0x14, 0x14, 0x17, 0x10, 0x17, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xf4, 0x04, 0xf4, 0x14, 0x14,
|
||||
0x14, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0x00, 0xf7, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
|
||||
0x14, 0x14, 0x14, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xf7, 0x00, 0xf7, 0x14, 0x14,
|
||||
0x14, 0x14, 0x14, 0x14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x08, 0x1c, 0x2a, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x2a, 0x1c, 0x08,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20,
|
||||
0x7f, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x08, 0x04, 0xfe, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x30, 0x0c, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46,
|
||||
0x3a, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x3c, 0x42, 0x02,
|
||||
0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x00,
|
||||
0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00,
|
||||
0x00, 0x32, 0x4c, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46,
|
||||
0x3a, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x02,
|
||||
0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x18,
|
||||
0x00, 0x3c, 0x42, 0x02, 0x3e, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x49, 0x09, 0x3f, 0x48, 0x48, 0x49,
|
||||
0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40,
|
||||
0x40, 0x40, 0x40, 0x42, 0x3c, 0x08, 0x08, 0x30, 0x00, 0x30, 0x0c, 0x00,
|
||||
0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0c, 0x30, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42,
|
||||
0x3c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42,
|
||||
0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x00,
|
||||
0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x30, 0x0c, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x3e, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x18, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x00,
|
||||
0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x18, 0x64, 0x02, 0x3a, 0x46,
|
||||
0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x32, 0x4c, 0x00,
|
||||
0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00,
|
||||
0x00, 0x30, 0x0c, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||
0x3c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x3c, 0x42, 0x42,
|
||||
0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x00,
|
||||
0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x32, 0x4c, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
||||
0x3c, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42,
|
||||
0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x10, 0x10, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x3c, 0x46, 0x4a, 0x4a, 0x52, 0x52, 0x62,
|
||||
0x3c, 0x40, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x42, 0x42, 0x42,
|
||||
0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00,
|
||||
0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46,
|
||||
0x3a, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42,
|
||||
0x42, 0x42, 0x42, 0x46, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00,
|
||||
0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x02, 0x42, 0x3c,
|
||||
0x00, 0x00, 0x40, 0x40, 0x40, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x62,
|
||||
0x5c, 0x40, 0x40, 0x40, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42,
|
||||
0x42, 0x42, 0x46, 0x3a, 0x02, 0x02, 0x42, 0x3c, 0xfd, 0xff, 0xff, 0xff,
|
||||
0xc0, 0x03, 0xff, 0xff, 0x60, 0x22, 0xff, 0xff, 0x64, 0x22, 0xff, 0xff,
|
||||
0x65, 0x22, 0xff, 0xff, 0xa0, 0x25, 0xac, 0x25, 0xae, 0x25, 0xfc, 0x25,
|
||||
0xfe, 0x25, 0x1b, 0x2b, 0x0e, 0x22, 0xff, 0xff, 0xc6, 0x25, 0x66, 0x26,
|
||||
0x25, 0x2b, 0x27, 0x2b, 0xff, 0xff, 0xbc, 0x00, 0xff, 0xff, 0xbd, 0x00,
|
||||
0xff, 0xff, 0xbe, 0x00, 0xff, 0xff, 0xa6, 0x00, 0xff, 0xff, 0xa8, 0x00,
|
||||
0xff, 0xff, 0xb8, 0x00, 0xff, 0xff, 0x92, 0x01, 0xff, 0xff, 0x20, 0x20,
|
||||
0xff, 0xff, 0x21, 0x20, 0xff, 0xff, 0x30, 0x20, 0xff, 0xff, 0x22, 0x21,
|
||||
0xff, 0xff, 0x26, 0x20, 0xff, 0xff, 0x39, 0x20, 0xff, 0xff, 0x3a, 0x20,
|
||||
0xff, 0xff, 0x1c, 0x20, 0x1f, 0x20, 0x36, 0x20, 0xff, 0xff, 0x1d, 0x20,
|
||||
0xba, 0x02, 0xdd, 0x02, 0xee, 0x02, 0x33, 0x20, 0xff, 0xff, 0x1e, 0x20,
|
||||
0xff, 0xff, 0x42, 0x2e, 0xff, 0xff, 0x41, 0x2e, 0xce, 0x02, 0xff, 0xff,
|
||||
0x1e, 0x01, 0xff, 0xff, 0x1f, 0x01, 0xff, 0xff, 0x30, 0x01, 0xff, 0xff,
|
||||
0x31, 0x01, 0xff, 0xff, 0x5e, 0x01, 0xff, 0xff, 0x5f, 0x01, 0xff, 0xff,
|
||||
0x20, 0x00, 0xa0, 0x00, 0x00, 0x20, 0x01, 0x20, 0x02, 0x20, 0x03, 0x20,
|
||||
0x04, 0x20, 0x05, 0x20, 0x06, 0x20, 0x07, 0x20, 0x08, 0x20, 0x09, 0x20,
|
||||
0x0a, 0x20, 0x2f, 0x20, 0x5f, 0x20, 0xff, 0xff, 0x21, 0x00, 0xff, 0xff,
|
||||
0x22, 0x00, 0xff, 0xff, 0x23, 0x00, 0xff, 0xff, 0x24, 0x00, 0xff, 0xff,
|
||||
0x25, 0x00, 0xff, 0xff, 0x26, 0x00, 0xff, 0xff, 0x27, 0x00, 0xb4, 0x00,
|
||||
0xb9, 0x02, 0xbc, 0x02, 0xca, 0x02, 0x19, 0x20, 0x32, 0x20, 0xff, 0xff,
|
||||
0x28, 0x00, 0xff, 0xff, 0x29, 0x00, 0xff, 0xff, 0x2a, 0x00, 0x4e, 0x20,
|
||||
0x17, 0x22, 0xff, 0xff, 0x2b, 0x00, 0xff, 0xff, 0x2c, 0x00, 0xcf, 0x02,
|
||||
0x1a, 0x20, 0xff, 0xff, 0x2d, 0x00, 0xad, 0x00, 0x10, 0x20, 0x11, 0x20,
|
||||
0x12, 0x20, 0x13, 0x20, 0x43, 0x20, 0x12, 0x22, 0xff, 0xff, 0x2e, 0x00,
|
||||
0x24, 0x20, 0xff, 0xff, 0x2f, 0x00, 0x44, 0x20, 0x15, 0x22, 0xff, 0xff,
|
||||
0x30, 0x00, 0xff, 0xff, 0x31, 0x00, 0xff, 0xff, 0x32, 0x00, 0xff, 0xff,
|
||||
0x33, 0x00, 0xff, 0xff, 0x34, 0x00, 0xff, 0xff, 0x35, 0x00, 0xff, 0xff,
|
||||
0x36, 0x00, 0xff, 0xff, 0x37, 0x00, 0xff, 0xff, 0x38, 0x00, 0xff, 0xff,
|
||||
0x39, 0x00, 0xff, 0xff, 0x3a, 0x00, 0x36, 0x22, 0xff, 0xff, 0x3b, 0x00,
|
||||
0xff, 0xff, 0x3c, 0x00, 0xff, 0xff, 0x3d, 0x00, 0x40, 0x2e, 0xff, 0xff,
|
||||
0x3e, 0x00, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0x40, 0x00, 0xff, 0xff,
|
||||
0x41, 0x00, 0xff, 0xff, 0x42, 0x00, 0xff, 0xff, 0x43, 0x00, 0xff, 0xff,
|
||||
0x44, 0x00, 0xff, 0xff, 0x45, 0x00, 0xff, 0xff, 0x46, 0x00, 0xff, 0xff,
|
||||
0x47, 0x00, 0xff, 0xff, 0x48, 0x00, 0xff, 0xff, 0x49, 0x00, 0xff, 0xff,
|
||||
0x4a, 0x00, 0xff, 0xff, 0x4b, 0x00, 0x2a, 0x21, 0xff, 0xff, 0x4c, 0x00,
|
||||
0xff, 0xff, 0x4d, 0x00, 0xff, 0xff, 0x4e, 0x00, 0xff, 0xff, 0x4f, 0x00,
|
||||
0xff, 0xff, 0x50, 0x00, 0xff, 0xff, 0x51, 0x00, 0xff, 0xff, 0x52, 0x00,
|
||||
0xff, 0xff, 0x53, 0x00, 0xff, 0xff, 0x54, 0x00, 0xff, 0xff, 0x55, 0x00,
|
||||
0xff, 0xff, 0x56, 0x00, 0xff, 0xff, 0x57, 0x00, 0xff, 0xff, 0x58, 0x00,
|
||||
0xff, 0xff, 0x59, 0x00, 0xff, 0xff, 0x5a, 0x00, 0xff, 0xff, 0x5b, 0x00,
|
||||
0xff, 0xff, 0x5c, 0x00, 0xf5, 0x29, 0xff, 0xff, 0x5d, 0x00, 0xff, 0xff,
|
||||
0x5e, 0x00, 0xc4, 0x02, 0xc6, 0x02, 0x03, 0x23, 0xff, 0xff, 0x5f, 0x00,
|
||||
0xff, 0xff, 0x60, 0x00, 0xbb, 0x02, 0xbd, 0x02, 0xcb, 0x02, 0x18, 0x20,
|
||||
0x1b, 0x20, 0x35, 0x20, 0xff, 0xff, 0x61, 0x00, 0xff, 0xff, 0x62, 0x00,
|
||||
0xff, 0xff, 0x63, 0x00, 0xff, 0xff, 0x64, 0x00, 0xff, 0xff, 0x65, 0x00,
|
||||
0xff, 0xff, 0x66, 0x00, 0xff, 0xff, 0x67, 0x00, 0xff, 0xff, 0x68, 0x00,
|
||||
0xff, 0xff, 0x69, 0x00, 0xff, 0xff, 0x6a, 0x00, 0xff, 0xff, 0x6b, 0x00,
|
||||
0xff, 0xff, 0x6c, 0x00, 0xff, 0xff, 0x6d, 0x00, 0xff, 0xff, 0x6e, 0x00,
|
||||
0xff, 0xff, 0x6f, 0x00, 0xff, 0xff, 0x70, 0x00, 0xff, 0xff, 0x71, 0x00,
|
||||
0xff, 0xff, 0x72, 0x00, 0xff, 0xff, 0x73, 0x00, 0xff, 0xff, 0x74, 0x00,
|
||||
0xff, 0xff, 0x75, 0x00, 0xff, 0xff, 0x76, 0x00, 0xff, 0xff, 0x77, 0x00,
|
||||
0xff, 0xff, 0x78, 0x00, 0xff, 0xff, 0x79, 0x00, 0xff, 0xff, 0x7a, 0x00,
|
||||
0xff, 0xff, 0x7b, 0x00, 0xff, 0xff, 0x7c, 0x00, 0x23, 0x22, 0xff, 0xff,
|
||||
0x7d, 0x00, 0xff, 0xff, 0x7e, 0x00, 0xdc, 0x02, 0xff, 0xff, 0x22, 0x20,
|
||||
0x19, 0x22, 0xcf, 0x25, 0xff, 0xff, 0xc0, 0x00, 0xff, 0xff, 0xc1, 0x00,
|
||||
0xff, 0xff, 0xc2, 0x00, 0xff, 0xff, 0xc3, 0x00, 0xff, 0xff, 0xc4, 0x00,
|
||||
0xff, 0xff, 0xc5, 0x00, 0x2b, 0x21, 0xff, 0xff, 0xc6, 0x00, 0xff, 0xff,
|
||||
0xc7, 0x00, 0xff, 0xff, 0xc8, 0x00, 0xff, 0xff, 0xc9, 0x00, 0xff, 0xff,
|
||||
0xca, 0x00, 0xff, 0xff, 0xcb, 0x00, 0xff, 0xff, 0xcc, 0x00, 0xff, 0xff,
|
||||
0xcd, 0x00, 0xff, 0xff, 0xce, 0x00, 0xff, 0xff, 0xcf, 0x00, 0xff, 0xff,
|
||||
0xd0, 0x00, 0x10, 0x01, 0xff, 0xff, 0xd1, 0x00, 0xff, 0xff, 0xd2, 0x00,
|
||||
0xff, 0xff, 0xd3, 0x00, 0xff, 0xff, 0xd4, 0x00, 0xff, 0xff, 0xd5, 0x00,
|
||||
0xff, 0xff, 0xd6, 0x00, 0xff, 0xff, 0xd7, 0x00, 0xff, 0xff, 0xd8, 0x00,
|
||||
0xff, 0xff, 0xd9, 0x00, 0xff, 0xff, 0xda, 0x00, 0xff, 0xff, 0xdb, 0x00,
|
||||
0xff, 0xff, 0xdc, 0x00, 0xff, 0xff, 0xdd, 0x00, 0xff, 0xff, 0xde, 0x00,
|
||||
0xff, 0xff, 0xdf, 0x00, 0xff, 0xff, 0x92, 0x25, 0xff, 0xff, 0xa1, 0x00,
|
||||
0xff, 0xff, 0xa2, 0x00, 0xff, 0xff, 0xa3, 0x00, 0xff, 0xff, 0xac, 0x20,
|
||||
0xff, 0xff, 0xa5, 0x00, 0xff, 0xff, 0x60, 0x01, 0xff, 0xff, 0xa7, 0x00,
|
||||
0xff, 0xff, 0x61, 0x01, 0xff, 0xff, 0xa9, 0x00, 0xff, 0xff, 0xaa, 0x00,
|
||||
0xff, 0xff, 0xab, 0x00, 0xff, 0xff, 0xac, 0x00, 0xff, 0xff, 0xa4, 0x00,
|
||||
0xff, 0xff, 0xae, 0x00, 0xff, 0xff, 0xaf, 0x00, 0xc9, 0x02, 0xff, 0xff,
|
||||
0xb0, 0x00, 0xda, 0x02, 0xff, 0xff, 0xb1, 0x00, 0xff, 0xff, 0xb2, 0x00,
|
||||
0xff, 0xff, 0xb3, 0x00, 0xff, 0xff, 0x7d, 0x01, 0xff, 0xff, 0xb5, 0x00,
|
||||
0xbc, 0x03, 0xff, 0xff, 0xb6, 0x00, 0xff, 0xff, 0xb7, 0x00, 0x27, 0x20,
|
||||
0xc5, 0x22, 0x31, 0x2e, 0xff, 0xff, 0x7e, 0x01, 0xff, 0xff, 0xb9, 0x00,
|
||||
0xff, 0xff, 0xba, 0x00, 0xff, 0xff, 0xbb, 0x00, 0xff, 0xff, 0x52, 0x01,
|
||||
0xff, 0xff, 0x53, 0x01, 0xff, 0xff, 0x78, 0x01, 0xff, 0xff, 0xbf, 0x00,
|
||||
0xff, 0xff, 0x00, 0x25, 0x14, 0x20, 0x15, 0x20, 0xaf, 0x23, 0xff, 0xff,
|
||||
0x02, 0x25, 0xff, 0xff, 0x0c, 0x25, 0x6d, 0x25, 0xff, 0xff, 0x10, 0x25,
|
||||
0x6e, 0x25, 0xff, 0xff, 0x14, 0x25, 0x70, 0x25, 0xff, 0xff, 0x18, 0x25,
|
||||
0x6f, 0x25, 0xff, 0xff, 0x1c, 0x25, 0xff, 0xff, 0x24, 0x25, 0xff, 0xff,
|
||||
0x2c, 0x25, 0xff, 0xff, 0x34, 0x25, 0xff, 0xff, 0x3c, 0x25, 0xff, 0xff,
|
||||
0x91, 0x25, 0xff, 0xff, 0xba, 0x23, 0x3e, 0x20, 0xff, 0xff, 0xbb, 0x23,
|
||||
0xff, 0xff, 0xbc, 0x23, 0xff, 0xff, 0xbd, 0x23, 0xff, 0xff, 0x50, 0x25,
|
||||
0x01, 0x25, 0xff, 0xff, 0x51, 0x25, 0x03, 0x25, 0xff, 0xff, 0x54, 0x25,
|
||||
0x0f, 0x25, 0xff, 0xff, 0x57, 0x25, 0x13, 0x25, 0xff, 0xff, 0x5a, 0x25,
|
||||
0x17, 0x25, 0xff, 0xff, 0x5d, 0x25, 0x1b, 0x25, 0xff, 0xff, 0x60, 0x25,
|
||||
0x23, 0x25, 0xff, 0xff, 0x63, 0x25, 0x2b, 0x25, 0xff, 0xff, 0x66, 0x25,
|
||||
0x33, 0x25, 0xff, 0xff, 0x69, 0x25, 0x3b, 0x25, 0xff, 0xff, 0x6c, 0x25,
|
||||
0x4b, 0x25, 0xff, 0xff, 0x88, 0x25, 0xff, 0xff, 0x91, 0x21, 0xff, 0xff,
|
||||
0x93, 0x21, 0xff, 0xff, 0x90, 0x21, 0xff, 0xff, 0x92, 0x21, 0xff, 0xff,
|
||||
0xe0, 0x00, 0xff, 0xff, 0xe1, 0x00, 0xff, 0xff, 0xe2, 0x00, 0xff, 0xff,
|
||||
0xe3, 0x00, 0xff, 0xff, 0xe4, 0x00, 0xff, 0xff, 0xe5, 0x00, 0xff, 0xff,
|
||||
0xe6, 0x00, 0xff, 0xff, 0xe7, 0x00, 0xff, 0xff, 0xe8, 0x00, 0xff, 0xff,
|
||||
0xe9, 0x00, 0xff, 0xff, 0xea, 0x00, 0xff, 0xff, 0xeb, 0x00, 0xff, 0xff,
|
||||
0xec, 0x00, 0xff, 0xff, 0xed, 0x00, 0xff, 0xff, 0xee, 0x00, 0xff, 0xff,
|
||||
0xef, 0x00, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xf1, 0x00, 0xff, 0xff,
|
||||
0xf2, 0x00, 0xff, 0xff, 0xf3, 0x00, 0xff, 0xff, 0xf4, 0x00, 0xff, 0xff,
|
||||
0xf5, 0x00, 0xff, 0xff, 0xf6, 0x00, 0xff, 0xff, 0xf7, 0x00, 0xff, 0xff,
|
||||
0xf8, 0x00, 0xff, 0xff, 0xf9, 0x00, 0xff, 0xff, 0xfa, 0x00, 0xff, 0xff,
|
||||
0xfb, 0x00, 0xff, 0xff, 0xfc, 0x00, 0xff, 0xff, 0xfd, 0x00, 0xff, 0xff,
|
||||
0xfe, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff
|
||||
};
|
||||
unsigned int zap_light16_psf_len = 5312;
|
||||
|
||||
typedef struct {
|
||||
uint8_t magic[2]; // 0x36, 0x04
|
||||
uint8_t mode;
|
||||
uint8_t charsize; // bytes per glyph
|
||||
} PSF1_Header;
|
||||
|
||||
@@ -0,0 +1,342 @@
|
||||
#include <stdint.h>
|
||||
#include "font.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "render.h"
|
||||
#include "mm/memory.h"
|
||||
|
||||
uint32_t *fb;
|
||||
uint32_t fb_width;
|
||||
uint32_t fb_height;
|
||||
uint32_t fb_pitch;
|
||||
|
||||
|
||||
|
||||
|
||||
static int cursor_x = 0;
|
||||
static int cursor_y = 0;
|
||||
|
||||
void put_pixel(int x, int y, uint32_t color) {
|
||||
fb[y * fb_pitch + x] = color;
|
||||
}
|
||||
|
||||
static void scroll_up(void) {
|
||||
uint32_t line_pixels = FONT_HEIGHT * fb_pitch;
|
||||
uint32_t total_pixels = fb_height * fb_pitch;
|
||||
|
||||
// Shift everything up by one line
|
||||
memmove(fb, fb + line_pixels, (total_pixels - line_pixels) * sizeof(uint32_t));
|
||||
|
||||
// Clear the last line
|
||||
memset(fb + (total_pixels - line_pixels), 0, line_pixels * sizeof(uint32_t));
|
||||
|
||||
cursor_y -= FONT_HEIGHT;
|
||||
}
|
||||
|
||||
void draw_char_colored(int x, int y, char c, uint32_t color) {
|
||||
PSF1_Header *font = (PSF1_Header*)(uintptr_t)zap_light16_psf;
|
||||
uint8_t *glyphs = zap_light16_psf + sizeof(PSF1_Header);
|
||||
int charsize = font->charsize;
|
||||
uint8_t *glyph = glyphs + ((unsigned char)c * charsize);
|
||||
|
||||
for (int row = 0; row < charsize; row++) {
|
||||
for (int col = 0; col < 8; col++) {
|
||||
if (glyph[row] & (0x80 >> col)) {
|
||||
fb[(y + row) * fb_pitch + (x + col)] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void putchar(char c) {
|
||||
if (c == '\n') {
|
||||
cursor_x = 0;
|
||||
cursor_y += FONT_HEIGHT;
|
||||
if (cursor_y + FONT_HEIGHT > fb_height) scroll_up();
|
||||
return;
|
||||
}
|
||||
|
||||
draw_char_colored(cursor_x, cursor_y, c, 0xFFFFFF);
|
||||
cursor_x += FONT_WIDTH;
|
||||
|
||||
if (cursor_x >= (int)fb_width) {
|
||||
cursor_x = 0;
|
||||
cursor_y += FONT_HEIGHT;
|
||||
if (cursor_y + FONT_HEIGHT > fb_height) scroll_up();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void putchar_colored(char c, uint32_t color) {
|
||||
if (c == '\n') {
|
||||
cursor_x = 0;
|
||||
cursor_y += FONT_HEIGHT;
|
||||
if (cursor_y + FONT_HEIGHT > fb_height) scroll_up();
|
||||
return;
|
||||
}
|
||||
|
||||
draw_char_colored(cursor_x, cursor_y, c, color);
|
||||
cursor_x += FONT_WIDTH;
|
||||
|
||||
if (cursor_x >= (int)fb_width) {
|
||||
cursor_x = 0;
|
||||
cursor_y += FONT_HEIGHT;
|
||||
if (cursor_y + FONT_HEIGHT > fb_height) scroll_up();
|
||||
}
|
||||
}
|
||||
|
||||
void print(const char *str) {
|
||||
while (*str) {
|
||||
putchar(*str++);
|
||||
}
|
||||
}
|
||||
|
||||
void itoa(int value, char *buf, int base) {
|
||||
char *ptr = buf, *ptr1 = buf, tmp_char;
|
||||
int tmp_value;
|
||||
|
||||
do {
|
||||
tmp_value = value;
|
||||
value /= base;
|
||||
*ptr++ = "0123456789ABCDEF"[tmp_value - value * base];
|
||||
} while (value);
|
||||
|
||||
*ptr-- = '\0';
|
||||
|
||||
while (ptr1 < ptr) {
|
||||
tmp_char = *ptr;
|
||||
*ptr-- = *ptr1;
|
||||
*ptr1++ = tmp_char;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t sample(uint32_t *src, int w, int h, int x, int y)
|
||||
{
|
||||
if (x < 0) x = 0;
|
||||
if (y < 0) y = 0;
|
||||
if (x >= w) x = w - 1;
|
||||
if (y >= h) y = h - 1;
|
||||
|
||||
return src[y * w + x];
|
||||
}
|
||||
|
||||
void clear_screen(uint32_t color)
|
||||
{
|
||||
uint32_t total = fb_width * fb_height;
|
||||
|
||||
for (uint32_t i = 0; i < total; i++)
|
||||
{
|
||||
fb[i] = color;
|
||||
}
|
||||
cursor_y = 0;
|
||||
}
|
||||
|
||||
void draw_image_bilinear(uint32_t *img, int x0, int y0, int new_w, int new_h)
|
||||
{
|
||||
int src_w = img[0];
|
||||
int src_h = img[1];
|
||||
uint32_t *src = &img[2];
|
||||
|
||||
// fixed-point scale factors (16.16)
|
||||
uint32_t x_scale = (src_w << 16) / new_w;
|
||||
uint32_t y_scale = (src_h << 16) / new_h;
|
||||
|
||||
for (int y = 0; y < new_h; y++)
|
||||
{
|
||||
int sy_fp = y * y_scale;
|
||||
int sy = sy_fp >> 16;
|
||||
int fy = (sy_fp >> 8) & 0xFF;
|
||||
|
||||
for (int x = 0; x < new_w; x++)
|
||||
{
|
||||
int sx_fp = x * x_scale;
|
||||
int sx = sx_fp >> 16;
|
||||
int fx = (sx_fp >> 8) & 0xFF;
|
||||
|
||||
int x1 = sx + 1;
|
||||
int y1 = sy + 1;
|
||||
|
||||
uint32_t c00 = sample(src, src_w, src_h, sx, sy);
|
||||
uint32_t c10 = sample(src, src_w, src_h, x1, sy);
|
||||
uint32_t c01 = sample(src, src_w, src_h, sx, y1);
|
||||
uint32_t c11 = sample(src, src_w, src_h, x1, y1);
|
||||
|
||||
// unpack
|
||||
uint32_t a00 = (c00 >> 24) & 0xFF;
|
||||
uint32_t r00 = (c00 >> 16) & 0xFF;
|
||||
uint32_t g00 = (c00 >> 8) & 0xFF;
|
||||
uint32_t b00 = (c00) & 0xFF;
|
||||
|
||||
uint32_t a10 = (c10 >> 24) & 0xFF;
|
||||
uint32_t r10 = (c10 >> 16) & 0xFF;
|
||||
uint32_t g10 = (c10 >> 8) & 0xFF;
|
||||
uint32_t b10 = (c10) & 0xFF;
|
||||
|
||||
uint32_t a01 = (c01 >> 24) & 0xFF;
|
||||
uint32_t r01 = (c01 >> 16) & 0xFF;
|
||||
uint32_t g01 = (c01 >> 8) & 0xFF;
|
||||
uint32_t b01 = (c01) & 0xFF;
|
||||
|
||||
uint32_t a11 = (c11 >> 24) & 0xFF;
|
||||
uint32_t r11 = (c11 >> 16) & 0xFF;
|
||||
uint32_t g11 = (c11 >> 8) & 0xFF;
|
||||
uint32_t b11 = (c11) & 0xFF;
|
||||
|
||||
// bilinear interpolation weights
|
||||
uint32_t w00 = (256 - fx) * (256 - fy);
|
||||
uint32_t w10 = fx * (256 - fy);
|
||||
uint32_t w01 = (256 - fx) * fy;
|
||||
uint32_t w11 = fx * fy;
|
||||
|
||||
uint32_t a = (a00*w00 + a10*w10 + a01*w01 + a11*w11) >> 16;
|
||||
uint32_t r = (r00*w00 + r10*w10 + r01*w01 + r11*w11) >> 16;
|
||||
uint32_t g = (g00*w00 + g10*w10 + g01*w01 + g11*w11) >> 16;
|
||||
uint32_t b = (b00*w00 + b10*w10 + b01*w01 + b11*w11) >> 16;
|
||||
|
||||
int dst_x = x0 + x;
|
||||
int dst_y = y0 + y;
|
||||
|
||||
if (dst_x < 0 || dst_y < 0 ||
|
||||
dst_x >= (int)fb_width ||
|
||||
dst_y >= (int)fb_height)
|
||||
continue;
|
||||
|
||||
uint32_t color = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
|
||||
// alpha blend with framebuffer
|
||||
if (a < 255)
|
||||
{
|
||||
uint32_t dst = fb[dst_y * fb_pitch + dst_x];
|
||||
|
||||
uint32_t dr = (dst >> 16) & 0xFF;
|
||||
uint32_t dg = (dst >> 8) & 0xFF;
|
||||
uint32_t db = dst & 0xFF;
|
||||
|
||||
uint32_t inv = 255 - a;
|
||||
|
||||
r = (r * a + dr * inv) / 255;
|
||||
g = (g * a + dg * inv) / 255;
|
||||
b = (b * a + db * inv) / 255;
|
||||
|
||||
fb[dst_y * fb_pitch + dst_x] =
|
||||
(0xFF << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
else
|
||||
{
|
||||
fb[dst_y * fb_pitch + dst_x] =
|
||||
(0xFF << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void backspace() {
|
||||
if (cursor_x >= FONT_WIDTH) {
|
||||
cursor_x -= FONT_WIDTH;
|
||||
|
||||
// clear the character cell
|
||||
for (int y = 0; y < FONT_HEIGHT; y++) {
|
||||
for (int x = 0; x < FONT_WIDTH; x++) {
|
||||
fb[(cursor_y + y) * fb_pitch + (cursor_x + x)] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_image(uint32_t *img, int x0, int y0)
|
||||
{
|
||||
uint32_t w = img[0];
|
||||
uint32_t h = img[1];
|
||||
uint32_t *pixels = &img[2];
|
||||
|
||||
for (uint32_t y = 0; y < h; y++) {
|
||||
for (uint32_t x = 0; x < w; x++) {
|
||||
|
||||
int dst_x = x0 + x;
|
||||
int dst_y = y0 + y;
|
||||
|
||||
// bounds check (VERY important in kernel)
|
||||
if (dst_x < 0 || dst_y < 0 ||
|
||||
dst_x >= (int)fb_width ||
|
||||
dst_y >= (int)fb_height)
|
||||
continue;
|
||||
|
||||
uint32_t color = pixels[y * w + x];
|
||||
|
||||
// alpha handling (TGA is ARGB in your parser)
|
||||
uint8_t a = color >> 24;
|
||||
|
||||
// fully transparent → skip
|
||||
if (a == 0)
|
||||
continue;
|
||||
|
||||
// optional: simple alpha blend
|
||||
if (a < 255) {
|
||||
uint32_t dst = fb[dst_y * fb_pitch + dst_x];
|
||||
|
||||
uint8_t sr = (color >> 16) & 0xFF;
|
||||
uint8_t sg = (color >> 8) & 0xFF;
|
||||
uint8_t sb = (color) & 0xFF;
|
||||
|
||||
uint8_t dr = (dst >> 16) & 0xFF;
|
||||
uint8_t dg = (dst >> 8) & 0xFF;
|
||||
uint8_t db = (dst) & 0xFF;
|
||||
|
||||
uint8_t inv = 255 - a;
|
||||
|
||||
uint32_t out =
|
||||
((sr * a + dr * inv) / 255) << 16 |
|
||||
((sg * a + dg * inv) / 255) << 8 |
|
||||
((sb * a + db * inv) / 255);
|
||||
|
||||
fb[dst_y * fb_pitch + dst_x] = out;
|
||||
}
|
||||
else {
|
||||
// opaque fast path
|
||||
fb[dst_y * fb_pitch + dst_x] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*void printf(const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
char buffer[32];
|
||||
|
||||
for (int i = 0; fmt[i] != 0; i++) {
|
||||
if (fmt[i] == '%') {
|
||||
i++;
|
||||
|
||||
switch (fmt[i]) {
|
||||
case 'd': {
|
||||
int val = va_arg(args, int);
|
||||
itoa(val, buffer, 10);
|
||||
print(buffer);
|
||||
break;
|
||||
}
|
||||
case 'x': {
|
||||
int val = va_arg(args, int);
|
||||
itoa(val, buffer, 16);
|
||||
print(buffer);
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
char *str = va_arg(args, char*);
|
||||
print(str);
|
||||
break;
|
||||
}
|
||||
case 'c': {
|
||||
char c = (char)va_arg(args, int);
|
||||
putchar(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
putchar(fmt[i]);
|
||||
}
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
}*/
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#define FONT_WIDTH 8
|
||||
#define FONT_HEIGHT 16
|
||||
|
||||
extern uint32_t *fb;
|
||||
extern uint32_t fb_width;
|
||||
extern uint32_t fb_height;
|
||||
extern uint32_t fb_pitch;
|
||||
|
||||
|
||||
void putchar(char c);
|
||||
void putchar_colored(char c, uint32_t color);
|
||||
void draw_image(uint32_t *img, int x0, int y0);
|
||||
void draw_image_bilinear(uint32_t *img, int x0, int y0, int new_w, int new_h);
|
||||
void clear_screen(uint32_t color);
|
||||
void backspace();
|
||||
+253
@@ -0,0 +1,253 @@
|
||||
#include "mm/memory.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static inline int ok(int m, int need, int size)
|
||||
{
|
||||
return (m >= 0 && need >= 0 && m <= size && size - m >= need);
|
||||
}
|
||||
|
||||
static inline uint32_t read_color(unsigned char *pal, int idx, int bpp)
|
||||
{
|
||||
// palette entry size = bpp/8
|
||||
int step = bpp >> 3;
|
||||
|
||||
unsigned char b = pal[idx * step + 0];
|
||||
unsigned char g = pal[idx * step + 1];
|
||||
unsigned char r = pal[idx * step + 2];
|
||||
unsigned char a = (step == 4) ? pal[idx * step + 3] : 0xFF;
|
||||
|
||||
return ((uint32_t)a << 24) |
|
||||
((uint32_t)r << 16) |
|
||||
((uint32_t)g << 8) |
|
||||
(uint32_t)b;
|
||||
}
|
||||
|
||||
unsigned int *tga_parse(unsigned char *ptr, int size)
|
||||
{
|
||||
if (!ptr || size < 18) return NULL;
|
||||
|
||||
int m = 0;
|
||||
|
||||
int id_len = ptr[0];
|
||||
int cmap_type = ptr[1];
|
||||
int img_type = ptr[2];
|
||||
|
||||
int cmap_start = ptr[3] | (ptr[4] << 8);
|
||||
int cmap_len = ptr[5] | (ptr[6] << 8);
|
||||
int cmap_bpp = ptr[7];
|
||||
|
||||
int w = ptr[12] | (ptr[13] << 8);
|
||||
int h = ptr[14] | (ptr[15] << 8);
|
||||
int bpp = ptr[16];
|
||||
int desc = ptr[17];
|
||||
|
||||
if (w <= 0 || h <= 0 || w > 4096 || h > 4096)
|
||||
return NULL;
|
||||
|
||||
if (!ok(18, id_len, size))
|
||||
return NULL;
|
||||
|
||||
m = 18 + id_len;
|
||||
if (m > size) return NULL;
|
||||
|
||||
int flip_y = !(desc & 0x20);
|
||||
|
||||
size_t pixels = (size_t)w * (size_t)h;
|
||||
if (pixels == 0 || pixels > (SIZE_MAX / sizeof(unsigned int)))
|
||||
return NULL;
|
||||
|
||||
unsigned int *out = (unsigned int *)kmalloc((pixels + 2) * sizeof(unsigned int));
|
||||
if (!out) return NULL;
|
||||
|
||||
out[0] = w;
|
||||
out[1] = h;
|
||||
|
||||
size_t i = 0;
|
||||
|
||||
unsigned char *palette = NULL;
|
||||
if (cmap_type == 1)
|
||||
{
|
||||
// palette starts immediately after header+id
|
||||
palette = ptr + m;
|
||||
|
||||
size_t pal_size = (size_t)cmap_len * (cmap_bpp >> 3);
|
||||
if (!ok(m, pal_size, size)) {
|
||||
kfree(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m += pal_size;
|
||||
}
|
||||
|
||||
// =========================
|
||||
// TYPE 2 (TRUECOLOR)
|
||||
// =========================
|
||||
if (img_type == 2)
|
||||
{
|
||||
int bytespp = bpp >> 3;
|
||||
if (bytespp != 3 && bytespp != 4) goto fail;
|
||||
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
int row = flip_y ? (h - 1 - y) : y;
|
||||
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
if (!ok(m, bytespp, size)) goto fail;
|
||||
|
||||
unsigned char b = ptr[m + 0];
|
||||
unsigned char g = ptr[m + 1];
|
||||
unsigned char r = ptr[m + 2];
|
||||
unsigned char a = (bytespp == 4) ? ptr[m + 3] : 0xFF;
|
||||
|
||||
m += bytespp;
|
||||
|
||||
out[2 + (size_t)row * w + x] =
|
||||
((uint32_t)a << 24) |
|
||||
((uint32_t)r << 16) |
|
||||
((uint32_t)g << 8) |
|
||||
(uint32_t)b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =========================
|
||||
// TYPE 3 (GRAYSCALE)
|
||||
// =========================
|
||||
else if (img_type == 3)
|
||||
{
|
||||
for (size_t idx = 0; idx < pixels; idx++)
|
||||
{
|
||||
if (!ok(m, 1, size)) goto fail;
|
||||
|
||||
unsigned char v = ptr[m++];
|
||||
|
||||
out[2 + idx] =
|
||||
0xFF000000 |
|
||||
(v << 16) |
|
||||
(v << 8) |
|
||||
v;
|
||||
}
|
||||
}
|
||||
|
||||
// =========================
|
||||
// TYPE 1 (PALETTED)
|
||||
// =========================
|
||||
else if (img_type == 1)
|
||||
{
|
||||
if (!palette) goto fail;
|
||||
|
||||
for (size_t idx = 0; idx < pixels; idx++)
|
||||
{
|
||||
if (!ok(m, 1, size)) goto fail;
|
||||
|
||||
unsigned char index = ptr[m++];
|
||||
|
||||
out[2 + idx] = read_color(palette, index, cmap_bpp);
|
||||
}
|
||||
}
|
||||
|
||||
// =========================
|
||||
// TYPE 9/10/11 (RLE)
|
||||
// =========================
|
||||
else if (img_type == 9 || img_type == 10 || img_type == 11)
|
||||
{
|
||||
int bytespp = (img_type == 9) ? 1 : (bpp >> 3);
|
||||
if (img_type != 9 && bytespp != 3 && bytespp != 4) goto fail;
|
||||
|
||||
while (i < pixels)
|
||||
{
|
||||
if (!ok(m, 1, size)) goto fail;
|
||||
|
||||
unsigned char packet = ptr[m++];
|
||||
int count = (packet & 0x7F) + 1;
|
||||
|
||||
if (count > (int)(pixels - i))
|
||||
count = (int)(pixels - i);
|
||||
|
||||
if (packet & 0x80)
|
||||
{
|
||||
// RLE
|
||||
if (!ok(m, bytespp, size)) goto fail;
|
||||
|
||||
uint32_t color;
|
||||
|
||||
if (img_type == 9)
|
||||
{
|
||||
color = read_color(palette, ptr[m], cmap_bpp);
|
||||
m += 1;
|
||||
}
|
||||
else if (img_type == 11)
|
||||
{
|
||||
unsigned char v = ptr[m++];
|
||||
color = 0xFF000000 | (v << 16) | (v << 8) | v;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char b = ptr[m + 0];
|
||||
unsigned char g = ptr[m + 1];
|
||||
unsigned char r = ptr[m + 2];
|
||||
unsigned char a = (bytespp == 4) ? ptr[m + 3] : 0xFF;
|
||||
m += bytespp;
|
||||
|
||||
color =
|
||||
((uint32_t)a << 24) |
|
||||
((uint32_t)r << 16) |
|
||||
((uint32_t)g << 8) |
|
||||
(uint32_t)b;
|
||||
}
|
||||
|
||||
for (int k = 0; k < count; k++)
|
||||
out[2 + i++] = color;
|
||||
}
|
||||
else
|
||||
{
|
||||
// RAW
|
||||
for (int k = 0; k < count; k++)
|
||||
{
|
||||
if (!ok(m, bytespp, size)) goto fail;
|
||||
|
||||
uint32_t color;
|
||||
|
||||
if (img_type == 9)
|
||||
{
|
||||
color = read_color(palette, ptr[m++], cmap_bpp);
|
||||
}
|
||||
else if (img_type == 11)
|
||||
{
|
||||
unsigned char v = ptr[m++];
|
||||
color = 0xFF000000 | (v << 16) | (v << 8) | v;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char b = ptr[m + 0];
|
||||
unsigned char g = ptr[m + 1];
|
||||
unsigned char r = ptr[m + 2];
|
||||
unsigned char a = (bytespp == 4) ? ptr[m + 3] : 0xFF;
|
||||
|
||||
m += bytespp;
|
||||
|
||||
color =
|
||||
((uint32_t)a << 24) |
|
||||
((uint32_t)r << 16) |
|
||||
((uint32_t)g << 8) |
|
||||
(uint32_t)b;
|
||||
}
|
||||
|
||||
out[2 + i++] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
fail:
|
||||
kfree(out);
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct {
|
||||
unsigned char magic1; // must be zero
|
||||
unsigned char colormap; // must be zero
|
||||
unsigned char encoding; // must be 2
|
||||
unsigned short cmaporig, cmaplen; // must be zero
|
||||
unsigned char cmapent; // must be zero
|
||||
unsigned short x; // must be zero
|
||||
unsigned short y; // image's height
|
||||
unsigned short h; // image's height
|
||||
unsigned short w; // image's width
|
||||
unsigned char bpp; // must be 32
|
||||
unsigned char pixeltype; // must be 40
|
||||
} __attribute__((packed)) tga_header_t;
|
||||
unsigned int *tga_parse(unsigned char *ptr, int size);
|
||||
Reference in New Issue
Block a user