Mon, 27 Mar 2023 21:16:22 +0200
11 files changed,
120 insertions(+),
59 deletions(-)
M
run.sh
→
run.sh
@@ -1,1 +1,1 @@
-qemu-system-i386 -drive index=0,if=floppy,format=raw,file=./build/release/cedos.img -m 64 -monitor stdio -no-reboot -d int,cpu_reset,exec,in_asm -vnc :0 2> log/run_err.log+qemu-system-i386 -drive index=0,if=floppy,format=raw,file=./build/release/cedos.img -m 64 -monitor stdio -no-reboot -d int,cpu_reset,exec,in_asm -vnc :0 2> log/run_err.log
M
src/boot/entry.s
→
src/boot/entry.s
@@ -158,13 +158,13 @@ or $0x00000001, %eax
mov %eax, %cr0 # perform long jump to set code segment - ljmp $0x8, $protected + ljmp $0x18, $protected .code32 protected: # setup registers with appropriate GDT values - mov $0x10, %eax + mov $0x20, %eax mov %eax, %ds mov %eax, %es mov %eax, %fs@@ -186,7 +186,7 @@ or $0x80000010, %eax
movl %eax, %cr0 # jump to kernel code - ljmp $8, $0xC0000000 + ljmp $0x18, $0xC0000000 # loop until the heat death of the universe loop:@@ -227,7 +227,7 @@ .byte 10
.byte 0 GDT_DESCRIPTOR: - .word 0x23 + .word 0x39 .int GDT IDT_DESCRIPTOR:
M
src/boot/gdt.c
→
src/boot/gdt.c
@@ -11,9 +11,15 @@ (uint8_t)(((limit >> 16) & 0x0F) | ((flags << 4) & 0xF0)), \
(uint8_t)(base >> 24) \ } -GDT_ENTRY GDT[5] = { +GDT_ENTRY GDT[7] = { // null descriptor GDT_MAKE_ENTRY(0x00000000, 0x00000000, 0x00, 0x0), + + // 16 bit code descriptor + GDT_MAKE_ENTRY(0x00000000, 0x0000FFFF, 0x9A, 0x8), + + // 16 bit data descriptor + GDT_MAKE_ENTRY(0x00000000, 0x0000FFFF, 0x92, 0x8), // identity mapping (code, ring 0) GDT_MAKE_ENTRY(0x00000000, 0x000FFFFF, 0x9A, 0xC),
M
src/boot/gdt.h
→
src/boot/gdt.h
@@ -38,6 +38,6 @@
/*! * The GDT. */ -GDT_ENTRY GDT[5]; +GDT_ENTRY GDT[7]; #endif
M
src/kernel/drivers/ps2_keyboard.c
→
src/kernel/drivers/ps2_keyboard.c
@@ -95,7 +95,7 @@ outb(PS2_WRTE_CONF, PS2_COMMAND);
nop(); nop(); nop(); nop(); outb(conf, PS2_DATA); - install_interrupt(PIC1_IRQ(0x01), keyboard_int_handler, 0x08, INT_GATE); + install_interrupt(PIC1_IRQ(0x01), keyboard_int_handler, 0x18, INT_GATE); pic_unmask_interrupt(0x01);
M
src/kernel/graphics.s
→
src/kernel/graphics.s
@@ -1,18 +1,13 @@
.section .text.realmode .global realmode_int10h +.code32 realmode_int10h: push %ebp mov %esp, %ebp + + cli pusha - - push %ds - push %es - push %fs - push %ss - - mov %cr3, %eax - push %eax mov %esp, %eax mov %eax, %esi@@ -28,58 +23,116 @@
push %esi push %edi + mov +16(%edi), %eax + push %eax + mov +12(%edi), %eax + push %eax + mov +8(%edi), %eax + push %eax + + push %ebp + mov %esp, %ebp + # disable paging + mov %cr3, %eax + push %eax + + mov %cr0, %eax + and $0x3FFFFFFD, %eax + mov %eax, %cr0 + xor %eax, %eax mov %eax, %cr3 - # switch to realmode temporarily + # switch to 16 bit protected mode + ljmp $0x8, $pmode16 + +.code16 +pmode16: + # setup segments + movw $0x10, %ax + movw %ax, %ss + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + + # load real mode interrupt descriptor table + sidt (pmode_IDT) + lidt (realmode_IDT) + + # switch to real mode mov %cr0, %eax - and $0x3FFFFFFC, %eax + and $0xFFFFFFFE, %eax mov %eax, %cr0 - # perform long jump to set code segment ljmp $0, $realmode -return_pmode: +realmode: + # setup segments + movw $0x0000, %ax + movw %ax, %ss + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + + sti + + # load arguments + movw +4(%bp), %ax + movw +8(%bp), %bx + movw +12(%bp), %cx + + int $0x10 + + cli + + lidt (pmode_IDT) + + mov %cr0, %eax + or $0x00000001, %eax + mov %eax, %cr0 + + ljmp $0x18, $pmode32 + +.code32 +pmode32: # set data segments - movw $0x10, %ax + movw $0x20, %ax movw %ax, %ss movw %ax, %ds movw %ax, %es movw %ax, %fs - # restore stack + # restore paging + pop %eax + mov %eax, %cr3 + + mov %cr0, %eax + or $0x80000010, %eax + mov %eax, %cr0 + + # clean up argument buffer + pop %ebp + add $12, %esp + + # restore original stack pop %ebp pop %eax mov %eax, %esp - # restore original segments and registers - pop %eax - mov %eax, %cr3 - - pop %ss - pop %fs - pop %es - pop %ds + popa - popa + sti # return pop %ebp + ret -.code16 -realmode: - # setup real mode segments - movw $0x0000, %ax - movw %ax, %ss - movw %ax, %ds - movw %ax, %es - movw %ax, %fs +realmode_IDT: + .word 0x3FF + .int 0 - # perform the actual interrupt +pmode_IDT: + .word 0 + .int 0 - mov %cr0, %eax - and $0x00000001, %eax - mov %eax, %cr0 - - ljmp $0x8, $return_pmode
M
src/kernel/interrupts.c
→
src/kernel/interrupts.c
@@ -65,17 +65,17 @@
int interrupts_init(void) { for (uint32_t i = 0; i < INTERRUPT_COUNT; i++) { if (i == 0x03) { - install_interrupt(i, breakpoint_isr, 0x08, INT_GATE); + install_interrupt(i, breakpoint_isr, 0x18, INT_GATE); } else if (i == 0x08) { - install_interrupt(i, double_fault_isr, 0x08, INT_GATE); + install_interrupt(i, double_fault_isr, 0x18, INT_GATE); } else if (i == 0x0d) { - install_interrupt(i, gpf_isr, 0x08, INT_GATE); + install_interrupt(i, gpf_isr, 0x18, INT_GATE); } else if (i >= 0x21 || i < 0x28) { - install_interrupt(i, pic1_handler, 0x08, INT_GATE); + install_interrupt(i, pic1_handler, 0x18, INT_GATE); } else if (i >= 0x28 || i < 0x30) { - install_interrupt(i, pic2_handler, 0x08, INT_GATE); + install_interrupt(i, pic2_handler, 0x18, INT_GATE); } else { - install_interrupt(i, default_isr, 0x08, INT_GATE); + install_interrupt(i, default_isr, 0x18, INT_GATE); } }
M
src/kernel/main.c
→
src/kernel/main.c
@@ -26,7 +26,7 @@ #else
#define PRINT_DBG(...) {} #endif -extern void realmode_int10h(uint32_t mode); +extern void realmode_int10h(uint32_t eax, uint32_t ebx, uint32_t ecx); int os_init(void) { core_init();@@ -68,9 +68,11 @@ printk("Initializing root file system...");
FAT_init(); printk("done."); - printk("Testing realmode graphics switch..."); - realmode_int10h(0x0D); - printk("done.\n");*/ + while (1) { + graph[i++] = (i & 0x0F); + + if (i > 320 * 240) { i = 0; } + } printk("Initialization finished.\n--------------\n");
M
src/kernel/mm/paging.c
→
src/kernel/mm/paging.c
@@ -209,5 +209,5 @@ // dump registers to stdout
} int paging_init(void) { - install_interrupt(0x0e, page_fault_isr, 0x08, TRAP_GATE); + install_interrupt(0x0e, page_fault_isr, 0x18, TRAP_GATE); }
M
src/kernel/sched/sched.c
→
src/kernel/sched/sched.c
@@ -87,7 +87,7 @@ frame.esi = frame.edi = 0;
frame.ebp = p->ebp; frame.esp = p->esp; frame.eflags = p->eflags; - frame.cs = 0x8; + frame.cs = 0x18; if (name == NULL) { frame.eip = entry_idle;@@ -179,7 +179,7 @@ extern void* sched_interrupt;
int sched_init(void) { // install scheduler interrupt - install_interrupt(PIC1_IRQ(0x00), &sched_interrupt, 0x08, INT_GATE); + install_interrupt(PIC1_IRQ(0x00), &sched_interrupt, 0x18, INT_GATE); current_pid = 0;
M
src/kernel/syscall.c
→
src/kernel/syscall.c
@@ -27,6 +27,6 @@ /*!
* Installs the syscall interrupt to INT 0x30 */ int syscall_init(void) { - install_interrupt(0x30, &syscall_interrupt, 0x08, INT_GATE); + install_interrupt(0x30, &syscall_interrupt, 0x18, INT_GATE); return 1; }