dead@root fuck this shit

This commit is contained in:
assada 2024-05-23 20:59:18 +03:00
parent c355d80244
commit 5bd849abeb
Signed by: assada
GPG Key ID: D4860A938E541F06
23 changed files with 340 additions and 236 deletions

View File

@ -10,7 +10,7 @@ KERNEL = deados.bin
ISO = deados.iso ISO = deados.iso
SOURCES_C = kernel.c tty.c idt.c timer.c io.c vga.c gdt.c sys.c irq.c isr.c keyboard.c shell.c string.c user_space.c syscall.c SOURCES_C = kernel.c tty.c idt.c timer.c io.c vga.c gdt.c sys.c irq.c isr.c keyboard.c shell.c string.c user_space.c syscall.c
SOURCES_ASM = boot.s idt_load.s gdt_flush.s pit_handler.s irq_e.s isr_e.s tss.s SOURCES_ASM = boot.s idt_load.s gdt_flush.s irq_flush.s isr_flush.s tss_flush.s
OBJECTS = $(SOURCES_ASM:.s=.o) $(SOURCES_C:.c=.o) OBJECTS = $(SOURCES_ASM:.s=.o) $(SOURCES_C:.c=.o)
ISO_DIR = isodir ISO_DIR = isodir

12
boot.s
View File

@ -12,24 +12,20 @@
.section .bss .section .bss
.align 16 .align 16
stack_bottom: stack_bottom:
.skip 1024 * 32 # 32 KB .skip 16384
stack_top:
stack_top: stack_top:
.section .text .section .text
.global _start .global _start
.type _start, @function .type _start, @function
_start: _start:
cli
mov $stack_top, %esp mov $stack_top, %esp
push %ebx
call kernel_main call kernel_main
hlt
jmp 1
1: 1:
jmp 1 jmp 1b
.size _start, . - _start .size _start, . - _start

50
gdt.c
View File

@ -4,14 +4,14 @@
#define GDT_ENTRY 6 #define GDT_ENTRY 6
Gdt_entry gdt[GDT_ENTRY]; Gdt_entry gdt[GDT_ENTRY];
Gdt_ptr gdtp; Gdt_ptr gdt_ptr;
extern void gdt_flush(uint32_t); extern void gdt_flush(void);
Tss_entry tss; Tss_entry tss;
extern void tss_flush(void); extern void tss_flush(void);
static void gdt_set_gate(uint8_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t granularity) void gdt_set_gate(uint8_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t granularity)
{ {
gdt[num].base_low = base & 0xFFFF; gdt[num].base_low = base & 0xFFFF;
gdt[num].base_middle = (base >> 16) & 0xFF; gdt[num].base_middle = (base >> 16) & 0xFF;
@ -25,45 +25,37 @@ static void gdt_set_gate(uint8_t num, uint32_t base, uint32_t limit, uint8_t acc
gdt[num].access = access; gdt[num].access = access;
} }
static void tss_install(uint8_t num, uint16_t kernel_ss, uint16_t kernel_esp) void tss_set_gate(uint32_t num, uint16_t ss0, uint32_t esp0)
{ {
uint32_t base = (uint32_t)&tss; uint32_t base = (uint32_t)&tss;
uint32_t limit = base + sizeof(Tss_entry); uint32_t limit = base + sizeof(Tss_entry);
gdt_set_gate(num, base, limit, 0xE9, 0x0); gdt_set_gate(num, base, limit, 0xE9, 0x0);
memset(&tss, 0x0, sizeof(Tss_entry));
tss.ss0 = ss0;
tss.esp0 = esp0;
memset(&tss, 0, sizeof(Tss_entry)); tss.cs = 0x1B;
tss.ss = 0x23;
tss.ss0 = kernel_ss; tss.es = 0x23;
tss.esp0 = kernel_esp; tss.ds = 0x23;
tss.fs = 0x23;
tss.cs = 0x0B; tss.gs = 0x23;
tss.ss = 0x13;
tss.es = 0x13;
tss.ds = 0x13;
tss.fs = 0x13;
tss.gs = 0x13;
}
void set_kernel_stack(uint32_t stack)
{
tss.esp0 = stack;
} }
void gdt_install() void gdt_install()
{ {
gdt_set_gate(0, 0x0, 0x0, 0x0, 0x0); // Null segment gdt_set_gate(0, 0x0, 0x0, 0x0, 0x0); // Null segment
gdt_set_gate(1, 0x0, 0xFFFFFFFF, 0x9A, 0xCF); // Kernel code segment gdt_set_gate(1, 0x0, 0xFFFFFFFF, 0x9A, 0xC0); // 0x08 Kernel code segment
gdt_set_gate(2, 0x0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment gdt_set_gate(2, 0x0, 0xFFFFFFFF, 0x92, 0xC0); // 0x10 Kernel data segment
gdt_set_gate(3, 0x0, 0xFFFFFFFF, 0xFA, 0xCF); // User code segment gdt_set_gate(3, 0x0, 0xFFFFFFFF, 0xFA, 0xC0); // 0x18 User code segment
gdt_set_gate(4, 0x0, 0xFFFFFFFF, 0xF2, 0xCF); // User data segment gdt_set_gate(4, 0x0, 0xFFFFFFFF, 0xF2, 0xC0); // 0x20 User data segment
tss_install(5, 0x10, 0x0); tss_set_gate(5, 0x10, 0);
gdtp.limit = (sizeof(Gdt_entry) * GDT_ENTRY) - 1; gdt_ptr.limit = (sizeof(Gdt_entry) * GDT_ENTRY) - 1;
gdtp.base = (uint32_t)&gdt; gdt_ptr.base = (uint32_t)&gdt;
gdt_flush((uint32_t)&gdtp); gdt_flush();
tss_flush(); tss_flush();
} }

2
gdt.h
View File

@ -21,7 +21,7 @@ struct gdt_ptr_t
uint32_t base; uint32_t base;
} __attribute__((packed)); } __attribute__((packed));
static void gdt_set_gate(uint8_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t granularity); void gdt_set_gate(uint8_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t granularity);
void gdt_install(); void gdt_install();
void set_kernel_stack(uint32_t stack); void set_kernel_stack(uint32_t stack);

View File

@ -1,19 +1,17 @@
.section .text
.align 4
.global gdt_flush .global gdt_flush
.type gdt_flush, @function
gdt_flush: gdt_flush:
cli lgdt gdt_ptr
jmp $0x08, $reload_cs
mov 4(%esp), %eax reload_cs:
lgdt (%eax) movw $0x10, %ax
movw %ax, %ds
mov $0x10, %ax movw %ax, %es
mov %ax, %ds movw %ax, %fs
mov %ax, %es movw %ax, %gs
mov %ax, %fs movw %ax, %ss
mov %ax, %gs ret
mov %ax, %ss
jmp $0x08, $.flush
.flush:
ret

View File

@ -1,5 +1,8 @@
.section .text .section .text
.align 4
.global idt_load .global idt_load
.type idt_load, @function
idt_load: idt_load:
lidt [idtp] lidt idtp
ret ret

View File

@ -25,8 +25,8 @@ void isr_install(void);
#define NB_IRQ_ROUTINES 16 #define NB_IRQ_ROUTINES 16
#define PIC1 0x20 /* master PIC */ #define PIC1 0x20
#define PIC2 0xA0 /* slave PIC */ #define PIC2 0xA0
#define PIC1_CMD PIC1 #define PIC1_CMD PIC1
#define PIC1_DATA (PIC1 + 1) #define PIC1_DATA (PIC1 + 1)
#define PIC2_CMD PIC2 #define PIC2_CMD PIC2

16
io.c
View File

@ -1,18 +1,20 @@
#include "io.h" #include "io.h"
void outb(uint16_t port, uint8_t val) { void outb(uint16_t port, uint8_t val)
asm volatile ("outb %0, %1" : : "a"(val), "Nd"(port)); {
asm volatile("outb %0, %1" : : "a"(val), "Nd"(port));
} }
uint8_t inb(uint16_t port) { uint8_t inb(uint16_t port)
{
uint8_t ret; uint8_t ret;
asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port)); asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret; return ret;
} }
void io_wait(void) void io_wait(void)
{ {
asm volatile ( "jmp 1f\n\t" asm volatile("jmp 1f\n\t"
"1:jmp 2f\n\t" "1:jmp 2f\n\t"
"2:" ); "2:");
} }

11
irq.c
View File

@ -4,6 +4,7 @@
#include "io.h" #include "io.h"
#include "sys.h" #include "sys.h"
#include "idt.h" #include "idt.h"
#include "tty.h"
extern void irq0(void); extern void irq0(void);
extern void irq1(void); extern void irq1(void);
@ -42,24 +43,16 @@ void irq_call_handler(Stack *registers)
handler(registers); handler(registers);
} }
static void irq_remap(void) static void irq_remap(void) // PIC REMAP
{ {
outb(PIC1_CMD, ICW1_INIT | ICW1_ICW4); outb(PIC1_CMD, ICW1_INIT | ICW1_ICW4);
io_wait();
outb(PIC2_CMD, ICW1_INIT | ICW1_ICW4); outb(PIC2_CMD, ICW1_INIT | ICW1_ICW4);
io_wait();
outb(PIC1_DATA, PIC1_OFFSET); outb(PIC1_DATA, PIC1_OFFSET);
io_wait();
outb(PIC2_DATA, PIC2_OFFSET); outb(PIC2_DATA, PIC2_OFFSET);
io_wait();
outb(PIC1_DATA, 0x04); outb(PIC1_DATA, 0x04);
io_wait();
outb(PIC2_DATA, 0x02); outb(PIC2_DATA, 0x02);
io_wait();
outb(PIC1_DATA, ICW4_8086); outb(PIC1_DATA, ICW4_8086);
io_wait();
outb(PIC2_DATA, ICW4_8086); outb(PIC2_DATA, ICW4_8086);
io_wait();
} }
void irq_install(void) void irq_install(void)

View File

@ -30,7 +30,6 @@ IRQ 15, 47
irq_common_stub: irq_common_stub:
pusha pusha
push %ds push %ds
push %es push %es
push %fs push %fs

13
isr.c
View File

@ -139,23 +139,20 @@ static const char *exception_messages[] =
void fault_handler(Stack *registers) void fault_handler(Stack *registers)
{ {
// check this
if (registers->id == 128) if (registers->id == 128)
{
isr_call_handler(registers); isr_call_handler(registers);
}
if (registers->id < 32) if (registers->id < 32)
{ {
terminal_printc("Exception. System Halted!\n");
const char *message = exception_messages[registers->id];
while (*message)
{
terminal_putchar(*message);
message++;
}
isr_call_handler(registers); isr_call_handler(registers);
for (;;) for (;;)
{
sys_halt(); sys_halt();
}
} }
} }

85
isr_e.s
View File

@ -1,85 +0,0 @@
.section .text
.align 4
.macro ISR_NO_ERR index
.global isr\index
isr\index:
cli
push $0
push $\index
jmp isr_common_stub
.endm
.macro ISR_ERR index
.global isr\index
isr\index:
cli
push $\index
jmp isr_common_stub
.endm
ISR_NO_ERR 0 # Division By Zero Exception
ISR_NO_ERR 1 # Debug Exception
ISR_NO_ERR 2 # Non Maskable Interrupt Exception
ISR_NO_ERR 3 # Breakpoint Exception
ISR_NO_ERR 4 # Into Detected Overflow Exception
ISR_NO_ERR 5 # Out of Bounds Exception
ISR_NO_ERR 6 # Invalid Opcode Exception
ISR_NO_ERR 7 # No Coprocessor Exception
ISR_ERR 8 # Double Fault Exception
ISR_NO_ERR 9 # Coprocessor Segment Overrun Exception
ISR_ERR 10 # Bad TSS Exception
ISR_ERR 11 # Segment Not Present Exception
ISR_ERR 12 # Stack Fault Exception
ISR_ERR 13 # General Protection Fault Exception
ISR_ERR 14 # Page Fault Exception
ISR_NO_ERR 15 # Unknown Interrupt Exception
ISR_NO_ERR 16 # Coprocessor Fault Exception
ISR_NO_ERR 17 # Alignment Check Exception
ISR_NO_ERR 18 # Machine Check Exception
ISR_NO_ERR 19 # Other
ISR_NO_ERR 20
ISR_NO_ERR 21
ISR_NO_ERR 22
ISR_NO_ERR 23
ISR_NO_ERR 24
ISR_NO_ERR 25
ISR_NO_ERR 26
ISR_NO_ERR 27
ISR_NO_ERR 28
ISR_NO_ERR 29
ISR_NO_ERR 30
ISR_NO_ERR 31
ISR_NO_ERR 128 # Syscal
isr_common_stub:
pusha
push %ds
push %es
push %fs
push %gs
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %esp, %eax
push %eax
mov $fault_handler, %eax
call *%eax
pop %eax
pop %gs
pop %fs
pop %es
pop %ds
popa
add $8, %esp
iret

102
isr_flush.s Normal file
View File

@ -0,0 +1,102 @@
.section .text
.align 4
.macro ISR_NO_ERR index
.global isr\index
isr\index:
cli
push $0
push $\index
jmp isr_common_stub
.endm
.macro ISR_ERR index
.global isr\index
isr\index:
cli
push $\index
jmp isr_common_stub
.endm
/* Division By Zero Exception */
ISR_NO_ERR 0
/* Debug Exception */
ISR_NO_ERR 1
/* Non Maskable Interrupt Exception */
ISR_NO_ERR 2
/* Breakpoint Exception */
ISR_NO_ERR 3
/* Into Detected Overflow Exception */
ISR_NO_ERR 4
/* Out of Bounds Exception */
ISR_NO_ERR 5
/* Invalid Opcode Exception */
ISR_NO_ERR 6
/* No Coprocessor Exception */
ISR_NO_ERR 7
/* Double Fault Exception */
ISR_ERR 8
/* Coprocessor Segment Overrun Exception */
ISR_NO_ERR 9
/* Bad TSS Exception */
ISR_ERR 10
/* Segment Not Present Exception */
ISR_ERR 11
/* Stack Fault Exception */
ISR_ERR 12
/* General Protection Fault Exception */
ISR_ERR 13
/* Page Fault Exception */
ISR_ERR 14
/* Unknown Interrupt Exception */
ISR_NO_ERR 15
/* Coprocessor Fault Exception */
ISR_NO_ERR 16
/* Alignment Check Exception */
ISR_NO_ERR 17
/* Machine Check Exception */
ISR_NO_ERR 18
/* All the others are reserved */
ISR_NO_ERR 19
ISR_NO_ERR 20
ISR_NO_ERR 21
ISR_NO_ERR 22
ISR_NO_ERR 23
ISR_NO_ERR 24
ISR_NO_ERR 25
ISR_NO_ERR 26
ISR_NO_ERR 27
ISR_NO_ERR 28
ISR_NO_ERR 29
ISR_NO_ERR 30
ISR_NO_ERR 31
/* Syscall */
ISR_NO_ERR 128
isr_common_stub:
pusha
push %ds
push %es
push %fs
push %gs
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %esp, %eax
push %eax
mov $fault_handler, %eax
call *%eax
pop %eax
pop %gs
pop %fs
pop %es
pop %ds
popa
add $8, %esp
iret

View File

@ -22,10 +22,9 @@ void kernel_main(void)
irq_install(); irq_install();
timer_install(); timer_install();
keyboard_install(); keyboard_install();
terminal_printc("Welcome to &cDeadOS&7.\n"); syscall_init();
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
terminal_printc("&cDead &7"); terminal_printc("&cDead &7");
@ -34,9 +33,22 @@ void kernel_main(void)
terminal_printc("\n"); terminal_printc("\n");
delay(100); delay(100);
} }
syscall_init();
enter_user_space(); enter_user_space_v2();
}
void user_main(void)
{
terminal_printc("Welcome to &cDeadOS&7.\n");
for (int i = 0; i < 3; i++)
{
terminal_printc("&cDead2 &7");
terminal_putchar('0' + (i / 10));
terminal_putchar('0' + (i % 10));
terminal_printc("\n");
delay(100);
}
shell_init(); shell_init();
} }

View File

@ -1,24 +1,43 @@
/* The bootloader will look at this image and start execution at the symbol
designated at the entry point. */
ENTRY(_start) ENTRY(_start)
/* Tell where the various sections of the object files will be put in the final
kernel image. */
SECTIONS SECTIONS
{ {
. = 1M; /* The kernel is situated at 1 MiB */
. = 1M;
.text ALIGN(4K) : kernel_start = .;
{
*(.multiboot)
*(.text)
*(.rodata)
}
.data ALIGN(4K) : /* First put the multiboot header, as it is required to be put very early
{ early in the image or the bootloader won't recognize the file format.
*(.data) Next we'll put the .text section. */
} .text BLOCK(4K) : ALIGN(4K)
{
*(.multiboot)
*(.text)
}
.bss ALIGN(4K) : /* Read-only data */
{ .rodata BLOCK(4K) : ALIGN(4K)
*(.bss) {
*(COMMON) *(.rodata)
} }
/* Read-write data (initialized) */
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
}
/* Read-write data (uninitialized) and stack */
.bss BLOCK(4K) : ALIGN(4K)
{
*(.bss)
*(.stack)
}
kernel_end = .;
} }

View File

@ -21,8 +21,6 @@ void *syscalls[NB_SYSCALL] = {
void syscall_handler(Stack *registers) void syscall_handler(Stack *registers)
{ {
terminal_writestring("Syscall\n");
int sys_index = registers->eax; int sys_index = registers->eax;
if (sys_index >= NB_SYSCALL) if (sys_index >= NB_SYSCALL)

41
timer.c
View File

@ -1,48 +1,20 @@
#include "timer.h" #include "timer.h"
#include "io.h" #include "io.h"
#include "sys.h" #include "sys.h"
#include "idt.h" #include "interrupts.h"
#define PIT_FREQUENCY 1193182
#define PIT_CHANNEL_0 0x40
#define PIT_COMMAND 0x43
volatile uint32_t tick = 0; volatile uint32_t tick = 0;
void pit_handler() void pit_handler(Stack *registers)
{ {
tick++; ++tick;
outb(0x20, 0x20);
}
void pic_remap(int offset1, int offset2)
{
unsigned char a1, a2;
a1 = inb(0x21);
a2 = inb(0xA1);
outb(0x20, 0x11);
outb(0xA0, 0x11);
outb(0x21, offset1);
outb(0xA1, offset2);
outb(0x21, 0x04);
outb(0xA1, 0x02);
outb(0x21, 0x01);
outb(0xA1, 0x01);
outb(0x21, a1);
outb(0xA1, a2);
} }
void delay(uint32_t milliseconds) void delay(uint32_t milliseconds)
{ {
uint32_t end = tick + milliseconds; uint32_t end = tick + milliseconds;
while (tick < end) while (tick < end)
{ ;
sys_halt();
}
} }
void pit_set_frequency(uint32_t frequency) void pit_set_frequency(uint32_t frequency)
@ -50,12 +22,11 @@ void pit_set_frequency(uint32_t frequency)
uint32_t divisor = PIT_FREQUENCY / frequency; uint32_t divisor = PIT_FREQUENCY / frequency;
outb(PIT_COMMAND, 0x36); outb(PIT_COMMAND, 0x36);
outb(PIT_CHANNEL_0, divisor & 0xFF); outb(PIT_CHANNEL_0, divisor & 0xFF);
outb(PIT_CHANNEL_0, (divisor >> 8) & 0xFF); outb(PIT_CHANNEL_0, divisor >> 8);
} }
void timer_install(void) void timer_install(void)
{ {
pic_remap(0x20, 0x28); irq_install_handler(0, pit_handler);
pit_set_frequency(1000); pit_set_frequency(1000);
idt_set_gate(32, (uint32_t)pit_handler_asm, 0x08, 0x8E);
} }

View File

@ -3,12 +3,16 @@
#include <stdint.h> #include <stdint.h>
extern void pit_handler_asm(); #define PIT_FREQUENCY 1193182
#define PIT_CHANNEL_0 0x40
#define PIT_COMMAND 0x43
extern void pit_handler_asm(); // defined in pit_handler.s remove this
void pit_handler(); void pit_handler();
void delay(uint32_t milliseconds); void delay(uint32_t milliseconds);
void pit_set_frequency(uint32_t frequency); void pit_set_frequency(uint32_t frequency);
void pic_remap(int offset1, int offset2); void pic_remap(int offset1, int offset2); // moved to irq_remap
void timer_install(void); void timer_install(void);
#endif #endif

View File

82
tty.c
View File

@ -4,6 +4,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdarg.h>
#include "string.h" #include "string.h"
static const size_t VGA_WIDTH = 80; static const size_t VGA_WIDTH = 80;
@ -138,6 +139,7 @@ void terminal_writestring(const char *data)
terminal_write(data, strlen(data)); terminal_write(data, strlen(data));
} }
// Існуюча функція для виводу одного рядка
void terminal_printc(const char *data) void terminal_printc(const char *data)
{ {
while (*data) while (*data)
@ -156,6 +158,86 @@ void terminal_printc(const char *data)
} }
} }
void itoa(int value, char *str, int base)
{
char *rc;
char *ptr;
char *low;
if (value < 0 && base == 10)
{
*str++ = '-';
value = -value;
}
rc = ptr = str;
do
{
*ptr++ = "0123456789abcdef"[value % base];
value /= base;
} while (value);
*ptr-- = '\0';
for (low = rc; low < ptr; low++, ptr--)
{
char tmp = *low;
*low = *ptr;
*ptr = tmp;
}
}
void terminal_printf_int(int value)
{
char buffer[12];
itoa(value, buffer, 10);
terminal_printf(buffer);
}
void terminal_printf_hex(unsigned int value)
{
char buffer[12];
itoa(value, buffer, 16);
terminal_printf(buffer);
}
void terminal_printf(const char *format, ...)
{
va_list args;
va_start(args, format);
const char *p = format;
while (*p)
{
if (*p == '%' && (*(p + 1) == 's' || *(p + 1) == 'd' || *(p + 1) == 'x'))
{
p++;
if (*p == 's')
{
const char *str = va_arg(args, const char *);
terminal_printc(str);
}
else if (*p == 'd')
{
int value = va_arg(args, int);
terminal_printf_int(value);
}
else if (*p == 'x')
{
unsigned int value = va_arg(args, unsigned int);
terminal_printf_hex(value);
}
}
else
{
terminal_putchar(*p);
}
p++;
}
va_end(args);
}
void terminal_update_cursor(void) void terminal_update_cursor(void)
{ {
uint16_t pos = terminal_row * VGA_WIDTH + terminal_column; uint16_t pos = terminal_row * VGA_WIDTH + terminal_column;

1
tty.h
View File

@ -10,6 +10,7 @@ void terminal_putentryat(char c, uint8_t color, size_t x, size_t y);
void terminal_putchar(char c); void terminal_putchar(char c);
void terminal_write(const char *data, size_t size); void terminal_write(const char *data, size_t size);
void terminal_writestring(const char *data); void terminal_writestring(const char *data);
void terminal_printf(const char *data, ...);
void terminal_printc(const char *data); void terminal_printc(const char *data);
void terminal_update_cursor(void); void terminal_update_cursor(void);
void terminal_clear(void); void terminal_clear(void);

View File

@ -1,9 +1,5 @@
#include "user_space.h"
#include "gdt.h"
void enter_user_space(void) void enter_user_space(void)
{ {
set_kernel_stack(0x110); // 128KB ?? WHY? ??
asm volatile("cli; \ asm volatile("cli; \
mov $0x23, %ax; \ mov $0x23, %ax; \
mov %ax, %ds; \ mov %ax, %ds; \
@ -23,3 +19,26 @@ void enter_user_space(void)
1: \ 1: \
"); ");
} }
void enter_user_space_v2()
{
asm volatile("cli; \
mov $0x23, %ax; \
mov %ax, %ds; \
mov %ax, %es; \
mov %ax, %fs; \
mov %ax, %gs; \
mov %esp, %eax; \
push $0x23; \
push %eax; \
pushf; \
pop %eax; \
or $0x200, %eax; \
push %eax; \
push $0x1B; \
push $user_code_entry; \
iret; \
user_code_entry: \
call user_main; \
");
}

View File

@ -2,5 +2,6 @@
#define _USER_SPACE_H #define _USER_SPACE_H
void enter_user_space(void); void enter_user_space(void);
void enter_user_space_v2(void);
#endif #endif