Fix bug in terminal.cpp where it would use incorrect pointers in scroll_up, removed old debug code from kmain.cpp, kernel.cpp no longer appends itself to the process list, update process.cpp to take a filename when constructing a new process. Update idt.cpp to plug context_switch in to int 0x20 (IRQ0)

This commit is contained in:
Xnoe 2021-11-27 13:11:44 +00:00
parent bfa648d96b
commit d6c1cc1869
Signed by: xnoe
GPG Key ID: 45AC398F44F0DAFE
8 changed files with 39 additions and 94 deletions

View File

@ -2,13 +2,16 @@ CFLAGS = -g -std=gnu11 -m32 -mgeneral-regs-only -nostdlib -fno-builtin -fno-exce
CXXFLAGS = -g -m32 -fno-use-cxa-atexit -mgeneral-regs-only -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -fpermissive -fno-pie -fno-stack-protector -I. CXXFLAGS = -g -m32 -fno-use-cxa-atexit -mgeneral-regs-only -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -fpermissive -fno-pie -fno-stack-protector -I.
LDFLAGS = LDFLAGS =
DISK_IMG_FILES = build/kernel/kernel.bin build/program/program.bin hello.txt alpha.txt DISK_IMG_FILES = build/kernel/kernel.bin build/program/program.bin build/program/hello.bin \
build/program/world.bin hello.txt alpha.txt
KERNEL_OBJS = build/kernel/entry.o build/kernel/screenstuff.o build/kernel/io.o build/kernel/idt.o build/kernel/keyboard.o \ KERNEL_OBJS = build/kernel/entry.o build/kernel/screenstuff.o build/kernel/io.o build/kernel/idt.o build/kernel/keyboard.o \
build/kernel/strings.o build/kernel/atapio.o build/kernel/kmain.o build/kernel/paging.o build/kernel/allocate.o \ build/kernel/strings.o build/kernel/atapio.o build/kernel/kmain.o build/kernel/paging.o build/kernel/allocate.o \
build/kernel/gdt.o build/kernel/memory.o build/kernel/process.o build/kernel/datatypes/hash.o \ build/kernel/gdt.o build/kernel/memory.o build/kernel/process.o build/kernel/datatypes/hash.o \
build/kernel/terminal.o build/kernel/global.o build/kernel/kernel.o build/kernel/terminal.o build/kernel/global.o build/kernel/kernel.o
STAGE2_OBJS = build/c_code_entry.o build/boot_stage2/io.o build/boot_stage2/atapio.o build/boot_stage2/strings.o build/boot_stage2/screenstuff.o build/boot_stage2/stage2.o build/boot_stage2/paging.o STAGE2_OBJS = build/c_code_entry.o build/boot_stage2/io.o build/boot_stage2/atapio.o build/boot_stage2/strings.o build/boot_stage2/screenstuff.o build/boot_stage2/stage2.o build/boot_stage2/paging.o
PROGRAM_OBJS = build/program_code_entry.o build/program/program.o PROGRAM_OBJS = build/program_code_entry.o build/program/program.o build/common/common.o
HELLO_OBJS = build/program_code_entry.o build/program/hello.o build/common/common.o
WORLD_OBJS = build/program_code_entry.o build/program/world.o build/common/common.o
run: disk.img run: disk.img
qemu-system-x86_64 disk.img qemu-system-x86_64 disk.img
@ -32,6 +35,7 @@ prepare:
mkdir -p build/kernel mkdir -p build/kernel
mkdir -p build/kernel/datatypes mkdir -p build/kernel/datatypes
mkdir -p build/program mkdir -p build/program
mkdir -p build/common
mountpoint img.d | grep not || umount img.d mountpoint img.d | grep not || umount img.d
clean: clean:
@ -70,3 +74,9 @@ build/%.o: src/%.asm
build/program/program.bin: src/program/program.ld $(PROGRAM_OBJS) build/program/program.bin: src/program/program.ld $(PROGRAM_OBJS)
ld $(LDFLAGS) -T $< $(PROGRAM_OBJS) ld $(LDFLAGS) -T $< $(PROGRAM_OBJS)
build/program/hello.bin: src/program/hello.ld $(HELLO_OBJS)
ld $(LDFLAGS) -T $< $(HELLO_OBJS)
build/program/world.bin: src/program/world.ld $(WORLD_OBJS)
ld $(LDFLAGS) -T $< $(WORLD_OBJS)

View File

@ -84,6 +84,8 @@ __attribute__((interrupt)) void context_switch(interrupt_frame* frame) {
asm volatile ("mov %%esp, %0" : "=a" (cESP) :); asm volatile ("mov %%esp, %0" : "=a" (cESP) :);
currentProc->esp = cESP; // Store the current ESP of the current process process. currentProc->esp = cESP; // Store the current ESP of the current process process.
outb(0x20, 0x20);
// Select the next processes page directory // Select the next processes page directory
asm volatile ("mov %0, %%cr3" : : "r" (nextProc->PD->phys_addr)); asm volatile ("mov %0, %%cr3" : : "r" (nextProc->PD->phys_addr));
// Restore ESP of the new process. // Restore ESP of the new process.
@ -92,14 +94,11 @@ __attribute__((interrupt)) void context_switch(interrupt_frame* frame) {
asm ("popa"); asm ("popa");
// Clear the garbage that was on the stack from previous switch_context call. // Clear the garbage that was on the stack from previous switch_context call.
asm ("add $44, %esp"); asm ("add $84, %esp");
// Pop EBP // Pop EBP
asm ("pop %ebp"); asm ("pop %ebp");
// Re-enable interrupts.
asm ("sti");
// Manually perform iret. // Manually perform iret.
asm ("iret"); asm ("iret");
} }
@ -152,10 +151,7 @@ __attribute__((interrupt)) void syscall(interrupt_frame* frame) {
rval = file_size(esi); rval = file_size(esi);
break; break;
case 7: { case 7: {
uint32_t size = file_size(esi); Global::kernel->createProcess(esi);
uint8_t* filebuffer = new uint8_t[size];
load_file(esi, filebuffer);
Global::kernel->createProcess();
break; break;
} }
default: default:
@ -174,7 +170,7 @@ void init_idt() {
for (int i=0; i<256; i++) for (int i=0; i<256; i++)
set_entry(i, 0x08, &ignore_interrupt, 0x8E); set_entry(i, 0x08, &ignore_interrupt, 0x8E);
set_entry(0x20, 0x08, &interrupt_20, 0x8E); set_entry(0x20, 0x08, &context_switch, 0x8E);
set_entry(0xD, 0x08, &gpf, 0x8E); set_entry(0xD, 0x08, &gpf, 0x8E);
set_entry(0xE, 0x08, &page_fault, 0x8E); set_entry(0xE, 0x08, &page_fault, 0x8E);
set_entry(0x80, 0x08, &context_switch, 0x8E); set_entry(0x80, 0x08, &context_switch, 0x8E);

View File

@ -9,15 +9,15 @@ Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint
Global::currentProc = 0; Global::currentProc = 0;
this->processes.append(this); //this->processes.append(this);
} }
void Kernel::init_kernel() { void Kernel::init_kernel() {
this->pid_map = new xnoe::hashtable<uint32_t, Process*>(); this->pid_map = new xnoe::hashtable<uint32_t, Process*>();
} }
Process* Kernel::createProcess() { Process* Kernel::createProcess(char* filename) {
Process* p = new Process(currentPID, this->PD, 0xc0000000); Process* p = new Process(currentPID, this->PD, 0xc0000000, filename);
this->pid_map->set(currentPID, p); this->pid_map->set(currentPID, p);
currentPID++; currentPID++;

View File

@ -19,7 +19,7 @@ public:
void init_kernel(); void init_kernel();
Process* createProcess(); Process* createProcess(char* filename);
}; };
#endif #endif

View File

@ -44,79 +44,14 @@ int main() {
term->printf("KERNEL OK!\n"); term->printf("KERNEL OK!\n");
Process* p = kernel.createProcess();
//term->deactivate();
//term2->activate();
Global::currentProc = &kernel; Global::currentProc = &kernel;
asm ("int $0x80");
term->printf("\n\nIf you are reading this, the XnoeOS kernel successfully switched contexts to another process, and then switched contexts back to the kernel. Therefore we can conclude that context switching works."); Process* p1 = kernel.createProcess("WORLD BIN");
Process* p2 = kernel.createProcess("HELLO BIN");
while (1);
init_keyboard(); init_keyboard();
enable_idt(); enable_idt();
uint8_t* filebuffer = new uint8_t[0x3000]; while (1) asm ("hlt");
char* buffer = 0;
while (1) {
if (buffer)
delete[] buffer;
buffer = new char[128];
printf(">>> ");
for (int i=0; i<128; i++)
buffer[i] = 0;
readline(128, buffer);
char* rest = split_on_first(' ', buffer);
if (strcmp(buffer, "help", 4)) {
printf(
"XnoeOS 32 Bit Mode Help.\n"
"------------------------\n"
" - help\n"
" : Shows this message\n"
" - clear\n"
" : Clears the screen\n"
" - echo\n"
" : Repeats the text written afterwards\n"
" - type\n"
" : Prints the contents of a file\n"
);
} else if (strcmp(buffer, "clear", 5)) {
clear_screen();
set_curpos(0, 0);
} else if (strcmp(buffer, "echo", 4)) {
printf("%s\n", rest);
} else if (strcmp(buffer, "type", 4)) {
char filenamebuffer[12];
decode_filename(rest, filenamebuffer);
if (!file_exists(filenamebuffer)) {
printf("File %s not found!\n", filenamebuffer);
continue;
}
for (int i=0; i<4096; i++)
filebuffer[i] = 0;
load_file(filenamebuffer, filebuffer);
printf(filebuffer);
} else if (strcmp(buffer, "pagefault", 9)) {
uint32_t* bad_addr = 0xdeadbeef;
uint32_t a = *bad_addr;
} else {
char filenamebuffer[12];
decode_filename(buffer, filenamebuffer);
if (!file_exists(filenamebuffer)) {
printf("Bad Command or filename!\n");
continue;
}
}
}
} }

View File

@ -30,7 +30,7 @@ Process::Process(uint32_t PID)
this->stack = this->allocate(0x8000); this->stack = this->allocate(0x8000);
} }
Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase) Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, char* filename)
: Allocator(new PageDirectory, new PageMap, 0) { : Allocator(new PageDirectory, new PageMap, 0) {
this->PID = PID; this->PID = PID;
this->page_remaining = 0; this->page_remaining = 0;
@ -45,12 +45,12 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase)
asm ("mov %%cr3, %0" : "=a" (pCR3) :); asm ("mov %%cr3, %0" : "=a" (pCR3) :);
this->PD->select(); this->PD->select();
uint8_t* program_data = this->allocate(file_size("PROGRAM BIN") + 12) + 12; uint8_t* program_data = this->allocate(file_size(filename) + 12) + 12;
// We also need to initialise ESP and the stack // We also need to initialise ESP and the stack
uint32_t* stack32 = ((uint32_t)this->stack + 0x8000); uint32_t* stack32 = ((uint32_t)this->stack + 0x8000);
stack32--; stack32--;
*stack32 = 0x0; // EFLAGS *stack32 = 0x200; // EFLAGS
stack32--; stack32--;
*stack32 = 8; // CS 0x08 *stack32 = 8; // CS 0x08
stack32--; stack32--;
@ -59,7 +59,7 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase)
stack32--; stack32--;
*stack32 = ((uint32_t)this->stack + 0x8000); // EBP *stack32 = ((uint32_t)this->stack + 0x8000); // EBP
stack32 -= 11; stack32 -= 21;
stack32--; stack32--;
*stack32 = 0; // EAX *stack32 = 0; // EAX
@ -80,7 +80,7 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase)
this->esp = stack32; this->esp = stack32;
load_file("PROGRAM BIN", program_data); load_file(filename, program_data);
asm ("mov %0, %%cr3" : : "r" (pCR3)); asm ("mov %0, %%cr3" : : "r" (pCR3));
} }

View File

@ -37,7 +37,7 @@ public:
Process(uint32_t PID, void* stack, PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base); Process(uint32_t PID, void* stack, PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
Process(uint32_t PID); Process(uint32_t PID);
Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase); Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, char* filename);
void* allocate(uint32_t size) override; void* allocate(uint32_t size) override;
void deallocate(uint32_t virt_addr) override; void deallocate(uint32_t virt_addr) override;

View File

@ -3,18 +3,20 @@
void Terminal::scroll_up() { void Terminal::scroll_up() {
// Scroll the entire buffer up. // Scroll the entire buffer up.
for (int y = 0; y < (height * pages); y++) { for (int y = 0; y < (height * pages); y++) {
uint16_t* cline = y * width; uint16_t* cline = buffer + y * width;
uint16_t* nline = (y+1) * width; uint16_t* nline = buffer + (y+1) * width;
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
cline[x] = nline[x]; cline[x] = nline[x];
} }
} }
// Clear the last line // Clear the last line
uint16_t* last_line = (height * pages - 1) * width; uint16_t* last_line = buffer + (height * pages - 1) * width;
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
last_line[x] = 0x0720; last_line[x] = 0x0720;
} }
this->cur_y--; this->cur_y--;
this->update();
} }
void Terminal::putchar(uint32_t ptr, uint8_t c, uint8_t edata) { void Terminal::putchar(uint32_t ptr, uint8_t c, uint8_t edata) {
@ -61,8 +63,10 @@ void Terminal::printf(const char* string, ...) {
this->cur_y++; this->cur_y++;
} }
if (this->cur_y == this->height) if (this->cur_y == this->height) {
this->scroll_up(); this->scroll_up();
printf("This gets called...");
}
if (current == '%') { if (current == '%') {
int type = string[index++]; int type = string[index++];