Merge into main the new state of the operating system/kernel #1

Open
Nigel wants to merge 120 commits from dev into main
48 changed files with 195 additions and 173 deletions
Showing only changes of commit 13e9beea79 - Show all commits

View File

@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc
CPP = ${HOME}/opt/cross/bin/i686-elf-g++
CFLAGS = -ffreestanding -Og -ggdb -Wall -Wextra
OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/memory.o $(BUILD_DIR)/paging.o $(BUILD_DIR)/pit.o $(BUILD_DIR)/time.o $(BUILD_DIR)/keyboard.o $(BUILD_DIR)/io.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/sv-terminal.o $(BUILD_DIR)/string.o $(BUILD_DIR)/prekernel.o
OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/memory.o $(BUILD_DIR)/paging.o $(BUILD_DIR)/pit.o $(BUILD_DIR)/time.o $(BUILD_DIR)/keyboard.o $(BUILD_DIR)/io.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/sv-terminal.o $(BUILD_DIR)/string.o $(BUILD_DIR)/prekernel.o $(BUILD_DIR)/cpu.o
SRC_DIR = source
BUILD_DIR = build
@ -55,7 +55,7 @@ $(BUILD_DIR)/kernel.o:
$(CPP) -c $(SRC_DIR)/kernel/kernel.cpp -o $(BUILD_DIR)/kernel.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/kterm.o:
$(CPP) -c $(SRC_DIR)/kernel/Terminal/kterm.cpp -o $(BUILD_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c $(SRC_DIR)/kernel/terminal/kterm.cpp -o $(BUILD_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/boot.o:
$(AS) $(SRC_DIR)/kernel/boot/boot.s -o $(BUILD_DIR)/boot.o
@ -71,38 +71,41 @@ $(BUILD_DIR)/io.o:
$(BUILD_DIR)/idt.o:
$(CPP) -c $(SRC_DIR)/kernel/Interrupts/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c $(SRC_DIR)/kernel/interrupts/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/gdtc.o:
$(CPP) -c $(SRC_DIR)/kernel/Memory/GDT/gdtc.cpp -o $(BUILD_DIR)/gdtc.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c $(SRC_DIR)/kernel/memory/gdt/gdtc.cpp -o $(BUILD_DIR)/gdtc.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/pic.o:
$(CPP) -c $(SRC_DIR)/kernel/Drivers/PIC/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c $(SRC_DIR)/kernel/drivers/pic/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/string.o:
$(CC) -c $(SRC_DIR)/kernel/Lib/string.c -o $(BUILD_DIR)/string.o $(CFLAGS) -std=gnu99
$(CC) -c $(SRC_DIR)/kernel/lib/string.c -o $(BUILD_DIR)/string.o $(CFLAGS) -std=gnu99
$(BUILD_DIR)/pit.o:
$(CPP) -c $(SRC_DIR)/kernel/Drivers/PIT/pit.cpp -o $(BUILD_DIR)/pit.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c $(SRC_DIR)/kernel/drivers/pit/pit.cpp -o $(BUILD_DIR)/pit.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/keyboard.o:
$(CPP) -c $(SRC_DIR)/kernel/Drivers/PS-2/keyboard.cpp -o $(BUILD_DIR)/keyboard.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c $(SRC_DIR)/kernel/drivers/ps-2/keyboard.cpp -o $(BUILD_DIR)/keyboard.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/time.o:
$(CPP) -c $(SRC_DIR)/kernel/time.cpp -o $(BUILD_DIR)/time.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/sv-terminal.o:
$(CPP) -c $(SRC_DIR)/kernel/SuperVisorTerminal/superVisorTerminal.cpp -o $(BUILD_DIR)/sv-terminal.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c $(SRC_DIR)/kernel/supervisorterminal/superVisorTerminal.cpp -o $(BUILD_DIR)/sv-terminal.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/memory.o:
$(CPP) -c $(SRC_DIR)/kernel/Memory/PhysicalMemoryManager.cpp -o $(BUILD_DIR)/memory.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c $(SRC_DIR)/kernel/memory/PhysicalMemoryManager.cpp -o $(BUILD_DIR)/memory.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/paging.o:
$(CPP) -c $(SRC_DIR)/kernel/Memory/VirtualMemoryManager.cpp -o $(BUILD_DIR)/paging.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c $(SRC_DIR)/kernel/memory/VirtualMemoryManager.cpp -o $(BUILD_DIR)/paging.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/prekernel.o:
$(CPP) -c $(SRC_DIR)/kernel/PreKernel/prekernel.cpp -o $(BUILD_DIR)/prekernel.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c $(SRC_DIR)/kernel/prekernel/prekernel.cpp -o $(BUILD_DIR)/prekernel.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/cpu.o:
$(CPP) -c $(SRC_DIR)/kernel/cpu.cpp -o $(BUILD_DIR)/cpu.o $(CFLAGS) -fno-exceptions -fno-rtti

View File

@ -1,24 +0,0 @@
#include "VirtualMemoryManager.h"
extern "C" void loadPageDirectory (uint32_t* addr );
extern "C" void enablePaging();
void AllocatePage(uint32_t vaddr)
{
}
void FreePage(uint32_t vaddr )
{
}
void Map ( uint32_t vaddr, uint32_t paddr)
{
}
void Unmap(uint32_t vaddr)
{
// NOTE: I will implement lazy unmapping for now
}

View File

@ -1,8 +0,0 @@
#pragma once
#include "../Terminal/kterm.h"
#include "../time.h"
#include "../Drivers/PIT/pit.h"
#include "../Drivers/PS-2/keyboard.h"
#include "../Memory/PhysicalMemoryManager.h"
void startSuperVisorTerminal();

View File

@ -17,6 +17,7 @@ stack_top:
.globl boot_page_directory
boot_page_directory:
.skip 4096
.globl boot_page_table
boot_page_table:
.skip 4096
.globl multiboot_page_table
@ -60,15 +61,6 @@ _start:
3: # Map VGA video memory to 0xC03FF00 as "present, writable"
movl $(0x000B8000 | 0x003), boot_page_table - 0xC0000000 + 1023 * 4
# IMPORTANT NOTE FROM WIKI.OSDEV.ORG/HIGHER_HALF_X86_BARE_BONES
# The page table is used at both page directory entry 0 (virtually from 0x0
# to 0x3FFFFF) (thus identity mapping the kernel) and page directory entry
# 768 (virtually from 0xC0000000 to 0xC03FFFFF) (thus mapping it in the
# higher half). The kernel is identity mapped because enabling paging does
# not change the next instruction, which continues to be physical. The CPU
# would instead page fault if there was no identity mapping.\
# Map the page table to both virtual addresss 0x00000000 and 0xC0000000
movl $(boot_page_table - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 0
movl $(boot_page_table - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 768 * 4
@ -112,10 +104,9 @@ isPaging:
jmp 1b
.include "./source/kernel/Memory/GDT/gdt.s"
.include "./source/kernel/memory/gdt/gdt.s"
.include "./source/kernel/irs_table.s"
.include "./source/kernel/irq_table.s"
.include "./source/kernel/Interrupts/idt/idt.s"
.include "./source/kernel/cpu.s"
.include "./source/kernel/interrupts/idt/idt.s"

39
source/kernel/cpu.cpp Normal file
View File

@ -0,0 +1,39 @@
#include "cpu.h"
uint32_t GetEFLAGS()
{
uint32_t EFLAGS = 0;
asm volatile ("pushfl;" "movl 4(%%esp), %%edx" : "=d"(EFLAGS));
return EFLAGS;
}
uint32_t GetCR0()
{
uint32_t cr0_value;
asm volatile ("movl %%cr0, %%edx" : "=d"(cr0_value));
return cr0_value;
}
uint32_t GetCR2(){
uint32_t cr2_value;
__asm__ volatile("movl %%cr2, %%edx": "=d"(cr2_value));
return cr2_value;
}
uint32_t GetCR3(){
uint32_t cr3_value;
__asm__ volatile("movl %%cr3, %%edx": "=d"(cr3_value));
return cr3_value;
}
uint32_t GetCR4(){
uint32_t cr4_value;
__asm__ volatile("movl %%cr4, %%edx": "=d"(cr4_value));
return cr4_value;
}

View File

@ -9,19 +9,18 @@ C++ interface for the cpu.s assembly file.
©Nigel Barink - 2022
*/
/*
* EFLAGS FUNCTIONS
*/
extern "C" uint32_t GetEFLAGS();
uint32_t GetEFLAGS();
/*
* CONTROL_REGISTER_0 FUNCTIONS
*/
extern "C" uint32_t GetCR0();
uint32_t GetCR0();
/*
struct CR0_Register {
@ -57,7 +56,7 @@ extern "C" uint32_t GetCR0();
* CONTROL_REGISTER_4 FUNCTIONS
*/
extern "C" uint32_t GetCR4();
uint32_t GetCR4();
#define GET_PSE_BIT(CONTROL_REGISTER_4) (CONTROL_REGISTER_4&0x4)
#define GET_PAE_BIT(CONTROL_REGISTER_4) (CONTROL_REGISTER_4&0x5)
@ -66,10 +65,10 @@ extern "C" uint32_t GetCR4();
* CONTROL_REGISTER_2 FUNCTIONS
*/
extern "C" uint32_t GetCR2();
uint32_t GetCR2();
/*
* CONTROL_REGISTER_3 FUNCTIONS
*/
extern "C" uint32_t GetCR3();
uint32_t GetCR3();

View File

@ -1,63 +0,0 @@
# Basic cpu functions
.globl GetCR0
GetCR0:
push %ebp # save the base pointer on the stack
mov %esp, %ebp # Set the base pointer to the current stack pointer
xor %eax, %eax # Clear EAX to make sure no weird stuff is going on
mov %cr0, %eax # Copy the value of the CR0 register into EAX
mov %ebp, %esp # restore the base pointer
pop %ebp
ret
.globl GetCR4
GetCR4:
push %ebp
mov %esp, %ebp
xor %eax, %eax
mov %cr4, %eax
mov %ebp, %esp
pop %ebp
ret
.globl GetEFLAGS
GetEFLAGS:
push %ebp
mov %esp, %ebp
xor %eax, %eax
pushfl # Push the EFLAGS register content onto the stack, should be pushfd but GAS apparently doesn't agree
mov 4(%esp) , %eax
mov %ebp, %esp
pop %ebp
ret
.globl GetCR2
GetCR2:
push %ebp
mov %esp, %ebp
xor %eax, %eax
mov %cr2, %eax
mov %ebp, %esp
pop %ebp
ret
.globl GetCR3
GetCR3:
push %ebp
mov %esp, %ebp
xor %eax, %eax
mov %cr3, %eax
mov %ebp, %esp
pop %ebp
ret

View File

@ -1,5 +1,5 @@
#include "pit.h"
#include "../../Terminal/kterm.h"
uint32_t pit_tick = 0;

View File

@ -1,6 +1,7 @@
#pragma once
#include <stdint.h>
#include "../../io.h"
#include "../../terminal/kterm.h"
#define PIT_DATA_0 0x40
#define PIT_DATA_1 0x41
#define PIT_DATA_2 0x42

View File

@ -1,6 +1,6 @@
#pragma once
#include <stdint.h>
#include "../../Terminal/kterm.h"
#include "../../terminal/kterm.h"
enum ScanCodeSet {
None = 0,
ScanCodeSet1 = 1,

View File

@ -1,6 +1,6 @@
#include "idt.h"
#include "../../Drivers/PIT/pit.h"
#include "../../Drivers/PS-2/keyboard.h"
#include "../../drivers/pit/pit.h"
#include "../../drivers/ps-2/keyboard.h"
#include "../../cpu.h"
IDT_entry idt_table[256];
IDT_ptr idt_ptr;

View File

@ -2,10 +2,10 @@
#include <stdint.h>
#include <stddef.h>
#include "../../Drivers/VGA/colors.h"
#include "../../Drivers/PIC/pic.h"
#include "../../drivers/vga/colors.h"
#include "../../drivers/pic/pic.h"
#include "../../Terminal/kterm.h"
#include "../../terminal/kterm.h"
extern "C" {

View File

@ -1,11 +1,6 @@
#include "kernel.h"
extern "C" void early_main()
{
/*
* Initialize terminal interface
*/
kterm_init();
initGDT();
@ -68,6 +63,7 @@ extern "C" void early_main()
printf( "Starting address: 0x%x\n", currentBlock);
while( (uint32_t)currentBlock->next != 0x0 )
{
printf("CurrentBlock: 0x%x \n", (uint32_t ) currentBlock );
if(IS_AVAILABLE_MEM(currentBlock->type)){
//printf("AVAILABLE RAM\n");
}
@ -91,11 +87,12 @@ extern "C" void early_main()
}
printf("Starting physical memory management setup\n");
// Setup PhysicalMemoryManagement
SetupPhysicalMemoryManager(BootInfo);
}
printf("Enable Protected mode and jump to kernel main\n");
asm volatile("mov %cr0, %eax ");
asm volatile("or $1, %eax");
asm volatile("mov %eax, %cr0"); // re-enable protected mode ?

View File

@ -1,27 +1,27 @@
#pragma once
extern "C"
{
#include "Lib/string.h"
#include "lib/string.h"
}
#include "definitions.h"
#include "Drivers/VGA/VBE.h"
#include "Terminal/kterm.h"
#include "drivers/vga/VBE.h"
#include "terminal/kterm.h"
#include "Memory/PhysicalMemoryManager.h"
#include "Memory/VirtualMemoryManager.h"
#include "memory/PhysicalMemoryManager.h"
#include "memory/VirtualMemoryManager.h"
#include "Memory/GDT/gdtc.h"
#include "Interrupts/idt/idt.h"
#include "memory/gdt/gdtc.h"
#include "interrupts/idt/idt.h"
#include "Drivers/PIT/pit.h"
#include "drivers/pit/pit.h"
#include "io.h"
#include "cpu.h"
#include "serial.h"
#include "time.h"
#include "SuperVisorTerminal/superVisorTerminal.h"
#include "PreKernel/bootstructure.h"
#include "supervisorterminal/superVisorTerminal.h"
#include "prekernel/bootstructure.h"
#define CHECK_FLAG(flag, bit) ( flag & (1 << bit ))
#define PANIC(message) {return;}

View File

@ -14,6 +14,7 @@ void* malloc(size_t size)
printf("Received request for %d bytes of memory", size);
heap_block* current = start;
// look for a free block
while(current < start + heap_size)
{
if(current->size >= size && current->Used == false )
@ -33,7 +34,7 @@ void* malloc(size_t size)
// If we are here we need more memory so we should
// probably ask the VMM for more
// TODO: ask for more memory
// TODO: ask for more memory | Extend kernel heap
}

View File

@ -1,30 +1,34 @@
#include "./PhysicalMemoryManager.h"
PhysicalMemoryManagerInfoBlock* PMMInfoBlock;
extern uint32_t* boot_page_directory;
extern uint32_t* boot_page_table;
const uint32_t KERNEL_OFFSET = 0xC0000000;
void SetupPhysicalMemoryManager( BootInfoBlock* Bootinfo) {
PMMInfoBlock = (PhysicalMemoryManagerInfoBlock*) ((uint32_t)MemoryMapHeap_pptr + Bootinfo->map_size + 0xC0000000);
// NOTE: Physical memory map will override the boot info for now!
PMMInfoBlock = (PhysicalMemoryManagerInfoBlock*) (&BootInfoBlock_pptr + KERNEL_OFFSET );
printf("Setting up physical memory infoblock (0x%x) \n", (uint32_t)&PMMInfoBlock);
/*
Every byte contains 8 pages
A page is 4096 kib
Every block (1 bit) represent an page
*/
// calculate the maximum number of blocks
PMMInfoBlock->max_blocks =Bootinfo->MemorySize / BLOCK_SIZE / 8;
// Calculate the maximum number of blocks
printf("Maxblocks at address(0x%x)\n" , (uint32_t)&(PMMInfoBlock->max_blocks));
int maximum_blocks = (uint32_t)Bootinfo->MemorySize / BLOCK_SIZE / 8;
printf("Set bitmap block maximum: %d\n", maximum_blocks);
PMMInfoBlock->max_blocks = maximum_blocks;
printf("Set used blocks to zero\n");
PMMInfoBlock->used_blocks = 0;
printf("Determine memory bit map address");
// put the map after the gdt
PMMInfoBlock->memoryBitMap = (uint32_t*) ( 0xC010b100) ;
// // Page in the address space please
// uint32_t PDEI = 0xC020a000 >> 22;
// uint32_t PTEI = (0xC020a000 >> 12) & 0x1FFF;
// printf("PDEI: %d, PTEI: %d\n", PDEI, PTEI);
printf("Maximum num blocks: %d \n",PMMInfoBlock->max_blocks);
//Size of memory map
uint32_t memMap_size = PMMInfoBlock->max_blocks / 8;
@ -54,7 +58,7 @@ void SetupPhysicalMemoryManager( BootInfoBlock* Bootinfo) {
printf("kernel size in memory: 0x%x\n", kernel_size);
allocate_region((uint32_t)&kernel_begin, kernel_size);
printf("allocate BIOS region");
printf("allocate BIOS region\n");
allocate_region (0x0000000, 0x00100000);
}

View File

@ -1,8 +1,8 @@
#pragma once
#include <stddef.h>
#include "../PreKernel/bootstructure.h"
#include "../Terminal/kterm.h"
#include "../Lib/mem.h"
#include "../prekernel/bootstructure.h"
#include "../terminal/kterm.h"
#include "../lib/mem.h"
#include "../bitmap.h"
// Asumming i386 for now!
@ -14,8 +14,8 @@
struct PhysicalMemoryManagerInfoBlock
{
uint32_t* memoryBitMap;
size_t pmmap_size;
size_t max_blocks;
uint32_t pmmap_size;
uint32_t max_blocks;
int used_blocks;
};

View File

@ -0,0 +1,73 @@
#include "VirtualMemoryManager.h"
extern uint32_t boot_page_directory[1024] ;
extern uint32_t boot_page_table[1024];
void AllocatePage(uint32_t vaddr)
{
uint32_t page_aligned_address = ALIGN(vaddr, 4096);
// allocate a page at virtual address
int PageDirectoryEntryIndex = vaddr >> 22;
int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
printf("Allocation happening at PDE: %d PTE: %d\n", PageDirectoryEntryIndex, PageTableEntryIndex);
// check if the page directory entry is marked as present
if (boot_page_directory[PageDirectoryEntryIndex] & 0x1 ) {
uint32_t* page_table = (uint32_t*)((boot_page_directory[PageDirectoryEntryIndex]) & 0xFFFFE000 + 0xC0000000);
// check if the page table entry is marked as present
if ( page_table[PageTableEntryIndex] & 0x1 )
{
// Map the entry to a physical page
page_table[PageTableEntryIndex] = (uint32_t)(allocate_block() + 0x3);
} else{
// mark page as present
page_table[PageTableEntryIndex] = 0x3;
}
} else {
// mark the page table as present and allocate a physical block for it
boot_page_directory[PageDirectoryEntryIndex] = (uint32_t)(allocate_block() + 0x3);
}
}
void FreePage(uint32_t vaddr )
{
uint32_t page_aligned_address = ALIGN(vaddr, 4096);
// allocate a page at virtual address
int PageDirectoryEntryIndex = vaddr >> 22;
int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
uint32_t* pageTable = (uint32_t*)(boot_page_directory[PageDirectoryEntryIndex] & 0xFFFFE000 + 0xC0000000);
void* physicalAddressToFree = (void*)(pageTable[PageTableEntryIndex] & 0xFFFFE000 + 0xC0000000);
free_block(physicalAddressToFree);
pageTable[PageTableEntryIndex] = 0x0;
}
void Map ( uint32_t vaddr, uint32_t paddr)
{
uint32_t page_aligned_address = ALIGN(vaddr, 4096);
// allocate a page at virtual address
int PageDirectoryEntryIndex = vaddr >> 22;
int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
}
void Unmap(uint32_t vaddr)
{
// NOTE: I will implement lazy unmapping for now
uint32_t page_aligned_address = ALIGN(vaddr, 4096);
// allocate a page at virtual address
int PageDirectoryEntryIndex = vaddr >> 22;
int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
}

View File

@ -1,6 +1,6 @@
#pragma once
#include "PhysicalMemoryManager.h"
#include "../Terminal/kterm.h"
#include "../terminal/kterm.h"
#include "../cpu.h"
void AllocatePage(uint32_t v_addr );

View File

@ -1,5 +1,5 @@
#include "gdtc.h"
#include "../../Terminal/kterm.h"
#include "../../terminal/kterm.h"
#define NULL_SEGMENT 0
#define KERNEL_CODE_SEGMENT 1

View File

@ -16,6 +16,7 @@ extern "C" void prekernelSetup ( unsigned long magic, multiboot_info_t* mbi) {
if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
{
BIB->MapIsInvalid = true;
// crash
return;
} else{
BIB->MapIsInvalid = false;

View File

@ -1,6 +1,6 @@
#pragma once
#include "Terminal/kterm.h"
#include "terminal/kterm.h"
#include "io.h"
#define PORT 0x3f8
static int init_serial() {

View File

@ -0,0 +1,8 @@
#pragma once
#include "../terminal/kterm.h"
#include "../time.h"
#include "../drivers/pit/pit.h"
#include "../drivers/ps-2/keyboard.h"
#include "../memory/PhysicalMemoryManager.h"
void startSuperVisorTerminal();

View File

@ -3,11 +3,11 @@
#include <stddef.h>
#include <stdbool.h>
#include "../Drivers/VGA/colors.h"
#include "../drivers/vga/colors.h"
#include "../io.h"
extern "C"{
#include "../Lib/string.h"
#include "../lib/string.h"
}
void kterm_init();