initial razzle

This commit is contained in:
Nicholas Orlowsky 2024-10-03 02:55:54 -05:00
commit cd3d8871df
29 changed files with 1986 additions and 0 deletions

32
arch/i386/asm.c Normal file
View file

@ -0,0 +1,32 @@
#pragma once
#include <stdint.h>
struct regs {
unsigned int gs, fs, es, ds;
unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;
unsigned int int_no, err_code;
unsigned int eip, cs, eflags, useresp, ss;
};
void __sl_acquire(uint32_t *lock_id) {
__asm__("retry_lock: lock bts $0,(%0); pause; jc retry_lock" : "+g"(lock_id));
}
void __sl_release(uint32_t *lock_id) {
__asm__("lock btr $0, (%0)" : "+g"(lock_id));
}
static inline void outb(int port, int val) {
__asm__ volatile("outb %b0, %w1" : : "a"(val), "Nd"(port) : "memory");
}
static inline unsigned char inb(int port) {
unsigned char val;
__asm__ volatile("inb %w1, %b0" : "=a"(val) : "Nd"(port) : "memory");
return val;
}
static inline void interrupt_disable() { __asm__ volatile("cli"); }
static inline void interrupt_enable() { __asm__ volatile("sti"); }

121
arch/i386/gdt.c Normal file
View file

@ -0,0 +1,121 @@
#pragma once
#include "../../kernel/memory.c"
#include <stdint.h>
struct gdt_row_t {
uint16_t limit_low;
uint16_t base_low;
uint8_t base_middle;
uint8_t access;
uint8_t granularity_limit_high;
uint8_t base_high;
} __attribute__((packed));
struct gdt_ptr_t {
uint16_t size;
uint32_t address;
} __attribute__((packed));
struct tss_row_t {
uint32_t prev_tss;
uint32_t esp_ring0;
uint32_t ss_ring0;
uint32_t padding[23]; // Extra options RAZZLE doesn't use
} __attribute__((packed));
enum gdt_access_t {
GDT_ACCESS_PRESENT = 0b10000000,
GDT_ACCESS_DPL_KERNEL = 0b00000000,
GDT_ACCESS_DPL_USER = 0b01100000,
GDT_ACCESS_CODEDATA = 0b00010000,
GDT_ACCESS_EXECUTABLE = 0b00001000,
GDT_ACCESS_GROW_DOWN = 0b00000100,
GDT_ACCESS_RW = 0b00000010,
GDT_ACCESS_ACCESSED = 0b00000001,
};
enum gdt_granularity_t {
GDT_GRANULARITY_4K = 0b10001111,
GDT_GRANULARITY_MODE_32BIT = 0b01001111,
};
struct tss_row_t tss_entry;
#define GDT_SIZE (6)
struct gdt_row_t gdt[GDT_SIZE];
void load_gdt(struct gdt_ptr_t *gp) {
asm volatile("lgdt (%0)\n\t"
"mov $0x10, %%ax\n\t"
"mov %%ax, %%ds\n\t"
"mov %%ax, %%es\n\t"
"mov %%ax, %%fs\n\t"
"mov %%ax, %%gs\n\t"
"mov %%ax, %%ss\n\t"
:
: "r"(gp)
: "%ax");
}
void set_gdt_row(uint32_t num, uint32_t base, uint32_t limit, uint8_t access,
uint8_t granularity) {
gdt[num].base_low = base & 0xFFFF;
gdt[num].base_middle = (base >> 16) & 0xFF;
gdt[num].base_high = (base >> 24) & 0xFF;
gdt[num].limit_low = limit & 0xFFFF;
gdt[num].granularity_limit_high = (limit >> 16) & 0x0F;
gdt[num].granularity_limit_high |= granularity & 0xF0;
gdt[num].access = access;
}
void load_tss(uint16_t gdt_row_num) {
gdt_row_num *= 8;
__asm__ volatile("mov %0, %%ax; ltr %%ax" : : "r"(gdt_row_num) : "ax");
}
#define KERNEL_CODE_SEL (0x08)
#define KERNEL_DATA_SEL (0x10)
void init_gdt() {
struct gdt_ptr_t gp;
gp.size = (sizeof(struct gdt_row_t) * GDT_SIZE) - 1;
gp.address = (uint32_t)&gdt;
set_gdt_row(0, 0, 0, 0, 0);
// Kernelmode code/data degments
set_gdt_row(1, 0, 0xFFFFFFFF,
GDT_ACCESS_PRESENT | GDT_ACCESS_DPL_KERNEL | GDT_ACCESS_CODEDATA |
GDT_ACCESS_EXECUTABLE | GDT_ACCESS_RW | GDT_ACCESS_ACCESSED,
GDT_GRANULARITY_4K | GDT_GRANULARITY_MODE_32BIT);
set_gdt_row(2, 0, 0xFFFFFFFF,
GDT_ACCESS_PRESENT | GDT_ACCESS_DPL_KERNEL | GDT_ACCESS_CODEDATA |
GDT_ACCESS_RW | GDT_ACCESS_ACCESSED,
GDT_GRANULARITY_4K | GDT_GRANULARITY_MODE_32BIT);
// Usermode code/data segments
set_gdt_row(3, 0x0000000, 0xFFFFFFFF,
GDT_ACCESS_PRESENT | GDT_ACCESS_DPL_USER | GDT_ACCESS_CODEDATA |
GDT_ACCESS_EXECUTABLE | GDT_ACCESS_RW | GDT_ACCESS_ACCESSED,
GDT_GRANULARITY_4K | GDT_GRANULARITY_MODE_32BIT);
set_gdt_row(4, 0x0000000, 0xFFFFFFFF,
GDT_ACCESS_PRESENT | GDT_ACCESS_DPL_USER | GDT_ACCESS_CODEDATA |
GDT_ACCESS_RW | GDT_ACCESS_ACCESSED,
GDT_GRANULARITY_4K | GDT_GRANULARITY_MODE_32BIT);
// TSS row
set_gdt_row(5, (uint32_t)&tss_entry, sizeof(tss_entry),
GDT_ACCESS_PRESENT | GDT_ACCESS_EXECUTABLE | GDT_ACCESS_ACCESSED,
GDT_GRANULARITY_4K | GDT_GRANULARITY_MODE_32BIT);
// Setup TSS
int kstack = 0;
memset((char *)&tss_entry, 0, sizeof(tss_entry));
tss_entry.ss_ring0 = 0x10;
tss_entry.esp_ring0 = (uint32_t)&kstack;
// Load GDT and TSS
load_gdt(&gp);
load_tss(5);
}

52
arch/i386/handlers.h Normal file
View file

@ -0,0 +1,52 @@
#pragma once
extern void irq0();
extern void irq1();
extern void irq2();
extern void irq3();
extern void irq4();
extern void irq5();
extern void irq6();
extern void irq7();
extern void irq8();
extern void irq9();
extern void irq10();
extern void irq11();
extern void irq12();
extern void irq13();
extern void irq14();
extern void irq15();
extern void irq128();
extern void isr0();
extern void isr1();
extern void isr2();
extern void isr3();
extern void isr4();
extern void isr5();
extern void isr6();
extern void isr7();
extern void isr8();
extern void isr9();
extern void isr10();
extern void isr11();
extern void isr12();
extern void isr13();
extern void isr14();
extern void isr15();
extern void isr16();
extern void isr17();
extern void isr18();
extern void isr19();
extern void isr20();
extern void isr21();
extern void isr22();
extern void isr23();
extern void isr24();
extern void isr25();
extern void isr26();
extern void isr27();
extern void isr28();
extern void isr29();
extern void isr30();
extern void isr31();

86
arch/i386/idt.c Normal file
View file

@ -0,0 +1,86 @@
#pragma once
#include "../../kernel/memory.c"
#include "./handlers.h"
#include "gdt.c"
struct idt_row_t {
uint16_t base_lo;
uint16_t sel;
uint8_t unset;
uint8_t flags;
uint16_t base_hi;
} __attribute__((packed));
struct idt_ptr_t {
uint16_t size;
uint32_t address;
} __attribute__((packed));
// TODO: double check this?
enum idt_flag_t {
IDTFLAG_PRESENT = 0b10000000,
IDTFLAG_DPL_KERNEL = 0b00000000,
IDTFLAG_DPL_USER = 0b01100000,
IDTFLAG_TRAP = 0b00001111,
IDTFLAG_INTERRUPT = 0b00001110,
};
#define KERNEL_INTERRUPT_FLAG (IDTFLAG_PRESENT | IDTFLAG_DPL_KERNEL | IDTFLAG_INTERRUPT)
#define USER_TRAP_FLAG (IDTFLAG_PRESENT | IDTFLAG_DPL_USER | IDTFLAG_INTERRUPT)
#define IDT_SIZE (256)
struct idt_row_t idt[IDT_SIZE];
struct idt_ptr_t idtp;
void load_idt(struct idt_ptr_t *pt) { asm volatile("lidt (%0)" ::"r"(pt)); }
void set_idt_row(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) {
idt[num].base_hi = (base >> 16) & 0x0000FFFF;
idt[num].base_lo = base & 0x0000FFFF;
idt[num].sel = sel;
idt[num].flags = flags;
idt[num].unset = 0;
}
void init_idt() {
idtp.size = (sizeof(struct idt_row_t) * IDT_SIZE) - 1;
idtp.address = (uint32_t)&idt;
memset((char *)&idt, 0, sizeof(struct idt_row_t) * IDT_SIZE);
set_idt_row(0, (uint32_t)isr0, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(1, (uint32_t)isr1, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(2, (uint32_t)isr2, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(3, (uint32_t)isr3, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(4, (uint32_t)isr4, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(5, (uint32_t)isr5, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(6, (uint32_t)isr6, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(7, (uint32_t)isr7, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(8, (uint32_t)isr8, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(9, (uint32_t)isr9, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(10, (uint32_t)isr10, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(11, (uint32_t)isr11, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(12, (uint32_t)isr12, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(13, (uint32_t)isr13, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(14, (uint32_t)isr14, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(15, (uint32_t)isr15, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(16, (uint32_t)isr16, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(17, (uint32_t)isr17, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(18, (uint32_t)isr18, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(19, (uint32_t)isr19, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(20, (uint32_t)isr20, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(21, (uint32_t)isr21, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(22, (uint32_t)isr22, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(23, (uint32_t)isr23, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(24, (uint32_t)isr24, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(25, (uint32_t)isr25, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(26, (uint32_t)isr26, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(27, (uint32_t)isr27, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(28, (uint32_t)isr28, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(29, (uint32_t)isr29, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(30, (uint32_t)isr30, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(31, (uint32_t)isr31, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
load_idt(&idtp);
}

11
arch/i386/init.c Normal file
View file

@ -0,0 +1,11 @@
#pragma once
#include "./gdt.c"
#include "./idt.c"
#include "./irq.c"
void arch_init() {
init_gdt();
init_idt();
init_irq();
}

81
arch/i386/irq.c Normal file
View file

@ -0,0 +1,81 @@
#pragma once
#include "../../kernel/ps2.c"
#include "../../kernel/syscall.c"
#include "./asm.c"
#include "./idt.c"
#include "handlers.h"
enum irq_code_t {
IRQCODE_PIT = 32,
IRQCODE_PS2 = 33,
IRQCODE_SYSCALL = 128,
};
void kb_handler() {
uint8_t char_code = inb(0x60);
handle_keypress(char_code);
}
void remap_irq(void) {
outb(0x20, 0x11);
outb(0xA0, 0x11);
outb(0x21, 0x20);
outb(0xA1, 0x28);
outb(0x21, 0x04);
outb(0xA1, 0x02);
outb(0x21, 0x01);
outb(0xA1, 0x01);
outb(0x21, 0x0);
outb(0xA1, 0x0);
}
void init_irq() {
remap_irq();
set_idt_row(32, (uint32_t)irq0, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(33, (uint32_t)irq1, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(34, (uint32_t)irq2, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(35, (uint32_t)irq3, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(36, (uint32_t)irq4, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(37, (uint32_t)irq5, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(38, (uint32_t)irq6, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(39, (uint32_t)irq7, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(40, (uint32_t)irq8, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(41, (uint32_t)irq9, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(42, (uint32_t)irq10, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(43, (uint32_t)irq11, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(44, (uint32_t)irq12, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(45, (uint32_t)irq13, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(46, (uint32_t)irq14, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(47, (uint32_t)irq15, KERNEL_CODE_SEL, KERNEL_INTERRUPT_FLAG);
set_idt_row(128, (uint32_t)irq128, KERNEL_CODE_SEL, USER_TRAP_FLAG);
}
void irq_handler(struct regs *r) {
switch (r->int_no) {
case IRQCODE_SYSCALL: {
syscall(r);
break;
};
case IRQCODE_PIT: {
schedule(r);
break;
};
case IRQCODE_PS2: {
kb_handler();
break;
};
}
// Send EOI to follower controller
if (r->int_no >= 40 && r->int_no < 48) {
outb(0xA0, 0x20);
}
// Send EOI to leader controller
outb(0x20, 0x20);
}

143
arch/i386/irq.s Normal file
View file

@ -0,0 +1,143 @@
.global irq0
.global irq1
.global irq2
.global irq3
.global irq4
.global irq5
.global irq6
.global irq7
.global irq8
.global irq9
.global irq10
.global irq11
.global irq12
.global irq13
.global irq14
.global irq15
.global irq128
irq0:
cli
push $0
push $32
jmp irq_handle
irq1:
cli
push $1
push $33
jmp irq_handle
irq2:
cli
push $2
push $34
jmp irq_handle
irq3:
cli
push $3
push $35
jmp irq_handle
irq4:
cli
push $4
push $36
jmp irq_handle
irq5:
cli
push $5
push $37
jmp irq_handle
irq6:
cli
push $6
push $38
jmp irq_handle
irq7:
cli
push $7
push $39
jmp irq_handle
irq8:
cli
push $8
push $40
jmp irq_handle
irq9:
cli
push $9
push $41
jmp irq_handle
irq10:
cli
push $10
push $42
jmp irq_handle
irq11:
cli
push $11
push $43
jmp irq_handle
irq12:
cli
push $12
push $44
jmp irq_handle
irq13:
cli
push $13
push $45
jmp irq_handle
irq14:
cli
push $14
push $46
jmp irq_handle
irq15:
cli
push $15
push $47
jmp irq_handle
irq128:
cli
push $0x80
push $0x80
jmp irq_handle
irq_handle:
pusha
push %ds
push %es
push %fs
push %gs
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
movl %esp, %eax
push %eax
movl $irq_handler, %eax
call *%eax
pop %eax
pop %gs
pop %fs
pop %es
pop %ds
popal
addl $8, %esp
iret

243
arch/i386/isr.s Normal file
View file

@ -0,0 +1,243 @@
.global isr0
.global isr1
.global isr2
.global isr3
.global isr4
.global isr5
.global isr6
.global isr7
.global isr8
.global isr9
.global isr10
.global isr11
.global isr12
.global isr13
.global isr14
.global isr15
.global isr16
.global isr17
.global isr18
.global isr19
.global isr20
.global isr21
.global isr22
.global isr23
.global isr24
.global isr25
.global isr26
.global isr27
.global isr28
.global isr29
.global isr30
.global isr31
isr0:
cli
push $0
push $0
jmp isr_handle
isr1:
cli
push $0
push $1
jmp isr_handle
isr2:
cli
push $0
push $2
jmp isr_handle
isr3:
cli
push $0
push $3
jmp isr_handle
isr4:
cli
push $0
push $4
jmp isr_handle
isr5:
cli
push $0
push $5
jmp isr_handle
isr6:
cli
push $0
push $6
jmp isr_handle
isr7:
cli
push $0
push $7
jmp isr_handle
isr8:
cli
push $0
push $8
jmp isr_handle
isr9:
cli
push $0
push $9
jmp isr_handle
isr10:
cli
push $10
jmp isr_handle
isr11:
cli
push $11
jmp isr_handle
isr12:
cli
push $12
jmp isr_handle
isr13:
cli
push $13
jmp isr_handle
isr14:
cli
push $14
jmp isr_handle
isr15:
cli
push $0
push $15
jmp isr_handle
isr16:
cli
push $0
push $16
jmp isr_handle
isr17:
cli
push $0
push $17
jmp isr_handle
isr18:
cli
push $0
push $18
jmp isr_handle
isr19:
cli
push $0
push $19
jmp isr_handle
isr20:
cli
push $0
push $20
jmp isr_handle
isr21:
cli
push $0
push $21
jmp isr_handle
isr22:
cli
push $0
push $22
jmp isr_handle
isr23:
cli
push $0
push $23
jmp isr_handle
isr24:
cli
push $0
push $24
jmp isr_handle
isr25:
cli
push $0
push $25
jmp isr_handle
isr26:
cli
push $0
push $26
jmp isr_handle
isr27:
cli
push $0
push $27
jmp isr_handle
isr28:
cli
push $0
push $28
jmp isr_handle
isr29:
cli
push $0
push $29
jmp isr_handle
isr30:
cli
push $0
push $30
jmp isr_handle
isr31:
cli
push $0
push $31
jmp isr_handle
isr_handle:
pushal
push %ds
push %es
push %fs
push %gs
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
movl %esp, %eax
push %eax
movl $fault_handler, %eax
call *%eax
pop %eax
pop %gs
pop %fs
pop %es
pop %ds
popal
addl $8, %esp
iret

26
arch/i386/loader.s Normal file
View file

@ -0,0 +1,26 @@
.set ALIGN, 1<<0
.set MEMINFO, 1<<1
.set FLAGS, ALIGN | MEMINFO
.set MAGIC, 0x1BADB002
.set CHECKSUM, -(MAGIC + FLAGS)
.section .multiboot
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
.section .bss
.align 16
stack_bottom:
.skip 16384
stack_top:
.section .text
.global _start
.type _start, @function
_start:
mov $stack_top, %esp
call kernel_main
.size _start, . - _start

66
arch/i386/scheduler.c Normal file
View file

@ -0,0 +1,66 @@
#pragma once
#include "asm.c"
enum eflags_t {
EFLAG_CARRY = 0x0001,
EFLAG_RES = 0x0002,
EFLAG_PARITY = 0x0004,
EFLAG_INTERRUPT = 0x0200
};
void initialize_registers(struct regs *new_regs, char *entrypoint,
uint32_t address_base, uint32_t address_space_size) {
new_regs->eip = (unsigned int)entrypoint;
new_regs->edi = 0;
new_regs->esi = 0;
new_regs->ebx = 0;
new_regs->edx = 0;
new_regs->ecx = 0;
new_regs->eax = 0;
new_regs->eflags = EFLAG_INTERRUPT;
new_regs->useresp = (unsigned int)address_base + address_space_size - 1;
new_regs->ebp = new_regs->useresp;
new_regs->ds = 35;
new_regs->es = 35;
new_regs->fs = 35;
new_regs->gs = 35;
new_regs->ss = 27;
}
void store_registers(struct regs *machine_regs, struct regs *current_regs) {
current_regs->edi = machine_regs->edi;
current_regs->esi = machine_regs->esi;
current_regs->ebx = machine_regs->ebx;
current_regs->edx = machine_regs->edx;
current_regs->ecx = machine_regs->ecx;
current_regs->eax = machine_regs->eax;
current_regs->eip = machine_regs->eip;
current_regs->eflags = machine_regs->eflags;
current_regs->useresp = machine_regs->useresp;
current_regs->ebp = machine_regs->ebp;
}
void switch_context(struct regs *machine_regs, struct regs *new_regs) {
machine_regs->edi = new_regs->edi;
machine_regs->esi = new_regs->esi;
machine_regs->ebx = new_regs->ebx;
machine_regs->edx = new_regs->edx;
machine_regs->ecx = new_regs->ecx;
machine_regs->eax = new_regs->eax;
machine_regs->eip = new_regs->eip;
machine_regs->eflags = new_regs->eflags;
machine_regs->esp = machine_regs->esp;
machine_regs->useresp = new_regs->useresp;
machine_regs->ebp = new_regs->ebp;
machine_regs->ds = 35;
machine_regs->es = 35;
machine_regs->fs = 35;
machine_regs->gs = 35;
machine_regs->ss = 35;
machine_regs->cs = 27;
}

8
arch/i386/syscall.c Normal file
View file

@ -0,0 +1,8 @@
#pragma once
#define INVOKE_SYSCALL(syscall_num) \
__asm__ volatile("movl %0, %%eax;" \
"int $0x80;" \
: \
: "r"(syscall_num) \
: "%eax")