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.
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 \
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/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
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
qemu-system-x86_64 disk.img
@ -32,6 +35,7 @@ prepare:
mkdir -p build/kernel
mkdir -p build/kernel/datatypes
mkdir -p build/program
mkdir -p build/common
mountpoint img.d | grep not || umount img.d
clean:
@ -69,4 +73,10 @@ build/%.o: src/%.asm
# Program
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) :);
currentProc->esp = cESP; // Store the current ESP of the current process process.
outb(0x20, 0x20);
// Select the next processes page directory
asm volatile ("mov %0, %%cr3" : : "r" (nextProc->PD->phys_addr));
// Restore ESP of the new process.
@ -92,14 +94,11 @@ __attribute__((interrupt)) void context_switch(interrupt_frame* frame) {
asm ("popa");
// Clear the garbage that was on the stack from previous switch_context call.
asm ("add $44, %esp");
asm ("add $84, %esp");
// Pop EBP
asm ("pop %ebp");
// Re-enable interrupts.
asm ("sti");
// Manually perform iret.
asm ("iret");
}
@ -152,10 +151,7 @@ __attribute__((interrupt)) void syscall(interrupt_frame* frame) {
rval = file_size(esi);
break;
case 7: {
uint32_t size = file_size(esi);
uint8_t* filebuffer = new uint8_t[size];
load_file(esi, filebuffer);
Global::kernel->createProcess();
Global::kernel->createProcess(esi);
break;
}
default:
@ -174,7 +170,7 @@ void init_idt() {
for (int i=0; i<256; i++)
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(0xE, 0x08, &page_fault, 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;
this->processes.append(this);
//this->processes.append(this);
}
void Kernel::init_kernel() {
this->pid_map = new xnoe::hashtable<uint32_t, Process*>();
}
Process* Kernel::createProcess() {
Process* p = new Process(currentPID, this->PD, 0xc0000000);
Process* Kernel::createProcess(char* filename) {
Process* p = new Process(currentPID, this->PD, 0xc0000000, filename);
this->pid_map->set(currentPID, p);
currentPID++;

View File

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

View File

@ -44,79 +44,14 @@ int main() {
term->printf("KERNEL OK!\n");
Process* p = kernel.createProcess();
//term->deactivate();
//term2->activate();
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.");
while (1);
Process* p1 = kernel.createProcess("WORLD BIN");
Process* p2 = kernel.createProcess("HELLO BIN");
init_keyboard();
enable_idt();
uint8_t* filebuffer = new uint8_t[0x3000];
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;
}
}
}
while (1) asm ("hlt");
}

View File

@ -30,7 +30,7 @@ Process::Process(uint32_t PID)
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) {
this->PID = PID;
this->page_remaining = 0;
@ -45,12 +45,12 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase)
asm ("mov %%cr3, %0" : "=a" (pCR3) :);
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
uint32_t* stack32 = ((uint32_t)this->stack + 0x8000);
stack32--;
*stack32 = 0x0; // EFLAGS
*stack32 = 0x200; // EFLAGS
stack32--;
*stack32 = 8; // CS 0x08
stack32--;
@ -59,7 +59,7 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase)
stack32--;
*stack32 = ((uint32_t)this->stack + 0x8000); // EBP
stack32 -= 11;
stack32 -= 21;
stack32--;
*stack32 = 0; // EAX
@ -80,7 +80,7 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase)
this->esp = stack32;
load_file("PROGRAM BIN", program_data);
load_file(filename, program_data);
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);
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 deallocate(uint32_t virt_addr) override;

View File

@ -3,18 +3,20 @@
void Terminal::scroll_up() {
// Scroll the entire buffer up.
for (int y = 0; y < (height * pages); y++) {
uint16_t* cline = y * width;
uint16_t* nline = (y+1) * width;
uint16_t* cline = buffer + y * width;
uint16_t* nline = buffer + (y+1) * width;
for (int x = 0; x < width; x++) {
cline[x] = nline[x];
}
}
// 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++) {
last_line[x] = 0x0720;
}
this->cur_y--;
this->update();
}
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++;
}
if (this->cur_y == this->height)
if (this->cur_y == this->height) {
this->scroll_up();
printf("This gets called...");
}
if (current == '%') {
int type = string[index++];