feat: implement initial CPIO parsing and shell improvements
- core: added CPIO parser (fs/cpio.c) and VFS structs - shell: refactored ksh, added 'help' command - lib: added string utils (strcpy, strncpy, strncmp) - wip: working on initramfs loading in kmain
This commit is contained in:
+2
-1
@@ -1,3 +1,4 @@
|
||||
.cache
|
||||
build*
|
||||
.venv
|
||||
.venv
|
||||
initrd/image.cpio
|
||||
+19
-3
@@ -11,12 +11,27 @@ add_subdirectory(kernel)
|
||||
|
||||
find_program(MCOPY_EXE mcopy)
|
||||
find_program(MKFS_EXE mkfs.fat)
|
||||
find_program(CPIO_EXE cpio)
|
||||
find_program(QEMU_EXE qemu-system-x86_64)
|
||||
set(OVMF_PATH "/usr/share/edk2/ovmf/OVMF_CODE.fd" CACHE FILEPATH "Path to OVMF bios")
|
||||
|
||||
if(MCOPY_EXE AND MKFS_EXE)
|
||||
if(MCOPY_EXE AND MKFS_EXE AND CPIO_EXE)
|
||||
set(IMG_FILE "${CMAKE_BINARY_DIR}/termOS.img")
|
||||
|
||||
set(INITRAMFS_SRC_DIR "${CMAKE_SOURCE_DIR}/initramfs")
|
||||
set(INITRAMFS_CPIO_FILE "${CMAKE_BINARY_DIR}/initramfs.cpio")
|
||||
file(GLOB_RECURSE INIT_FILES "${INITRAMFS_SRC_DIR}/*")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${INITRAMFS_CPIO_FILE}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}
|
||||
COMMAND sh -c "find . -mindepth 1 ! -name '*.cpio' -print0 | ${CPIO_EXE} --null -ov -H newc > \"${INITRAMFS_CPIO_FILE}\""
|
||||
WORKING_DIRECTORY ${INITRAMFS_SRC_DIR}
|
||||
DEPENDS ${INIT_FILES}
|
||||
VERBATIM
|
||||
COMMENT "Packing initramfs to cpio..."
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${IMG_FILE}
|
||||
COMMAND dd if=/dev/zero of=${IMG_FILE} bs=1M count=64 status=none
|
||||
@@ -24,7 +39,9 @@ if(MCOPY_EXE AND MKFS_EXE)
|
||||
COMMAND mmd -i ${IMG_FILE} ::/EFI ::/EFI/BOOT
|
||||
COMMAND ${MCOPY_EXE} -i ${IMG_FILE} $<TARGET_FILE:BOOTX64> ::/EFI/BOOT/BOOTX64.EFI
|
||||
COMMAND ${MCOPY_EXE} -i ${IMG_FILE} ${CMAKE_BINARY_DIR}/bin/kernel.bin ::/kernel.bin
|
||||
DEPENDS BOOTX64 kernel
|
||||
COMMAND ${MCOPY_EXE} -i ${IMG_FILE} ${INITRAMFS_CPIO_FILE} ::/initramfs.cpio
|
||||
DEPENDS BOOTX64 kernel ${INITRAMFS_CPIO_FILE}
|
||||
VERBATIM
|
||||
COMMENT "Generating bootable image: ${IMG_FILE}"
|
||||
)
|
||||
|
||||
@@ -41,7 +58,6 @@ if(QEMU_EXE)
|
||||
-net none
|
||||
-serial stdio
|
||||
-m 512M
|
||||
#-s -S
|
||||
DEPENDS image
|
||||
)
|
||||
endif()
|
||||
+73
-23
@@ -4,63 +4,113 @@
|
||||
#include "uefi.h" // IWYU pragma: keep
|
||||
#include "../../common/bootinfo.h"
|
||||
|
||||
void print(wchar_t* msg) {
|
||||
ST->ConOut->OutputString(ST->ConOut, msg);
|
||||
}
|
||||
|
||||
void print_initramfs_warning(wchar_t* reason) {
|
||||
print(L"WARNING: Failed to load initramfs file!! Only kernel emergency shell available..\r\nReason: ");
|
||||
print(reason);
|
||||
print(L"\r\n");
|
||||
BS->Stall(2 * 1000 * 1000); // 2s
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
efi_gop_t *gop = nullptr;
|
||||
efi_gop_t* gop = nullptr;
|
||||
efi_guid_t gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
||||
ST->BootServices->LocateProtocol(&gop_guid, 0, (void**)&gop);
|
||||
|
||||
efi_loaded_image_protocol_t *loaded_image;
|
||||
efi_loaded_image_protocol_t* loaded_image;
|
||||
efi_guid_t lip_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||
gBS->HandleProtocol(IM, &lip_guid, (void**)&loaded_image);
|
||||
|
||||
efi_simple_file_system_protocol_t *fs;
|
||||
efi_simple_file_system_protocol_t* fs;
|
||||
efi_guid_t sfsp_guid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
|
||||
gBS->HandleProtocol(loaded_image->DeviceHandle, &sfsp_guid, (void**)&fs);
|
||||
|
||||
efi_file_handle_t *root;
|
||||
efi_file_handle_t* root;
|
||||
efi_guid_t fi_guid = EFI_FILE_INFO_GUID;
|
||||
fs->OpenVolume(fs, &root);
|
||||
|
||||
efi_file_handle_t *kernel_file;
|
||||
efi_guid_t fi_guid = EFI_FILE_INFO_GUID;
|
||||
uintn_t info_size = 0;
|
||||
efi_file_info_t *file_info = nullptr;
|
||||
// kernel
|
||||
|
||||
efi_file_handle_t* kernel_file;
|
||||
uintn_t kinfo_size = 0;
|
||||
efi_file_info_t* kfile_info = nullptr;
|
||||
efi_status_t status = root->Open(root, &kernel_file, L"kernel.bin", EFI_FILE_MODE_READ, 0);
|
||||
if (EFI_ERROR(status)) {
|
||||
ST->ConOut->OutputString(ST->ConOut, L"Kernel not found :(");
|
||||
print(L"Kernel not found :(");
|
||||
while (1);
|
||||
}
|
||||
|
||||
status = kernel_file->GetInfo(kernel_file, &fi_guid, &info_size, NULL);
|
||||
status = kernel_file->GetInfo(kernel_file, &fi_guid, &kinfo_size, nullptr);
|
||||
|
||||
if (status == EFI_BUFFER_TOO_SMALL) {
|
||||
gBS->AllocatePool(EfiLoaderData, info_size, (void**)&file_info);
|
||||
status = kernel_file->GetInfo(kernel_file, &fi_guid, &info_size, file_info);
|
||||
gBS->AllocatePool(EfiLoaderData, kinfo_size, (void**)&kfile_info);
|
||||
status = kernel_file->GetInfo(kernel_file, &fi_guid, &kinfo_size, kfile_info);
|
||||
}
|
||||
|
||||
if (EFI_ERROR(status)) {
|
||||
ST->ConOut->OutputString(ST->ConOut, L"Failed to allocate memory for buffer!!");
|
||||
print(L"Failed to allocate memory for buffer!!");
|
||||
while (1) __asm__("hlt");
|
||||
}
|
||||
|
||||
uint64_t kernel_size = file_info->FileSize;
|
||||
uint64_t kernel_size = kfile_info->FileSize;
|
||||
uintn_t kernel_size_read = (uintn_t)kernel_size;
|
||||
efi_physical_address_t kernel_addr = 0x100000;
|
||||
uintn_t pages = (kernel_size + 0xFFF) / 0x1000 + 32;
|
||||
uintn_t kernel_pages = (kernel_size + 0xFFF) / 0x1000 + 32;
|
||||
|
||||
status = gBS->AllocatePages(AllocateAddress, EfiLoaderData, pages, &kernel_addr);
|
||||
status = gBS->AllocatePages(AllocateAddress, EfiLoaderData, kernel_pages, &kernel_addr);
|
||||
if (EFI_ERROR(status)) {
|
||||
ST->ConOut->OutputString(ST->ConOut, L"Memory 0x100000 busy!\r\n");
|
||||
print(L"Memory 0x100000 busy!\r\n");
|
||||
while (1);
|
||||
}
|
||||
|
||||
kernel_file->Read(kernel_file, &kernel_size_read, (void*)kernel_addr); // scary!
|
||||
|
||||
Bootinfo *boot_info = NULL;
|
||||
|
||||
// initramfs
|
||||
Bootinfo* boot_info = nullptr;
|
||||
status = gBS->AllocatePool(EfiLoaderData, sizeof(Bootinfo), (void**)&boot_info);
|
||||
|
||||
boot_info->magic = BOOTINFO_MAGIC;
|
||||
|
||||
efi_file_handle_t* initramfs_file;
|
||||
uintn_t iinfo_size = 0;
|
||||
efi_file_info_t* ifile_info = nullptr;
|
||||
status = root->Open(root, &initramfs_file, L"initramfs.cpio", EFI_FILE_MODE_READ, 0);
|
||||
|
||||
if (EFI_ERROR(status)) {
|
||||
print_initramfs_warning(L"initramfs.cpio is missing");
|
||||
boot_info->initramfs.addr = nullptr;
|
||||
boot_info->initramfs.size = 0;
|
||||
} else {
|
||||
status = initramfs_file->GetInfo(initramfs_file, &fi_guid, &iinfo_size, nullptr);
|
||||
if (status == EFI_BUFFER_TOO_SMALL) {
|
||||
gBS->AllocatePool(EfiLoaderData, iinfo_size, (void**)&ifile_info);
|
||||
status = initramfs_file->GetInfo(initramfs_file, &fi_guid, &iinfo_size, ifile_info);
|
||||
}
|
||||
if (EFI_ERROR(status)) {
|
||||
print_initramfs_warning(L"failed to allocate memory for initramfs buffer!!");
|
||||
} else {
|
||||
// i hate that nesting
|
||||
uint64_t initramfs_size = ifile_info->FileSize;
|
||||
|
||||
uintn_t initramfs_pages = (initramfs_size + 0xFFF) / 0x1000;
|
||||
efi_physical_address_t initramfs_addr = 0;
|
||||
status = gBS->AllocatePages(AllocateAnyPages, EfiLoaderData, initramfs_pages, &initramfs_addr);
|
||||
if (EFI_ERROR(status)) {
|
||||
print_initramfs_warning(L"failed to allocate memory for initramfs itself!!");
|
||||
} else {
|
||||
// just fucking kill me
|
||||
uintn_t initramfs_size_read = (uintn_t)initramfs_size;
|
||||
initramfs_file->Read(initramfs_file, &initramfs_size_read, (void*)initramfs_addr);
|
||||
boot_info->initramfs.addr = (void*)initramfs_addr;
|
||||
boot_info->initramfs.size = initramfs_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boot_info->framebuffer.base = (uint32_t*)gop->Mode->FrameBufferBase;
|
||||
boot_info->framebuffer.base_size = gop->Mode->FrameBufferSize;
|
||||
boot_info->framebuffer.height = gop->Mode->Information->VerticalResolution;
|
||||
@@ -68,19 +118,19 @@ int main()
|
||||
boot_info->framebuffer.pitch = gop->Mode->Information->PixelsPerScanLine;
|
||||
|
||||
uintn_t map_size = 0;
|
||||
efi_memory_descriptor_t *map = NULL;
|
||||
efi_memory_descriptor_t *map = nullptr;
|
||||
uintn_t map_key;
|
||||
uintn_t desc_size;
|
||||
uint32_t desc_version;
|
||||
|
||||
ST->ConOut->OutputString(ST->ConOut, L"Almost ready to jump :D. Working with memory map\r\n");
|
||||
print(L"Almost ready to jump :D. Working with memory map\r\n");
|
||||
|
||||
gBS->GetMemoryMap(&map_size, NULL, &map_key, &desc_size, &desc_version);
|
||||
gBS->GetMemoryMap(&map_size, nullptr, &map_key, &desc_size, &desc_version);
|
||||
map_size += 4096;
|
||||
// woah letsgoo
|
||||
status = gBS->AllocatePool(EfiLoaderData, map_size, (void**)&map);
|
||||
if (EFI_ERROR(status)) {
|
||||
ST->ConOut->OutputString(ST->ConOut, L"Failed to allocate pool");
|
||||
print(L"Failed to allocate pool");
|
||||
}
|
||||
|
||||
do {
|
||||
|
||||
+12
-3
@@ -7,7 +7,7 @@ typedef unsigned int bi_u32;
|
||||
typedef unsigned long long bi_u64;
|
||||
|
||||
typedef struct {
|
||||
bi_u32 *base;
|
||||
bi_u32* base;
|
||||
bi_u64 base_size;
|
||||
bi_u64 width;
|
||||
bi_u64 height;
|
||||
@@ -15,7 +15,7 @@ typedef struct {
|
||||
} BI_Framebuffer;
|
||||
|
||||
typedef struct {
|
||||
void *map;
|
||||
void* map;
|
||||
bi_u64 map_size;
|
||||
bi_u64 descriptor_size;
|
||||
bi_u32 map_key;
|
||||
@@ -23,6 +23,15 @@ typedef struct {
|
||||
} BI_MemoryMap;
|
||||
|
||||
typedef struct {
|
||||
void* addr;
|
||||
bi_u64 size;
|
||||
} BI_Initramfs;
|
||||
|
||||
typedef struct {
|
||||
bi_u64 magic;
|
||||
BI_Framebuffer framebuffer;
|
||||
BI_MemoryMap mem;
|
||||
} Bootinfo;
|
||||
BI_Initramfs initramfs;
|
||||
} Bootinfo;
|
||||
|
||||
#define BOOTINFO_MAGIC 0x7E833055 // termOS
|
||||
@@ -0,0 +1 @@
|
||||
Meow!!
|
||||
@@ -0,0 +1 @@
|
||||
Nyaaa
|
||||
@@ -12,7 +12,7 @@ endif()
|
||||
message(STATUS "TermOS Kernel: Building for architecture '${ARCH}'")
|
||||
|
||||
|
||||
file(GLOB_RECURSE KERNEL_SOURCES
|
||||
file(GLOB_RECURSE KERNEL_SOURCES CMAKE_CONFIGURE_DEPENDS
|
||||
"src/kmain.c"
|
||||
|
||||
"src/arch/${ARCH}/*.c"
|
||||
@@ -22,6 +22,7 @@ file(GLOB_RECURSE KERNEL_SOURCES
|
||||
"src/drivers/*.c"
|
||||
"src/mm/*.c"
|
||||
"src/shell/*.c"
|
||||
"src/fs/*.c"
|
||||
|
||||
"data/*.c"
|
||||
)
|
||||
|
||||
@@ -5,3 +5,6 @@
|
||||
#include <types.h>
|
||||
|
||||
i32 strcmp(const char* s1, const char* s2);
|
||||
i32 strncmp(const char* s1, const char* s2, u64 n);
|
||||
char* strcpy(char* dest, const char* src);
|
||||
char* strncpy(char* dest, const char* src, u64 n);
|
||||
@@ -0,0 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright (c) 2026 0xKarinyash
|
||||
#pragma once
|
||||
#include <types.h>
|
||||
#include <fs/vfs.h>
|
||||
|
||||
u64 cpio_read(fs_node* node, u64 offset, u64 size, u8* buff);
|
||||
fs_node* cpio_mount(void* base, u64 size);
|
||||
@@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright (c) 2026 0xKarinyash
|
||||
#pragma once
|
||||
#include <types.h>
|
||||
|
||||
#define FS_FILE 0x01
|
||||
#define FS_DIR 0x02
|
||||
|
||||
struct fs_node;
|
||||
typedef struct fs_node fs_node;
|
||||
|
||||
typedef struct {
|
||||
u64 (*read)(struct fs_node* node, u64 offset, u64 size, u8* buff);
|
||||
u64 (*write)(struct fs_node* node, u64 offset, u64 size, u8* buff);
|
||||
void (*open)(struct fs_node* node);
|
||||
void (*close)(struct fs_node* node);
|
||||
|
||||
struct fs_node* (*finddir)(struct fs_node* node, char* name);
|
||||
} fs_ops;
|
||||
|
||||
struct fs_node {
|
||||
char name[256];
|
||||
u32 mask;
|
||||
u32 uid;
|
||||
u32 gid;
|
||||
u32 flags;
|
||||
u32 inode;
|
||||
u64 len;
|
||||
fs_ops* ops;
|
||||
void* impl_data;
|
||||
struct fs_node* ptr;
|
||||
struct fs_node* next;
|
||||
};
|
||||
@@ -100,14 +100,7 @@ void draw_panic_bg() {
|
||||
console_clear(0x000000);
|
||||
console_set_color(0xFFFFFF);
|
||||
console_set_default_color(0xFFFFFF);
|
||||
|
||||
// SG_Point p = console_get_dimensions();
|
||||
// p.x /= 2;
|
||||
// p.y /= 2;
|
||||
// p.y -= 200;
|
||||
|
||||
// console_set_cursor_pos(&p);
|
||||
|
||||
u64 msg_count = sizeof(fun_messages) / sizeof(fun_messages[0]);
|
||||
u8 rand_num = shitrand() % msg_count;
|
||||
|
||||
|
||||
@@ -9,4 +9,36 @@ i32 strcmp(const char *s1, const char *s2) {
|
||||
s2++;
|
||||
}
|
||||
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
|
||||
}
|
||||
|
||||
i32 strncmp(const char* s1, const char* s2, u64 n) {
|
||||
while (n > 0) {
|
||||
if (*s1 != *s2) return *(unsigned char*)s1 - *(unsigned char*)s2;
|
||||
if (*s1 == '\0') return 0;
|
||||
s1++;
|
||||
s2++;
|
||||
n--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* strcpy(char* dest, const char* src) {
|
||||
char* saved = dest;
|
||||
while (*src) *dest++ = *src++;
|
||||
*dest = 0;
|
||||
return saved;
|
||||
}
|
||||
|
||||
char* strncpy(char* dest, const char* src, u64 n) {
|
||||
char* saved = dest;
|
||||
while (*src && n > 0) {
|
||||
*dest++ = *src++;
|
||||
n--;
|
||||
}
|
||||
while (n > 0) {
|
||||
*dest++ = 0;
|
||||
n--;
|
||||
}
|
||||
return saved;
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright (c) 2026 0xKarinyash
|
||||
|
||||
#include <types.h>
|
||||
#include <fs/cpio.h>
|
||||
#include <fs/vfs.h>
|
||||
#include <core/string.h>
|
||||
#include <core/panic.h>
|
||||
#include <mm/memory.h>
|
||||
#include <mm/heap.h>
|
||||
#include <drivers/console.h>
|
||||
|
||||
#define ALIGN4(x) (((x) + 3) & ~3)
|
||||
|
||||
typedef struct {
|
||||
char c_magic[6]; // "070701"
|
||||
char c_ino[8];
|
||||
char c_mode[8]; // type and flags
|
||||
char c_uid[8];
|
||||
char c_gid[8];
|
||||
char c_nlink[8];
|
||||
char c_mtime[8];
|
||||
char c_filesize[8];
|
||||
char c_devmajor[8];
|
||||
char c_devminor[8];
|
||||
char c_rdevmajor[8];
|
||||
char c_rdevminor[8];
|
||||
char c_namesize[8]; // including \0
|
||||
char c_check[8]; // checksum (usually 0)
|
||||
} cpio_header;
|
||||
|
||||
static fs_ops cpio_ops = {
|
||||
.read = cpio_read,
|
||||
.write = nullptr,
|
||||
.open = nullptr,
|
||||
.close = nullptr,
|
||||
};
|
||||
|
||||
u64 hex_to_u64(const char* s, i32 len) {
|
||||
u64 res = 0;
|
||||
for (i32 i = 0; i < len; i++) {
|
||||
char c = s[i];
|
||||
res <<= 4;
|
||||
if (c >= '0' && c <= '9') res += (c - '0');
|
||||
else if (c >= 'A' && c <= 'F') res += (c - 'A' + 10);
|
||||
else if (c >= 'a' && c <= 'f') res += (c - 'a' + 10);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
u64 cpio_read(fs_node* node, u64 offset, u64 size, u8* buff) {
|
||||
if (offset > node->len) return 0; // EOF
|
||||
if ((offset + size) > node->len) size = node->len - offset;
|
||||
memcpy(buff, (char*)node->impl_data + offset, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
fs_node* cpio_mount(void* base, u64 size) {
|
||||
u8* ptr = (u8*)base;
|
||||
u8* end = ptr + size;
|
||||
|
||||
fs_node* root = malloc(sizeof(fs_node));
|
||||
if (!root) panic("CPIO: Failed to malloc for root node!");
|
||||
memset(root, 0, sizeof(fs_node));
|
||||
strcpy(root->name, "/");
|
||||
root->flags = FS_DIR;
|
||||
root->ops = &cpio_ops;
|
||||
|
||||
while (ptr < end) {
|
||||
cpio_header* header = (cpio_header*)ptr;
|
||||
|
||||
if (strncmp(header->c_magic, "070701", 6) != 0) panic("CPIO: Bad magic! Corrupted initramfs");
|
||||
u64 namesize = hex_to_u64(header->c_namesize, 8);
|
||||
u64 filesize = hex_to_u64(header->c_filesize, 8);
|
||||
|
||||
char* filename = (char*)(ptr + sizeof(cpio_header));
|
||||
if (strcmp(filename, "TRAILER!!!") == 0) break;
|
||||
|
||||
u64 header_and_name_len = sizeof(cpio_header) + namesize;
|
||||
u64 offset_to_data = ALIGN4(header_and_name_len);
|
||||
void* file_content = (void*)(ptr + offset_to_data);
|
||||
|
||||
fs_node* new_node = malloc(sizeof(fs_node));
|
||||
if (!new_node) panic("CPIO: Failed to malloc for new node!");
|
||||
memset(new_node, 0, sizeof(fs_node));
|
||||
strcpy(new_node->name, filename);
|
||||
|
||||
new_node->len = filesize;
|
||||
new_node->inode = hex_to_u64(header->c_ino, 8);
|
||||
new_node->ops = &cpio_ops;
|
||||
new_node->impl_data = file_content;
|
||||
|
||||
u64 mode = hex_to_u64(header->c_mode, 8);
|
||||
if ((mode & 0xF000) == 0x4000) new_node->flags = FS_DIR;
|
||||
else new_node->flags = FS_FILE;
|
||||
|
||||
kprintf("^bCPIO^!: Found file '^y%s^!' (size ^y%d^!) at ^y%x^!\n", filename, filesize, &file_content);
|
||||
|
||||
u64 data_len = ALIGN4(filesize);
|
||||
ptr += offset_to_data + data_len;
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright (c) 2026 0xKarinyash
|
||||
|
||||
+9
-2
@@ -2,7 +2,6 @@
|
||||
// Copyright (c) 2025 0xKarinyash
|
||||
|
||||
#include "bootinfo.h"
|
||||
#include "core/scheduler.h"
|
||||
#include <shell/ksh.h>
|
||||
|
||||
#include <types.h>
|
||||
@@ -13,6 +12,7 @@
|
||||
#include <drivers/timer.h>
|
||||
|
||||
#include <core/panic.h>
|
||||
#include <core/scheduler.h>
|
||||
#include <core/splash.h>
|
||||
|
||||
#include <gdt.h>
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <mm/vmm.h>
|
||||
#include <mm/heap.h>
|
||||
|
||||
#include <fs/cpio.h>
|
||||
|
||||
#define FG_COLOR 0xffffff
|
||||
#define BG_COLOR 0x111111
|
||||
|
||||
@@ -35,6 +37,8 @@ void kmain(Bootinfo* info) {
|
||||
|
||||
console_init(&sg_ctx);
|
||||
|
||||
if (info->magic != BOOTINFO_MAGIC) panic("Corrupt bootinfo!");
|
||||
|
||||
gdt_init();
|
||||
kprintf("GDT initialized\n");
|
||||
idt_init();
|
||||
@@ -52,10 +56,12 @@ void kmain(Bootinfo* info) {
|
||||
sched_init();
|
||||
kprintf("Scheduler initialized\n");
|
||||
sg_init(&sg_ctx);
|
||||
kprintf("Shitgui initialized");
|
||||
kprintf("Shitgui initialized\n");
|
||||
|
||||
info = (Bootinfo*)PHYS_TO_HHDM((u64)info);
|
||||
|
||||
cpio_mount(PHYS_TO_HHDM(info->initramfs.addr), info->initramfs.size);
|
||||
|
||||
u32 *fb = (u32*)info->framebuffer.base;
|
||||
if (!fb) return serial_write("No framebuffer found!!");
|
||||
|
||||
@@ -72,6 +78,7 @@ void kmain(Bootinfo* info) {
|
||||
|
||||
sched_spawn(composer_task);
|
||||
sched_spawn(ksh);
|
||||
if (!info->initramfs.addr) kprintf("^rWARNING^!: Failed to load ^yinitramfs^!, VFS is empty.\n\n");
|
||||
__asm__ volatile("sti");
|
||||
|
||||
while (true) __asm__ volatile("hlt");
|
||||
|
||||
@@ -49,8 +49,31 @@ void cmd_meow() {
|
||||
}
|
||||
|
||||
void cmd_help() {
|
||||
kprintf("\tWelcome to ^ptermOS^!'s kernel shell!\n");
|
||||
kprintf("\tIt can almost nothing! yet.\n");
|
||||
kprintf("Welcome to ^ptermOS^!'s ^gk^!ernel ^gsh^!ell!\n");
|
||||
kprintf("It loads when userspace is failed to load and acts as a basic rescue environment\n");
|
||||
kprintf("At this moment i dont have userspace so it loads always\n");
|
||||
kprintf("Available commands:\n");
|
||||
|
||||
kprintf("\t^rDebug^!:\n");
|
||||
kprintf("\t\t^ysleep^! \t\tSleep for 3seconds\n");
|
||||
kprintf("\t\t^ydbg^! \t\tTest new stuff\n");
|
||||
kprintf("\t\t^yregs^! \t\tPrint current regs\n");
|
||||
kprintf("\t\t^yrectest^! \t\tTSS test\n");
|
||||
kprintf("\t\t^ypanic^! \t\tPanics (lol)\n");
|
||||
kprintf("\t\t^yud2^! \t\tPanics with #UD\n");
|
||||
kprintf("\t\t^ypf^! \t\tPanics with #PF\n");
|
||||
|
||||
kprintf("\t^pFun^!:\n");
|
||||
kprintf("\t\t^ysplash^! \t\tShows splash (works kinda unstable)\n");
|
||||
kprintf("\t\t^ymeow^! \t\tcats!!!\n");
|
||||
kprintf("\t\t^ykfetch^! \t\tr/unixporn compatible\n");
|
||||
|
||||
kprintf("\t^gCustomisation^!:\n");
|
||||
kprintf("\t\t^yblinking^! \t\tDisable/Enable cursor blinking\n");
|
||||
|
||||
kprintf("\t^bMisc^!:\n");
|
||||
kprintf("\t\t^yclear^! \t\tClear console\n");
|
||||
kprintf("\t\t^yhelp^! \t\tShow this menu\n");
|
||||
}
|
||||
|
||||
void cmd_regs() {
|
||||
|
||||
+17
-14
@@ -35,7 +35,10 @@ typedef enum {
|
||||
TOKEN_PANIC_PF,
|
||||
|
||||
TOKEN_CLEAR,
|
||||
TOKEN_BLINKING
|
||||
TOKEN_BLINKING,
|
||||
|
||||
TOKEN_BACK,
|
||||
TOKEN_FORWARD,
|
||||
} ksh_token;
|
||||
|
||||
typedef struct {
|
||||
@@ -46,17 +49,10 @@ typedef struct {
|
||||
static const ksh_command_map token_map[] = {
|
||||
{"", TOKEN_EMPTY},
|
||||
|
||||
{"cls", TOKEN_CLEAR},
|
||||
{"clear", TOKEN_CLEAR},
|
||||
// customisation
|
||||
{"blinking", TOKEN_BLINKING},
|
||||
|
||||
{"meow", TOKEN_MEOW},
|
||||
{"nya", TOKEN_MEOW},
|
||||
{"splash", TOKEN_SPLASH},
|
||||
{"kfetch", TOKEN_KFETCH},
|
||||
{"fastfetch", TOKEN_KFETCH},
|
||||
{"neofetch", TOKEN_KFETCH},
|
||||
|
||||
// debug
|
||||
{"sleep", TOKEN_SLEEP},
|
||||
{"dbg", TOKEN_DEBUG},
|
||||
{"regs", TOKEN_REGS},
|
||||
@@ -65,8 +61,14 @@ static const ksh_command_map token_map[] = {
|
||||
{"ud2", TOKEN_PANIC_UD2},
|
||||
{"pf", TOKEN_PANIC_PF},
|
||||
|
||||
// fun
|
||||
{"meow", TOKEN_MEOW},
|
||||
{"splash", TOKEN_SPLASH},
|
||||
{"kfetch", TOKEN_KFETCH},
|
||||
|
||||
// misc
|
||||
{"help", TOKEN_HELP},
|
||||
{"clear", TOKEN_CLEAR},
|
||||
{nullptr, TOKEN_NULL}
|
||||
};
|
||||
|
||||
@@ -85,7 +87,10 @@ void ksh() {
|
||||
kgets(cmdbuff, 256);
|
||||
switch(char2token(cmdbuff)) {
|
||||
case TOKEN_EMPTY: continue;
|
||||
|
||||
|
||||
case TOKEN_CLEAR: console_clear((u32) console_get_colors() & 0xFFFFFFFF); break;
|
||||
case TOKEN_BLINKING: console_toggle_cursor_blink(); break;
|
||||
|
||||
case TOKEN_SLEEP: cmd_sleep(); break;
|
||||
case TOKEN_DEBUG: cmd_debug(); break;
|
||||
case TOKEN_REGS: cmd_regs(); break;
|
||||
@@ -95,12 +100,10 @@ void ksh() {
|
||||
case TOKEN_PANIC_PF: u64* bad_ptr = (u64*)0xDEADBEEF; *bad_ptr = 666;
|
||||
|
||||
case TOKEN_SPLASH: show_splash(console_get_context()); break;
|
||||
case TOKEN_CLEAR: console_clear((u32) console_get_colors() & 0xFFFFFFFF); break;
|
||||
case TOKEN_HELP: cmd_help(); break;
|
||||
case TOKEN_KFETCH: cmd_kfetch(); break;
|
||||
case TOKEN_MEOW: cmd_meow(); break;
|
||||
case TOKEN_BLINKING: console_toggle_cursor_blink(); break;
|
||||
|
||||
case TOKEN_HELP: cmd_help(); break;
|
||||
default: kprintf("Unknown command!!\n"); break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user