Updated the KernelInformationStruct, added BGA (Bochs Graphics Extensions) mode termimal, added new system calls to get terminal width. Updated world.bin to calculate sizes. Fixed a bug where GetExhaustive would crash when given a completely null path. Started work on V86 for VBE support.
This commit is contained in:
parent
6339b3e4bd
commit
da5fc52afe
4
Makefile
4
Makefile
@ -1,5 +1,5 @@
|
|||||||
CFLAGS = -g -std=gnu11 -m32 -mgeneral-regs-only -nostdlib -fno-builtin -fno-exceptions -fno-leading-underscore -fno-pie -fno-stack-protector -Wno-pointer-to-int-cast -Isrc/
|
CFLAGS = -g -w -std=gnu11 -m32 -mgeneral-regs-only -nostdlib -fno-builtin -fno-exceptions -fno-leading-underscore -fno-pie -fno-stack-protector -Wno-pointer-to-int-cast -Isrc/
|
||||||
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 -Isrc/
|
CXXFLAGS = -g -w -m32 -fno-use-cxa-atexit -mgeneral-regs-only -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -fpermissive -fno-pie -fno-stack-protector -Isrc/
|
||||||
LDFLAGS =
|
LDFLAGS =
|
||||||
|
|
||||||
DISK_IMG_FILES = build/kernel/kernel.bin hello.txt alpha.txt
|
DISK_IMG_FILES = build/kernel/kernel.bin hello.txt alpha.txt
|
||||||
|
@ -50,7 +50,7 @@ bootcode:
|
|||||||
|
|
||||||
mov ax, 2 ; Begin with the 2nd sector
|
mov ax, 2 ; Begin with the 2nd sector
|
||||||
call prep_i13
|
call prep_i13
|
||||||
mov al, 31 ; Load the next 9 sectors (4.5k)
|
mov al, 31 ; Load the next 31 sectors (15.5kb)
|
||||||
int 13h
|
int 13h
|
||||||
|
|
||||||
; We need to get the memory configuration from the BIOS now
|
; We need to get the memory configuration from the BIOS now
|
||||||
|
@ -146,7 +146,7 @@ void main() {
|
|||||||
|
|
||||||
map_many_4k_phys_to_virt(0xa0000, 0xc07a0000, kernel_page_directory, kernel_page_tables, 0x20); // Map 32 pages from 0xa0000 to 0xa0000
|
map_many_4k_phys_to_virt(0xa0000, 0xc07a0000, kernel_page_directory, kernel_page_tables, 0x20); // Map 32 pages from 0xa0000 to 0xa0000
|
||||||
mark_unavailble(0xa0000, 0x20000, bitmap);
|
mark_unavailble(0xa0000, 0x20000, bitmap);
|
||||||
|
|
||||||
|
|
||||||
uint8_t* vm_bitmap = 0x522000;
|
uint8_t* vm_bitmap = 0x522000;
|
||||||
mark_unavailble(vm_bitmap, 0x20000, bitmap);
|
mark_unavailble(vm_bitmap, 0x20000, bitmap);
|
||||||
@ -173,18 +173,22 @@ void main() {
|
|||||||
map_many_4k_phys_to_virt(0x8a000, 0xc1000000, kernel_page_directory, kernel_page_tables, 16);
|
map_many_4k_phys_to_virt(0x8a000, 0xc1000000, kernel_page_directory, kernel_page_tables, 16);
|
||||||
mark_unavailble(0x8a000, 0x10000, bitmap);
|
mark_unavailble(0x8a000, 0x10000, bitmap);
|
||||||
|
|
||||||
load_file("KERNEL BIN", kernel_location);
|
// Identity map the first 1MiB of RAM
|
||||||
|
mark_unavailble(0, 0x100000, bitmap);
|
||||||
|
mark_unavailble(0, 0x100000, vm_bitmap);
|
||||||
|
map_many_4k_phys_to_virt_pl3(0, 0, kernel_page_directory, kernel_page_tables, 256);
|
||||||
|
|
||||||
//while (1);
|
load_file("KERNEL BIN", kernel_location);
|
||||||
|
|
||||||
asm volatile("mov %0, %%eax;"
|
asm volatile("mov %0, %%eax;"
|
||||||
"mov %%eax, %%cr3;"
|
"mov %%eax, %%cr3;"
|
||||||
"mov %%cr0, %%eax;"
|
"mov %%cr0, %%eax;"
|
||||||
"or $0x80000000, %%eax;"
|
"or $0x80000000, %%eax;"
|
||||||
"mov %%eax, %%cr0" : : "m" (kernel_page_directory));
|
"mov %%eax, %%cr0" : : "m" (kernel_page_directory));
|
||||||
|
|
||||||
|
asm volatile ("mov %0, %%esp":: "r"(0xc1000000 + 16*0x1000));
|
||||||
|
|
||||||
KernelInformationStruct* kstruct = 0xc1000000 + 16*0x1000 - sizeof(KernelInformationStruct);
|
KernelInformationStruct kstruct= (KernelInformationStruct){
|
||||||
*kstruct = (KernelInformationStruct){
|
|
||||||
.pde = 0xc0100000,
|
.pde = 0xc0100000,
|
||||||
.page_directory_phys_addr = kernel_page_directory,
|
.page_directory_phys_addr = kernel_page_directory,
|
||||||
.page_directory_phys_offset = 0xc0100000 - (uint32_t)kernel_page_directory,
|
.page_directory_phys_offset = 0xc0100000 - (uint32_t)kernel_page_directory,
|
||||||
@ -195,7 +199,5 @@ void main() {
|
|||||||
.remainingPages = pages
|
.remainingPages = pages
|
||||||
};
|
};
|
||||||
|
|
||||||
*(uint32_t*)(0xc100a004) = kstruct;
|
((void(*)(KernelInformationStruct))0xc0000000)(kstruct);
|
||||||
|
|
||||||
((void(*)())0xc0000000)();
|
|
||||||
}
|
}
|
@ -6,6 +6,40 @@ typedef struct {
|
|||||||
uint32_t pd_index : 10;
|
uint32_t pd_index : 10;
|
||||||
}__attribute__((packed)) split_addr;
|
}__attribute__((packed)) split_addr;
|
||||||
|
|
||||||
|
void map_4k_phys_to_virt_pl3(uint32_t physical, uint32_t virtual, PDE* page_directory, PTE** page_tables) {
|
||||||
|
split_addr* split = (split_addr*)&virtual;
|
||||||
|
|
||||||
|
page_directory[split->pd_index] = (PDE){
|
||||||
|
.address = (uint32_t)(page_tables[split->pd_index]) >> 12,
|
||||||
|
.available = 0,
|
||||||
|
.page_4mb = 0,
|
||||||
|
.accessed = 0,
|
||||||
|
.disable_cache = 0,
|
||||||
|
.write_through_cache = 0,
|
||||||
|
.privilege = 3,
|
||||||
|
.present = 1,
|
||||||
|
.read_write = 1,
|
||||||
|
|
||||||
|
.ignored = 0,
|
||||||
|
.ignored2 = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
page_tables[split->pd_index][split->pt_index] = (PTE){
|
||||||
|
.address = physical >> 12,
|
||||||
|
.available = 0,
|
||||||
|
.global = 0,
|
||||||
|
.accessed = 0,
|
||||||
|
.disable_cache = 0,
|
||||||
|
.dirty = 0,
|
||||||
|
.write_through_cache = 0,
|
||||||
|
.privilege = 3,
|
||||||
|
.present = 1,
|
||||||
|
.read_write = 1,
|
||||||
|
|
||||||
|
.ignored = 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void map_4k_phys_to_virt(uint32_t physical, uint32_t virtual, PDE* page_directory, PTE** page_tables) {
|
void map_4k_phys_to_virt(uint32_t physical, uint32_t virtual, PDE* page_directory, PTE** page_tables) {
|
||||||
split_addr* split = (split_addr*)&virtual;
|
split_addr* split = (split_addr*)&virtual;
|
||||||
|
|
||||||
@ -40,6 +74,11 @@ void map_4k_phys_to_virt(uint32_t physical, uint32_t virtual, PDE* page_director
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void map_many_4k_phys_to_virt_pl3(uint32_t physical, uint32_t virtual, PDE* page_directory, PTE** page_tables, uint32_t count) {
|
||||||
|
for (int i=0; i<count; i++)
|
||||||
|
map_4k_phys_to_virt_pl3(physical + 4096*i, virtual + 4096*i, page_directory, page_tables);
|
||||||
|
}
|
||||||
|
|
||||||
void map_many_4k_phys_to_virt(uint32_t physical, uint32_t virtual, PDE* page_directory, PTE** page_tables, uint32_t count) {
|
void map_many_4k_phys_to_virt(uint32_t physical, uint32_t virtual, PDE* page_directory, PTE** page_tables, uint32_t count) {
|
||||||
for (int i=0; i<count; i++)
|
for (int i=0; i<count; i++)
|
||||||
map_4k_phys_to_virt(physical + 4096*i, virtual + 4096*i, page_directory, page_tables);
|
map_4k_phys_to_virt(physical + 4096*i, virtual + 4096*i, page_directory, page_tables);
|
||||||
|
@ -21,4 +21,7 @@ syscall_hdlr_1(void, kill, "17", uint32_t, PID);
|
|||||||
syscall_hdlr_1(void, sleep, "18", uint32_t, time);
|
syscall_hdlr_1(void, sleep, "18", uint32_t, time);
|
||||||
|
|
||||||
syscall_hdlr_0(uint32_t, getRemainingPages, "19");
|
syscall_hdlr_0(uint32_t, getRemainingPages, "19");
|
||||||
syscall_hdlr_0(uint32_t, getInitPages, "20");
|
syscall_hdlr_0(uint32_t, getInitPages, "20");
|
||||||
|
|
||||||
|
syscall_hdlr_0(uint32_t, getCurrentTerminalWidth, "21");
|
||||||
|
syscall_hdlr_0(uint32_t, getCurrentTerminalHeight, "22");
|
@ -1,7 +1,6 @@
|
|||||||
[BITS 32]
|
[BITS 32]
|
||||||
|
|
||||||
_start:
|
_start:
|
||||||
mov esp, 0xc100a000
|
|
||||||
jmp main
|
jmp main
|
||||||
|
|
||||||
extern main
|
extern main
|
@ -125,6 +125,8 @@ Path* RootFSTree::getRemainingPath(Path p) {
|
|||||||
FSTreeNode* RootFSTree::getExhaustive(Path p) {
|
FSTreeNode* RootFSTree::getExhaustive(Path p) {
|
||||||
PathElement* currentPath = p.start;
|
PathElement* currentPath = p.start;
|
||||||
FSTreeNode* currentNode = this->node;
|
FSTreeNode* currentNode = this->node;
|
||||||
|
if (!currentPath)
|
||||||
|
return 0;
|
||||||
if (currentPath->elem != currentNode->self)
|
if (currentPath->elem != currentNode->self)
|
||||||
return 0;
|
return 0;
|
||||||
while (currentPath && currentNode) {
|
while (currentPath && currentNode) {
|
||||||
|
@ -38,7 +38,7 @@ tss_struct tss = (tss_struct) {
|
|||||||
.ldtr = 0,
|
.ldtr = 0,
|
||||||
._reserved10 = 0,
|
._reserved10 = 0,
|
||||||
._reserved11 = 0,
|
._reserved11 = 0,
|
||||||
.iopb = 104
|
.iopb = sizeof(tss_struct)
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr gdt_entry::gdt_entry(uint32_t limit, uint32_t base, bool rw, bool exec, bool system, uint8_t ring) :
|
constexpr gdt_entry::gdt_entry(uint32_t limit, uint32_t base, bool rw, bool exec, bool system, uint8_t ring) :
|
||||||
@ -77,25 +77,29 @@ constexpr gdt_entry::gdt_entry() :
|
|||||||
base_hi(0)
|
base_hi(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
gdt_entry gdt[] = {
|
gdt_and_iopb gai = {
|
||||||
gdt_entry(), // Null Segment
|
.gdt = {
|
||||||
gdt_entry(0xfffff, 0, 1, 1, 1, 0), // Kernel Code Segment
|
gdt_entry(), // Null Segment
|
||||||
gdt_entry(0xfffff, 0, 1, 0, 1, 0), // Kernel Data Segment
|
gdt_entry(0xfffff, 0, 1, 1, 1, 0), // Kernel Code Segment
|
||||||
|
gdt_entry(0xfffff, 0, 1, 0, 1, 0), // Kernel Data Segment
|
||||||
|
|
||||||
gdt_entry(0xfffff, 0, 1, 1, 1, 3), // User Code Segment
|
gdt_entry(0xfffff, 0, 1, 1, 1, 3), // User Code Segment
|
||||||
gdt_entry(0xfffff, 0, 1, 0, 1, 3), // User Data Segment
|
gdt_entry(0xfffff, 0, 1, 0, 1, 3), // User Data Segment
|
||||||
|
|
||||||
gdt_entry() // Empty Task State Segment
|
gdt_entry() // Empty Task State Segment
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
gdt_descr descr = (gdt_descr){
|
gdt_descr descr = (gdt_descr){
|
||||||
.size = sizeof(gdt) - 1,
|
.size = sizeof(gai.gdt) - 1,
|
||||||
.offset = gdt,
|
.offset = gai.gdt,
|
||||||
};
|
};
|
||||||
|
|
||||||
void init_gdt() {
|
void init_gdt() {
|
||||||
gdt[5] = gdt_entry(sizeof(tss), &tss, 0, 1, 0, 0); // Initialise the TSS.
|
gai.gdt[5] = gdt_entry(sizeof(tss) + 8193, &tss, 0, 1, 0, 0); // Initialise the TSS.
|
||||||
gdt[5].accessed = 1;
|
gai.gdt[5].accessed = 1;
|
||||||
|
for (int i=0; i<8192; i++)
|
||||||
|
gai.iopb[i] = 0;
|
||||||
asm volatile("lgdt %0;"
|
asm volatile("lgdt %0;"
|
||||||
"mov $0x10, %%eax;"
|
"mov $0x10, %%eax;"
|
||||||
"mov %%eax, %%ss;"
|
"mov %%eax, %%ss;"
|
||||||
|
@ -76,6 +76,11 @@ struct __attribute__((packed)) gdt_descr {
|
|||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct __attribute__((packed)) gdt_and_iopb {
|
||||||
|
gdt_entry gdt[6];
|
||||||
|
uint8_t iopb[8192];
|
||||||
|
};
|
||||||
|
|
||||||
void init_gdt();
|
void init_gdt();
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -7,6 +7,9 @@ for i ({0..255}); do
|
|||||||
echo "isr$i:" >> isr.S
|
echo "isr$i:" >> isr.S
|
||||||
echo " push ebp" >> isr.S
|
echo " push ebp" >> isr.S
|
||||||
echo " mov ebp, esp" >> isr.S
|
echo " mov ebp, esp" >> isr.S
|
||||||
|
if (( (i == 8 || i == 17 || (i >= 10 && i <= 14) ) )); then
|
||||||
|
echo " add ebp, 4" >> isr.S
|
||||||
|
fi
|
||||||
if (( !(i == 8 || i == 17 || (i >= 10 && i <= 14) ) )); then
|
if (( !(i == 8 || i == 17 || (i >= 10 && i <= 14) ) )); then
|
||||||
echo " push 0" >> isr.S
|
echo " push 0" >> isr.S
|
||||||
fi
|
fi
|
||||||
|
@ -8,6 +8,7 @@ namespace Global {
|
|||||||
bool currentProcValid = false;
|
bool currentProcValid = false;
|
||||||
xnoe::hashtable<void*, ReadWriter*>* FH; // Map of File Handlers -> Read Writer
|
xnoe::hashtable<void*, ReadWriter*>* FH; // Map of File Handlers -> Read Writer
|
||||||
uint32_t milliseconds_elapsed = 0;
|
uint32_t milliseconds_elapsed = 0;
|
||||||
|
uint32_t resp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new (uint32_t size) {
|
void* operator new (uint32_t size) {
|
||||||
|
@ -21,6 +21,7 @@ namespace Global {
|
|||||||
extern bool currentProcValid;
|
extern bool currentProcValid;
|
||||||
extern xnoe::hashtable<void*, ReadWriter*>* FH;
|
extern xnoe::hashtable<void*, ReadWriter*>* FH;
|
||||||
extern uint32_t milliseconds_elapsed;
|
extern uint32_t milliseconds_elapsed;
|
||||||
|
extern uint32_t resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new (uint32_t size);
|
void* operator new (uint32_t size);
|
||||||
|
@ -26,25 +26,29 @@ void handle_fault(frame_struct* frame) {
|
|||||||
asm ("cli");
|
asm ("cli");
|
||||||
uint32_t problem_address;
|
uint32_t problem_address;
|
||||||
asm ("mov %%cr2, %0" : "=a" (problem_address):);
|
asm ("mov %%cr2, %0" : "=a" (problem_address):);
|
||||||
/*Global::kernel->terminal->printf("\x1b[44;37;1m(CS %x EIP %x): ", frame->cs, frame->eip);
|
/*Global::kernel->terminal->printf("\x1b[44;37;1m(CS %x EIP %x): ", frame->cs, frame->eip);*/
|
||||||
switch (frame->gate) {
|
switch (frame->gate) {
|
||||||
case 0: // Divide by zero
|
case 0: // Divide by zero
|
||||||
Global::kernel->terminal->printf("Divide by Zero");
|
//Global::kernel->terminal->printf("Divide by Zero");
|
||||||
break;
|
break;
|
||||||
case 6: // Invalid Opcode
|
case 6: // Invalid Opcode
|
||||||
Global::kernel->terminal->printf("Invalid Opcode");
|
//Global::kernel->terminal->printf("Invalid Opcode");
|
||||||
break;
|
break;
|
||||||
case 13: // GPF
|
case 13: // GPF
|
||||||
Global::kernel->terminal->printf("General Protection Fault!");
|
//Global::kernel->terminal->printf("General Protection Fault!");
|
||||||
|
if (frame->eflags & 0x00020000) {
|
||||||
|
v86_monitor((v8086_frame_struct*)frame);
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 14: // Page Fault
|
case 14: // Page Fault
|
||||||
Global::kernel->terminal->printf("Page Fault at %x", problem_address);
|
//Global::kernel->terminal->printf("Page Fault at %x", problem_address);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Global::kernel->terminal->printf("Unkown Fault!");
|
//Global::kernel->terminal->printf("Unkown Fault!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Global::kernel->terminal->printf(" Error Code: %x\n", frame->errcode);*/
|
/*Global::kernel->terminal->printf(" Error Code: %x\n", frame->errcode);*/
|
||||||
if (!(frame->cs & 3)) {
|
if (!(frame->cs & 3)) {
|
||||||
Global::kernel->terminal->printf("[FATAL] Kernel Fault!!!\n");
|
Global::kernel->terminal->printf("[FATAL] Kernel Fault!!!\n");
|
||||||
while (1) asm("hlt");
|
while (1) asm("hlt");
|
||||||
@ -194,6 +198,12 @@ void syscall(frame_struct* frame) {
|
|||||||
|
|
||||||
// 18: sleep :: int time ms -> void // Sleeps the current process for time milliseconds.
|
// 18: sleep :: int time ms -> void // Sleeps the current process for time milliseconds.
|
||||||
|
|
||||||
|
// 19: getInitPages :: void -> uint_32 // Returns the amount of physical pages available at boot.
|
||||||
|
// 20: getRemainingPages :: void -> uint_32 // Returns the amount of physical pages remaining.
|
||||||
|
|
||||||
|
// 21: getCurrentTerminalWidth :: void -> uint32_t // Gets the width of the current terminal
|
||||||
|
// 22: getCurrentTerminalHeight :: void -> uint32_t // Gets the height of the current terminal
|
||||||
|
|
||||||
// File handlers:
|
// File handlers:
|
||||||
// 0: Stdout
|
// 0: Stdout
|
||||||
// 1: Stdin
|
// 1: Stdin
|
||||||
@ -362,6 +372,13 @@ void syscall(frame_struct* frame) {
|
|||||||
rval = Global::kernel->phys->initPages;
|
rval = Global::kernel->phys->initPages;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 21:
|
||||||
|
rval = Global::kernel->terminal->width;
|
||||||
|
break;
|
||||||
|
case 22:
|
||||||
|
rval = Global::kernel->terminal->height;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -369,6 +386,60 @@ void syscall(frame_struct* frame) {
|
|||||||
frame->eax = rval;
|
frame->eax = rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void v86_monitor(v8086_frame_struct* frame) {
|
||||||
|
uint8_t* ip = (uint8_t*)((frame->cs<<4) + frame->eip);
|
||||||
|
uint16_t* sp = (uint16_t*)frame->esp;
|
||||||
|
uint16_t flags = (uint16_t)frame->eflags;
|
||||||
|
switch (*ip) {
|
||||||
|
case 0x9c:
|
||||||
|
*(--sp) = (uint16_t)frame->eflags;
|
||||||
|
frame->eip++;
|
||||||
|
break;
|
||||||
|
case 0x9d:
|
||||||
|
frame->eflags &= 0xffff0000;
|
||||||
|
frame->eflags |= *(sp++);
|
||||||
|
frame->eip++;
|
||||||
|
break;
|
||||||
|
case 0xcd: {
|
||||||
|
// Handle int
|
||||||
|
if (!ip[1]) {
|
||||||
|
asm("mov %0, %%esp"::"a"(Global::resp));
|
||||||
|
asm("popa");
|
||||||
|
asm("ret");
|
||||||
|
}
|
||||||
|
uint32_t vector_data = *(uint32_t*)(ip[1]<<2);
|
||||||
|
*(--sp) = flags;
|
||||||
|
frame->eflags &= ~(0x00040300);
|
||||||
|
*(--sp) = (uint16_t)frame->cs;
|
||||||
|
*(--sp) = (uint16_t)(frame->eip+2);
|
||||||
|
uint16_t* vector = (uint16_t*)&vector_data;
|
||||||
|
frame->cs = vector[1];
|
||||||
|
frame->eip = (uint32_t)vector[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xcf: {
|
||||||
|
// Handle iret
|
||||||
|
frame->eip = *(sp++);
|
||||||
|
frame->cs = *(sp++);
|
||||||
|
frame->eflags &= 0xffff0000;
|
||||||
|
frame->eflags |= *(sp++);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xfa:
|
||||||
|
asm("cli");
|
||||||
|
frame->eip++;
|
||||||
|
break;
|
||||||
|
case 0xfb:
|
||||||
|
asm("sti");
|
||||||
|
frame->eip++;
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
frame->esp = sp;
|
||||||
|
}
|
||||||
|
|
||||||
void init_idt() {
|
void init_idt() {
|
||||||
idt_desc desc = {.size = 256 * sizeof(GateEntry) - 1, .offset = (uint32_t)idt};
|
idt_desc desc = {.size = 256 * sizeof(GateEntry) - 1, .offset = (uint32_t)idt};
|
||||||
asm volatile("lidt %0" : : "m" (desc));
|
asm volatile("lidt %0" : : "m" (desc));
|
||||||
@ -379,7 +450,6 @@ void init_idt() {
|
|||||||
for (int i=0; i<256; i++)
|
for (int i=0; i<256; i++)
|
||||||
gates[i] = &ignore_interrupt;
|
gates[i] = &ignore_interrupt;
|
||||||
|
|
||||||
gates[32] = &Timer::tick;
|
|
||||||
gates[0] = &handle_fault;
|
gates[0] = &handle_fault;
|
||||||
gates[5] = &handle_fault;
|
gates[5] = &handle_fault;
|
||||||
gates[6] = &handle_fault;
|
gates[6] = &handle_fault;
|
||||||
@ -424,5 +494,6 @@ void init_idt() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void enable_idt() {
|
void enable_idt() {
|
||||||
|
gates[32] = &Timer::tick;
|
||||||
asm ("sti");
|
asm ("sti");
|
||||||
}
|
}
|
@ -28,9 +28,43 @@ struct __attribute__((packed)) frame_struct {
|
|||||||
uint16_t cs;
|
uint16_t cs;
|
||||||
uint16_t _ignored0;
|
uint16_t _ignored0;
|
||||||
uint32_t eflags;
|
uint32_t eflags;
|
||||||
|
uint32_t esp;
|
||||||
uint16_t ss;
|
uint16_t ss;
|
||||||
uint16_t _ignored1;
|
uint16_t _ignored1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__((packed)) v8086_frame_struct {
|
||||||
|
uint32_t new_cr3;
|
||||||
|
uint32_t new_esp;
|
||||||
|
|
||||||
|
uint32_t edi;
|
||||||
|
uint32_t esi;
|
||||||
|
uint32_t ebp;
|
||||||
|
uint32_t oesp;
|
||||||
|
uint32_t ebx;
|
||||||
|
uint32_t edx;
|
||||||
|
uint32_t ecx;
|
||||||
|
uint32_t eax;
|
||||||
|
|
||||||
|
uint32_t gate;
|
||||||
|
uint32_t __ignored2;
|
||||||
|
uint32_t errcode;
|
||||||
|
|
||||||
|
uint32_t eip;
|
||||||
|
uint16_t cs;
|
||||||
|
uint16_t _ignored0;
|
||||||
|
uint32_t eflags;
|
||||||
uint32_t esp;
|
uint32_t esp;
|
||||||
|
uint16_t ss;
|
||||||
|
uint16_t _ignored1;
|
||||||
|
uint16_t es;
|
||||||
|
uint16_t _ignored2;
|
||||||
|
uint16_t ds;
|
||||||
|
uint16_t _ignored3;
|
||||||
|
uint16_t fs;
|
||||||
|
uint16_t _ignored4;
|
||||||
|
uint16_t gs;
|
||||||
|
uint16_t _ignored5;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void(*gates[256])(frame_struct*);
|
extern void(*gates[256])(frame_struct*);
|
||||||
@ -60,5 +94,6 @@ void context_switch(frame_struct* frame);
|
|||||||
void handle_fault(frame_struct* frame);
|
void handle_fault(frame_struct* frame);
|
||||||
void syscall(frame_struct* frame);
|
void syscall(frame_struct* frame);
|
||||||
void ignore_interrupt(frame_struct* frame);
|
void ignore_interrupt(frame_struct* frame);
|
||||||
|
void v86_monitor(v8086_frame_struct* frame);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -51,4 +51,62 @@ int Kernel::mapFH(ReadWriter* fh) {
|
|||||||
|
|
||||||
void Kernel::unmapFH(uint32_t fh) {
|
void Kernel::unmapFH(uint32_t fh) {
|
||||||
Global::FH->remove((void*)fh);
|
Global::FH->remove((void*)fh);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Kernel::v86(uint16_t ax, uint16_t bx, uint16_t cx, uint16_t es, uint16_t di, uint8_t intn) {
|
||||||
|
// Create the payload to perform an interrupt.
|
||||||
|
uint8_t payload[21] = {
|
||||||
|
0xb8, 0x00, 0x00, // mov ax, 0
|
||||||
|
0x8e, 0xc0, // mov es, ax
|
||||||
|
0xb8, 0x00, 0x00, // mov ax, 0
|
||||||
|
0xbb, 0x00, 0x00, // mov bx, 0
|
||||||
|
0xb9, 0x00, 0x00, // mov cx, 0
|
||||||
|
0xbf, 0x00, 0x00, // mov di, 0
|
||||||
|
0xcd, 0x00, // int 0
|
||||||
|
0xcd, 0x00 // int 0
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set the values in the payload.
|
||||||
|
uint16_t* ax1 = (uint16_t*)(payload+1);
|
||||||
|
uint16_t* ax2 = (uint16_t*)(payload+6);
|
||||||
|
uint16_t* bx1 = (uint16_t*)(payload+9);
|
||||||
|
uint16_t* cx1 = (uint16_t*)(payload+12);
|
||||||
|
uint16_t* di1 = (uint16_t*)(payload+15);
|
||||||
|
uint8_t* intn1 = (uint8_t*)(payload+18);
|
||||||
|
|
||||||
|
*ax1 = es;
|
||||||
|
*ax2 = ax;
|
||||||
|
*bx1 = bx;
|
||||||
|
*cx1 = cx;
|
||||||
|
*di1 = di;
|
||||||
|
*intn1 = intn;
|
||||||
|
|
||||||
|
// Construct a stack.
|
||||||
|
uint32_t* stack = 0x9000;
|
||||||
|
|
||||||
|
*(--stack) = 0; // GS
|
||||||
|
*(--stack) = 0; // FS
|
||||||
|
*(--stack) = 0; // DS
|
||||||
|
*(--stack) = 0; // ES
|
||||||
|
*(--stack) = 0; // SS
|
||||||
|
*(--stack) = 0x9000; // ESP
|
||||||
|
*(--stack) = 0x00020000; // EFLAGS
|
||||||
|
*(--stack) = 0; // CS
|
||||||
|
*(--stack) = 0x7c00; // EIP
|
||||||
|
|
||||||
|
// Copy 19 bytes from payload to 0x7c00
|
||||||
|
|
||||||
|
memcpy(payload, (uint8_t*)0x7c00, 21);
|
||||||
|
|
||||||
|
asm("lea _after_iret, %eax");
|
||||||
|
asm("push %eax");
|
||||||
|
asm("pusha");
|
||||||
|
asm("mov %%esp, %0":"=m"(Global::resp)::);
|
||||||
|
|
||||||
|
asm("xor %eax, %eax; xor %ebx, %ebx; xor %ecx, %ecx; xor %edi, %edi");
|
||||||
|
|
||||||
|
asm("mov %0, %%esp"::"m"(stack):);
|
||||||
|
asm("iret");
|
||||||
|
|
||||||
|
asm("_after_iret:");
|
||||||
}
|
}
|
@ -6,6 +6,7 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
#include "filesystem/fstree.h"
|
#include "filesystem/fstree.h"
|
||||||
|
#include "gdt.h"
|
||||||
|
|
||||||
class Kernel : public Process {
|
class Kernel : public Process {
|
||||||
private:
|
private:
|
||||||
@ -33,7 +34,8 @@ public:
|
|||||||
|
|
||||||
int mapFH(ReadWriter* fh);
|
int mapFH(ReadWriter* fh);
|
||||||
void unmapFH(uint32_t fh);
|
void unmapFH(uint32_t fh);
|
||||||
//void loadPrimaryStack();
|
|
||||||
|
void v86(uint16_t ax, uint16_t bx, uint16_t cx, uint16_t es, uint16_t di, uint8_t intn);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -28,21 +28,20 @@ struct KernelInformationStruct {
|
|||||||
uint32_t remainingPages;
|
uint32_t remainingPages;
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(KernelInformationStruct* kstruct) {
|
int main(KernelInformationStruct kstruct) {
|
||||||
init_gdt();
|
init_gdt();
|
||||||
|
|
||||||
PageDirectory kernel_pd = PageDirectory(kstruct->pde, kstruct->page_directory_phys_addr, kstruct->page_directory_phys_offset);
|
PageDirectory kernel_pd = PageDirectory(kstruct.pde, kstruct.page_directory_phys_addr, kstruct.page_directory_phys_offset);
|
||||||
|
|
||||||
kernel_pd.select();
|
kernel_pd.select();
|
||||||
kernel_pd.unmap(0x8000);
|
|
||||||
|
|
||||||
PageMap phys_pm(kstruct->page_bitmap_phys, kstruct->remainingPages);
|
PageMap phys_pm(kstruct.page_bitmap_phys, kstruct.remainingPages);
|
||||||
PageMap virt_pm(kstruct->page_bitmap_virt);
|
PageMap virt_pm(kstruct.page_bitmap_virt);
|
||||||
|
|
||||||
Kernel kernel = Kernel(&kernel_pd, &phys_pm, &virt_pm, 0xc0000000, kstruct->stack_ptr);
|
Kernel kernel = Kernel(&kernel_pd, &phys_pm, &virt_pm, 0xc0000000, kstruct.stack_ptr);
|
||||||
kernel.init_kernel();
|
kernel.init_kernel();
|
||||||
|
|
||||||
VGAModeTerminal* term = new VGAModeTerminal(kstruct->vga_addr);
|
VGAModeTerminal* term = new VGAModeTerminal(kstruct.vga_addr);
|
||||||
|
|
||||||
kernel.terminal = term;
|
kernel.terminal = term;
|
||||||
|
|
||||||
@ -72,6 +71,10 @@ int main(KernelInformationStruct* kstruct) {
|
|||||||
|
|
||||||
Process* p1 = kernel.createProcess(fh, term);
|
Process* p1 = kernel.createProcess(fh, term);
|
||||||
|
|
||||||
|
Global::tss->esp0 = (new uint8_t[8192]) + 8192;
|
||||||
|
|
||||||
|
//kernel.v86(0x4f00,0,0,0x0,0x8000,0x10);
|
||||||
|
|
||||||
init_keyboard();
|
init_keyboard();
|
||||||
if (worldbin) {
|
if (worldbin) {
|
||||||
worldbin->seek(0);
|
worldbin->seek(0);
|
||||||
|
@ -200,6 +200,9 @@ void Terminal::putchar(uint8_t c) {
|
|||||||
this->edata &= 0x0f;
|
this->edata &= 0x0f;
|
||||||
this->edata |= (n-40)<<4;
|
this->edata |= (n-40)<<4;
|
||||||
break;
|
break;
|
||||||
|
case 49:
|
||||||
|
this->edata &= 0x0f;
|
||||||
|
this->edata |= 0xf0;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -235,6 +238,21 @@ Terminal::Terminal(uint32_t width, uint32_t height, uint32_t pages)
|
|||||||
this->active = false;
|
this->active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Terminal::resize(uint32_t width, uint32_t height, uint32_t pages) {
|
||||||
|
delete this->buffer;
|
||||||
|
this->width = width;
|
||||||
|
this->height = height;
|
||||||
|
this->pages = pages;
|
||||||
|
this->buffer = new uint16_t[width * height * pages];
|
||||||
|
this->last_page_pointer = buffer + (width * height * pages) - (width * height);
|
||||||
|
this->current_page_pointer = last_page_pointer;
|
||||||
|
|
||||||
|
this->cur_x = 0;
|
||||||
|
this->cur_y = 0;
|
||||||
|
|
||||||
|
this->active = false;
|
||||||
|
}
|
||||||
|
|
||||||
void Terminal::printf(const char* string, ...) {
|
void Terminal::printf(const char* string, ...) {
|
||||||
va_list ptr;
|
va_list ptr;
|
||||||
va_start(ptr, string);
|
va_start(ptr, string);
|
||||||
@ -354,6 +372,25 @@ TextModeTerminal::TextModeTerminal(uint16_t* text_mode_pointer): Terminal(80, 25
|
|||||||
this->text_mode_pointer = text_mode_pointer;
|
this->text_mode_pointer = text_mode_pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t color_map[16] = {
|
||||||
|
0, // Black
|
||||||
|
0x00000080, // Blue
|
||||||
|
0x00008000, // Green
|
||||||
|
0x00008080, // Cyan
|
||||||
|
0x00800000, // Red
|
||||||
|
0x00800080, // Magenta
|
||||||
|
0x00008080, // Yellow
|
||||||
|
0x00808080, // White
|
||||||
|
0x00404040, // Black
|
||||||
|
0x000000ff, // Blue
|
||||||
|
0x0000ff00, // Green
|
||||||
|
0x0000ffff, // Cyan
|
||||||
|
0x000000ff, // Red
|
||||||
|
0x00ff00ff, // Magenta
|
||||||
|
0x00ffff00, // Yellow
|
||||||
|
0x00ffffff // White
|
||||||
|
};
|
||||||
|
|
||||||
void VGAModeTerminal::update() {
|
void VGAModeTerminal::update() {
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
@ -382,7 +419,7 @@ void VGAModeTerminal::putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VGAModeTerminal::put_pixels_byte(uint32_t x, uint32_t y, uint8_t color, uint8_t pixel_byte) {
|
void VGAModeTerminal::put_pixels_byte(uint32_t x, uint32_t y, uint8_t color, uint8_t pixel_byte) {
|
||||||
uint32_t pixel = y * 720 + x;
|
uint32_t pixel = y * pixelWidth + x;
|
||||||
uint32_t pixelindex = pixel / 8;
|
uint32_t pixelindex = pixel / 8;
|
||||||
|
|
||||||
uint8_t trbyte = 0;
|
uint8_t trbyte = 0;
|
||||||
@ -403,7 +440,7 @@ void VGAModeTerminal::put_pixels_byte(uint32_t x, uint32_t y, uint8_t color, uin
|
|||||||
void VGAModeTerminal::put_pixel(uint32_t x, uint32_t y, uint8_t color) {
|
void VGAModeTerminal::put_pixel(uint32_t x, uint32_t y, uint8_t color) {
|
||||||
// For any pixel we need to write 1 bit to planes 0, 1, 2, and 3
|
// For any pixel we need to write 1 bit to planes 0, 1, 2, and 3
|
||||||
|
|
||||||
uint32_t pixel = y * 720 + x;
|
uint32_t pixel = y * pixelWidth + x;
|
||||||
uint32_t pixelindex = pixel / 8;
|
uint32_t pixelindex = pixel / 8;
|
||||||
uint32_t pixelbitindex = pixel % 8;
|
uint32_t pixelbitindex = pixel % 8;
|
||||||
|
|
||||||
@ -416,7 +453,7 @@ void VGAModeTerminal::put_pixel(uint32_t x, uint32_t y, uint8_t color) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void VGAModeTerminal::bufferToVRAM(frame_struct* frame, VGAModeTerminal* terminal) {
|
static void VGAModeTerminal::bufferToVRAM(frame_struct* frame, VGAModeTerminal* terminal) {
|
||||||
uint32_t count4 = (720 * 480) / 8 / 4;
|
uint32_t count4 = (terminal->pixelWidth * terminal->pixelHeight) / 8 / 4;
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
outb(0x3c4, 2);
|
outb(0x3c4, 2);
|
||||||
outb(0x3c5, 1<<i);
|
outb(0x3c5, 1<<i);
|
||||||
@ -427,28 +464,25 @@ static void VGAModeTerminal::bufferToVRAM(frame_struct* frame, VGAModeTerminal*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VGAModeTerminal::VGAModeTerminal(uint8_t* vga_pointer): Terminal(90, 60, 1) {
|
VGAModeTerminal::VGAModeTerminal(uint8_t* vga_pointer): Terminal(0, 0, 1) {
|
||||||
this->vga_pointer = vga_pointer;
|
this->vga_pointer = vga_pointer;
|
||||||
|
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
this->planes[i] = new uint8_t[720 * 480 / 8];
|
this->planes[i] = new uint8_t[720 * 480 / 8];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->resize(pixelWidth / 8, pixelHeight / 8, 1);
|
||||||
|
|
||||||
unsigned char g_720x480x16[] =
|
unsigned char g_720x480x16[] =
|
||||||
{
|
{
|
||||||
/* MISC */
|
|
||||||
0xE7,
|
0xE7,
|
||||||
/* SEQ */
|
|
||||||
0x03, 0x01, 0x08, 0x00, 0x06,
|
0x03, 0x01, 0x08, 0x00, 0x06,
|
||||||
/* CRTC */
|
|
||||||
0x6B, 0x59, 0x5A, 0x82, 0x60, 0x8D, 0x0B, 0x3E,
|
0x6B, 0x59, 0x5A, 0x82, 0x60, 0x8D, 0x0B, 0x3E,
|
||||||
0x00, 0x40, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x40, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xEA, 0x0C, 0xDF, 0x2D, 0x08, 0xE8, 0x05, 0xE3,
|
0xEA, 0x0C, 0xDF, 0x2D, 0x08, 0xE8, 0x05, 0xE3,
|
||||||
0xFF,
|
0xFF,
|
||||||
/* GC */
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x0F,
|
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x0F,
|
||||||
0xFF,
|
0xFF,
|
||||||
/* AC */
|
|
||||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||||
0x01, 0x00, 0x0F, 0x00, 0x00,
|
0x01, 0x00, 0x0F, 0x00, 0x00,
|
||||||
@ -501,4 +535,85 @@ VGAModeTerminal::VGAModeTerminal(uint8_t* vga_pointer): Terminal(90, 60, 1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Timer::register_event(16, &VGAModeTerminal::bufferToVRAM, this);
|
Timer::register_event(16, &VGAModeTerminal::bufferToVRAM, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BGAModeTerminal::update() {
|
||||||
|
for (int y = 0; y < height; y++) {
|
||||||
|
for (int x = 0; x < width; x++) {
|
||||||
|
putchar_internal(y * width + x, (uint8_t)(current_page_pointer[y * width + x]), (uint8_t)(current_page_pointer[y * width + x]>>8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BGAModeTerminal::update_cur() {
|
||||||
|
// Todo: Implement cursor for VGAModeTerminal
|
||||||
|
}
|
||||||
|
|
||||||
|
void BGAModeTerminal::putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) {
|
||||||
|
uint32_t col = ptr % width;
|
||||||
|
uint32_t row = ptr / width;
|
||||||
|
|
||||||
|
uint32_t sx = col * 8;
|
||||||
|
uint32_t sy = row * 8;
|
||||||
|
|
||||||
|
if (c>127)
|
||||||
|
return;
|
||||||
|
uint8_t* char_data = font[c];
|
||||||
|
|
||||||
|
for (int y=0; y<8; y++)
|
||||||
|
put_pixels_byte(sx, sy+y, edata, char_data[y]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BGAModeTerminal::put_pixels_byte(uint32_t x, uint32_t y, uint8_t color, uint8_t pixel_byte) {
|
||||||
|
uint32_t pixel = y * pixelWidth + x;
|
||||||
|
|
||||||
|
for (int i=0; i<8; i++)
|
||||||
|
if (pixel_byte&(1<<i))
|
||||||
|
this->fb[pixel+i] = color_map[color&0xf];
|
||||||
|
else
|
||||||
|
this->fb[pixel+i] = color_map[(color>>4)&0xf];
|
||||||
|
}
|
||||||
|
|
||||||
|
void BGAModeTerminal::put_pixel(uint32_t x, uint32_t y, uint8_t color) {
|
||||||
|
// For any pixel we need to write 1 bit to planes 0, 1, 2, and 3
|
||||||
|
|
||||||
|
uint32_t pixel = y * pixelWidth + x;
|
||||||
|
uint32_t pixelindex = pixel / 8;
|
||||||
|
uint32_t pixelbitindex = pixel % 8;
|
||||||
|
|
||||||
|
this->fb[pixel] = color_map[color];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BGAModeTerminal::bufferToVRAM(frame_struct* frame, BGAModeTerminal* terminal) {
|
||||||
|
uint32_t c = terminal->pixelWidth * terminal->pixelHeight;
|
||||||
|
uint32_t bank=0;
|
||||||
|
uint32_t ctr=0;
|
||||||
|
for (int i=0; i<c; i++) {
|
||||||
|
if (i%16384 == 0) {
|
||||||
|
outw(0x1ce, 5);
|
||||||
|
outw(0x1cf, bank++);
|
||||||
|
}
|
||||||
|
((uint32_t*)terminal->vga_pointer)[i%16384] = ((uint32_t*)terminal->fb)[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BGAModeTerminal::BGAModeTerminal(uint8_t* vga_pointer): Terminal(0, 0, 1) {
|
||||||
|
this->vga_pointer = vga_pointer;
|
||||||
|
|
||||||
|
this->fb = new uint32_t[pixelWidth * pixelHeight];
|
||||||
|
|
||||||
|
this->resize(pixelWidth / 8, pixelHeight / 8, 1);
|
||||||
|
|
||||||
|
outw(0x1ce, 4);
|
||||||
|
outw(0x1cf, 0);
|
||||||
|
outw(0x1ce, 1);
|
||||||
|
outw(0x1cf, pixelWidth);
|
||||||
|
outw(0x1ce, 2);
|
||||||
|
outw(0x1cf, pixelHeight);
|
||||||
|
outw(0x1ce, 3);
|
||||||
|
outw(0x1cf, 32);
|
||||||
|
outw(0x1ce, 4);
|
||||||
|
outw(0x1cf, 1);
|
||||||
|
|
||||||
|
Timer::register_event(16, &BGAModeTerminal::bufferToVRAM, this);
|
||||||
}
|
}
|
@ -46,8 +46,6 @@ private:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint16_t* buffer;
|
uint16_t* buffer;
|
||||||
uint32_t width;
|
|
||||||
uint32_t height;
|
|
||||||
uint32_t pages;
|
uint32_t pages;
|
||||||
|
|
||||||
uint32_t cur_x;
|
uint32_t cur_x;
|
||||||
@ -59,7 +57,12 @@ protected:
|
|||||||
bool active;
|
bool active;
|
||||||
|
|
||||||
uint8_t edata=0x07;
|
uint8_t edata=0x07;
|
||||||
|
void resize(uint32_t width, uint32_t height, uint32_t pages);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
|
||||||
Terminal(uint32_t width, uint32_t height, uint32_t pages);
|
Terminal(uint32_t width, uint32_t height, uint32_t pages);
|
||||||
|
|
||||||
void printf(const char* string, ...);
|
void printf(const char* string, ...);
|
||||||
@ -88,7 +91,6 @@ public:
|
|||||||
TextModeTerminal(uint16_t* text_mode_pointer);
|
TextModeTerminal(uint16_t* text_mode_pointer);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class VGAModeTerminal : public Terminal {
|
class VGAModeTerminal : public Terminal {
|
||||||
private:
|
private:
|
||||||
void update() override;
|
void update() override;
|
||||||
@ -101,9 +103,33 @@ private:
|
|||||||
static void bufferToVRAM(frame_struct* frame, VGAModeTerminal* terminal);
|
static void bufferToVRAM(frame_struct* frame, VGAModeTerminal* terminal);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
uint32_t pixelWidth = 720;
|
||||||
|
uint32_t pixelHeight = 480;
|
||||||
|
|
||||||
uint8_t* vga_pointer;
|
uint8_t* vga_pointer;
|
||||||
uint8_t* planes[4];
|
uint8_t* planes[4];
|
||||||
|
|
||||||
VGAModeTerminal(uint8_t* vga_pointer);
|
VGAModeTerminal(uint8_t* vga_pointer);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BGAModeTerminal : public Terminal {
|
||||||
|
private:
|
||||||
|
void update() override;
|
||||||
|
void update_cur() override;
|
||||||
|
void putchar_internal(uint32_t ptr, uint8_t c,uint8_t edata) override;
|
||||||
|
|
||||||
|
void put_pixel(uint32_t x, uint32_t y, uint8_t color);
|
||||||
|
void put_pixels_byte(uint32_t x, uint32_t y, uint8_t color, uint8_t pixel_byte);
|
||||||
|
|
||||||
|
static void bufferToVRAM(frame_struct* frame, BGAModeTerminal* terminal);
|
||||||
|
|
||||||
|
public:
|
||||||
|
uint32_t pixelWidth = 720;
|
||||||
|
uint32_t pixelHeight = 480;
|
||||||
|
|
||||||
|
uint8_t* vga_pointer;
|
||||||
|
uint32_t* fb;
|
||||||
|
|
||||||
|
BGAModeTerminal(uint8_t* vga_pointer);
|
||||||
|
};
|
||||||
#endif
|
#endif
|
@ -8,15 +8,17 @@ typedef struct {
|
|||||||
uint32_t process;
|
uint32_t process;
|
||||||
uint32_t stdin;
|
uint32_t stdin;
|
||||||
uint32_t stdout;
|
uint32_t stdout;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
} procbuffer;
|
} procbuffer;
|
||||||
|
|
||||||
void scrollBuffer(char* buf) {
|
void scrollBuffer(procbuffer* buf) {
|
||||||
for (int y=0; y<56; y++)
|
for (int y=0; y<buf->height; y++)
|
||||||
for (int x=0; x<43; x++)
|
for (int x=0; x<buf->width; x++)
|
||||||
if (y != 55)
|
if (y != buf->height-1)
|
||||||
buf[y*43+x] = buf[(y+1)*43+x];
|
buf->buffer[y*buf->width+x] = buf->buffer[(y+1)*buf->width+x];
|
||||||
else
|
else
|
||||||
buf[y*43+x] = ' ';
|
buf->buffer[y*buf->width+x] = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeToBuf(char c, procbuffer* buf) {
|
void writeToBuf(char c, procbuffer* buf) {
|
||||||
@ -30,22 +32,22 @@ void writeToBuf(char c, procbuffer* buf) {
|
|||||||
if (buf->x > 0)
|
if (buf->x > 0)
|
||||||
buf->x--;
|
buf->x--;
|
||||||
else if (buf->y > 0) {
|
else if (buf->y > 0) {
|
||||||
buf->x = 42;
|
buf->x = buf->width-1;
|
||||||
buf->y--;
|
buf->y--;
|
||||||
}
|
}
|
||||||
buf->buffer[buf->y*43+buf->x] = ' ';
|
buf->buffer[buf->y*buf->width+buf->x] = ' ';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
buf->buffer[buf->y*43+buf->x++] = c;
|
buf->buffer[buf->y*buf->width+buf->x++] = c;
|
||||||
}
|
}
|
||||||
if (buf->x == 43) {
|
if (buf->x == buf->width) {
|
||||||
buf->x = 0;
|
buf->x = 0;
|
||||||
buf->y++;
|
buf->y++;
|
||||||
}
|
}
|
||||||
if (buf->y == 56) {
|
if (buf->y == buf->height) {
|
||||||
buf->y--;
|
buf->y--;
|
||||||
scrollBuffer(buf->buffer);
|
scrollBuffer(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +58,7 @@ void writeCountToBuf(int count, char* c, procbuffer* buf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void clearBuf(procbuffer* buf) {
|
void clearBuf(procbuffer* buf) {
|
||||||
for (int i=0; i<56*43;i++) {
|
for (int i=0; i<buf->height*buf->width;i++) {
|
||||||
buf->buffer[i] = ' ';
|
buf->buffer[i] = ' ';
|
||||||
}
|
}
|
||||||
buf->x = 0;
|
buf->x = 0;
|
||||||
@ -69,53 +71,42 @@ void writeStrToBuf(char* c, procbuffer* b) {
|
|||||||
writeToBuf(*(s++), b);
|
writeToBuf(*(s++), b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void displayBuf(procbuffer* b, int dx, int dy) {
|
|
||||||
print("\x1b[42;36;1m");
|
|
||||||
char pset[9] = "\x1b[00;00H";
|
|
||||||
for (int i=0; i<dy;i++) {
|
|
||||||
pset[3]++;
|
|
||||||
if (pset[3] == 0x3a) {
|
|
||||||
pset[3] = 0x30;
|
|
||||||
pset[2]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i=0; i<dx;i++) {
|
|
||||||
pset[6]++;
|
|
||||||
if (pset[6] == 0x3a) {
|
|
||||||
pset[6] = 0x30;
|
|
||||||
pset[5]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i=0; i<56; i++) {
|
|
||||||
print(pset);
|
|
||||||
write(43, 0, b->buffer+(43*i));
|
|
||||||
pset[3]++;
|
|
||||||
if (pset[3] == 0x3a) {
|
|
||||||
pset[3] = 0x30;
|
|
||||||
pset[2]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setCurPos(int x, int y) {
|
void setCurPos(int x, int y) {
|
||||||
char pset[9] = "\x1b[00;00H";
|
char pset[11] = "\x1b[000;000H";
|
||||||
for (int i=0; i<y;i++) {
|
for (int i=0; i<y;i++) {
|
||||||
pset[3]++;
|
pset[4]++;
|
||||||
|
if (pset[4] == 0x3a) {
|
||||||
|
pset[4] = 0x30;
|
||||||
|
pset[3]++;
|
||||||
|
}
|
||||||
if (pset[3] == 0x3a) {
|
if (pset[3] == 0x3a) {
|
||||||
pset[3] = 0x30;
|
pset[3] = 0x30;
|
||||||
pset[2]++;
|
pset[2]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i=0; i<x;i++) {
|
for (int i=0; i<x;i++) {
|
||||||
pset[6]++;
|
pset[8]++;
|
||||||
if (pset[6] == 0x3a) {
|
if (pset[8] == 0x3a) {
|
||||||
pset[6] = 0x30;
|
pset[8] = 0x30;
|
||||||
pset[5]++;
|
pset[7]++;
|
||||||
|
}
|
||||||
|
if (pset[7] == 0x3a) {
|
||||||
|
pset[7] = 0x30;
|
||||||
|
pset[6]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print(pset);
|
print(pset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void displayBuf(procbuffer* b, int dx, int dy) {
|
||||||
|
print("\x1b[42;36;1m");
|
||||||
|
char pset[9] = "\x1b[000;000H";
|
||||||
|
for (int i=0; i<b->height; i++) {
|
||||||
|
setCurPos(dx, dy++);
|
||||||
|
write(b->width, 0, b->buffer+(b->width*i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void readline(int count, char* buffer) {
|
void readline(int count, char* buffer) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
char c;
|
char c;
|
||||||
@ -161,6 +152,12 @@ bool strcmpcnt(int count, char* a, char* b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
int width = getCurrentTerminalWidth();
|
||||||
|
int height = getCurrentTerminalHeight();
|
||||||
|
|
||||||
|
int bufferWidth = (width - 4) / 2;
|
||||||
|
int bufferHeight = (height - 4);
|
||||||
|
|
||||||
bindToKeyboard();
|
bindToKeyboard();
|
||||||
|
|
||||||
char space = ' ';
|
char space = ' ';
|
||||||
@ -172,16 +169,25 @@ int main() {
|
|||||||
print("\x1b[1;1H");
|
print("\x1b[1;1H");
|
||||||
print("\x1b[45;33;1m");
|
print("\x1b[45;33;1m");
|
||||||
|
|
||||||
char* mid = "+ ++ +";
|
for (int i=0; i<width;i++)
|
||||||
char* bottom = "+ +";
|
|
||||||
for (int i=0; i<90;i++)
|
|
||||||
write(1, 0, &plus);
|
write(1, 0, &plus);
|
||||||
for (int i=0; i<56;i++)
|
for (int i=0; i<bufferHeight;i++) {
|
||||||
write(90, 0, mid);
|
|
||||||
for (int i=0; i<90;i++)
|
|
||||||
write(1, 0, &plus);
|
write(1, 0, &plus);
|
||||||
write(90, 0, bottom);
|
for (int j=0; j<bufferWidth; j++)
|
||||||
for (int i=0; i<90;i++)
|
write(1, 0, &space);
|
||||||
|
write(1, 0, &plus);
|
||||||
|
write(1, 0, &plus);
|
||||||
|
for (int j=0; j<bufferWidth; j++)
|
||||||
|
write(1, 0, &space);
|
||||||
|
write(1, 0, &plus);
|
||||||
|
}
|
||||||
|
for (int i=0; i<width;i++)
|
||||||
|
write(1, 0, &plus);
|
||||||
|
write(1, 0, &plus);
|
||||||
|
for (int i=0; i< width - 2; i++)
|
||||||
|
write(1, 0, &space);
|
||||||
|
write(1, 0, &plus);
|
||||||
|
for (int i=0; i<width;i++)
|
||||||
write(1, 0, &plus);
|
write(1, 0, &plus);
|
||||||
|
|
||||||
uint32_t program = fopen("/hello.bin");
|
uint32_t program = fopen("/hello.bin");
|
||||||
@ -196,21 +202,25 @@ int main() {
|
|||||||
fclose(program);
|
fclose(program);
|
||||||
|
|
||||||
procbuffer b1 = {
|
procbuffer b1 = {
|
||||||
.buffer = malloc(56 * 43),
|
.buffer = malloc(bufferWidth * bufferHeight),
|
||||||
.x = 0,
|
.x = 0,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
.process = p1,
|
.process = p1,
|
||||||
.stdin = p1in,
|
.stdin = p1in,
|
||||||
.stdout = p1out
|
.stdout = p1out,
|
||||||
|
.width = bufferWidth,
|
||||||
|
.height = bufferHeight
|
||||||
};
|
};
|
||||||
|
|
||||||
procbuffer b2 = {
|
procbuffer b2 = {
|
||||||
.buffer = malloc(56 * 43),
|
.buffer = malloc(bufferWidth * bufferHeight),
|
||||||
.x = 0,
|
.x = 0,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
.process = p2,
|
.process = p2,
|
||||||
.stdin = p2in,
|
.stdin = p2in,
|
||||||
.stdout = p2out
|
.stdout = p2out,
|
||||||
|
.width = bufferWidth,
|
||||||
|
.height = bufferHeight
|
||||||
};
|
};
|
||||||
|
|
||||||
procbuffer* selectedBuf = &b1;
|
procbuffer* selectedBuf = &b1;
|
||||||
@ -230,9 +240,9 @@ int main() {
|
|||||||
if (c[0] == ':') {
|
if (c[0] == ':') {
|
||||||
char buf[32] = {0};
|
char buf[32] = {0};
|
||||||
print("\x1b[45;33;1m");
|
print("\x1b[45;33;1m");
|
||||||
print("\x1b[59;2H");
|
setCurPos(2, height-1);
|
||||||
print(": ");
|
print(": ");
|
||||||
print("\x1b[59;3H");
|
setCurPos(3, height-1);
|
||||||
readline(32, buf);
|
readline(32, buf);
|
||||||
if (strcmpcnt(6, buf, "switch")) {
|
if (strcmpcnt(6, buf, "switch")) {
|
||||||
if (selectedBuf == &b1) {
|
if (selectedBuf == &b1) {
|
||||||
@ -293,6 +303,6 @@ int main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
displayBuf(&b1, 2, 2);
|
displayBuf(&b1, 2, 2);
|
||||||
displayBuf(&b2, 47, 2);
|
displayBuf(&b2, bufferWidth+4, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user