Merge pull request #12 from xamidev/programs

Programs: loading, 1 fake syscall.. (bad)
This commit was merged in pull request #12.
This commit is contained in:
xamidev
2024-09-23 16:41:44 +02:00
committed by GitHub
35 changed files with 293 additions and 19 deletions

View File

@@ -8,6 +8,7 @@
#include "../libc/string.h"
#include "initrd.h"
#include "system.h"
#include "kheap.h"
static unsigned int octal_to_int(const char* str, size_t size)
{
@@ -31,6 +32,18 @@ uint32_t tar_parse_size(const char* in)
return size;
}
uint32_t tar_get_size(tar_header_t* header)
{
uint32_t size = 0;
char* size_str = header->size;
for (int i=0; i<11 && size_str[i] != '\0'; i++)
{
size = size*8 + (size_str[i]-'0');
}
return size;
}
void tar_find_file(uint8_t *tar_start, const char* filename)
{
uint8_t *ptr = tar_start;
@@ -186,3 +199,52 @@ uint32_t tar_get_file_size(uint8_t* initrd, const char* filename)
}
return -1;
}
tar_header_t* tar_find(uint8_t* initrd, const char* filename)
{
tar_header_t* header = (tar_header_t*)initrd;
while (header->filename[0] != '\0')
{
if (strcmp(header->filename, filename) == 0)
{
return header;
}
uint32_t file_size = tar_get_size(header);
uint32_t file_blocks = (file_size + 511)/512;
header = (tar_header_t*) ((uintptr_t)header+(file_blocks+1)*512);
}
return NULL;
}
void* tar_get_file_content(tar_header_t* header)
{
return (void*) ((uintptr_t)header+512);
}
void* load_file_from_initrd(uint8_t* initrd, const char* filename)
{
tar_header_t* file = tar_find(initrd, filename);
if (file == NULL)
{
printf("'%s' not found\n", filename);
return NULL;
}
uint32_t file_size = tar_get_size(file);
void* file_data = malloc(file_size);
if (file_data == NULL)
{
printf("Malloc error for file '%s'\n", filename);
return NULL;
}
void* file_content = tar_get_file_content(file);
memcpy(file_data, file_content, file_size);
printf("[initrd] Loaded '%s' at 0x%x, size=%u\n", filename, (unsigned int)file_data, file_size);
return file_data;
}

View File

@@ -35,5 +35,6 @@ void ls_initrd(uint8_t* initrd, int verbose);
void cat_initrd(uint8_t* initrd, const char* filename);
int tar_file_to_buffer(uint8_t* initrd, const char* filename, char* buffer);
uint32_t tar_get_file_size(uint8_t* initrd, const char* filename);
void* load_file_from_initrd(uint8_t* initrd, const char* filename);
#endif

View File

@@ -25,6 +25,8 @@ extern void irq13();
extern void irq14();
extern void irq15();
extern void syscall_common_stub();
void *irq_routines[16] =
{
0, 0, 0, 0, 0, 0, 0, 0,
@@ -76,6 +78,8 @@ void irq_install()
idt_set_gate(46, (unsigned)irq14, 0x08, 0x8E);
idt_set_gate(47, (unsigned)irq15, 0x08, 0x8E);
printf("[kernel] installed irq 0-15\n");
idt_set_gate(0x80, (unsigned long)syscall_common_stub, 0x08, 0x8E);
}
void irq_handler(struct regs *r)

View File

@@ -6,6 +6,7 @@
#include "kheap.h"
#include <stdint.h>
#include "system.h"
#include "../libc/stdio.h"
// Free list allocator
@@ -17,6 +18,7 @@ void init_alloc()
free_list = (block_t*)heap;
free_list->size = HEAP_SIZE-sizeof(block_t);
free_list->next = NULL;
printf("[kernel] initialized heap and allocator, start=0x%x\n", heap);
}
void* malloc(size_t size)

View File

@@ -17,7 +17,6 @@ typedef struct block
#define HEAP_SIZE 1024*1024 // 1MB malloc-able
void init_alloc();
void* malloc(size_t size);
void free(void* ptr);

View File

@@ -15,7 +15,7 @@
#include "multiboot2.h"
#include "kheap.h"
#include "initrd.h"
#include "../programs/programs.h"
#include "../utils/utils.h"
#include "../libc/crypto.h"
void kmain(multiboot2_info *mb_info)
@@ -78,14 +78,14 @@ void kmain(multiboot2_info *mb_info)
if (mmap->addr != 0)
{
/*
serial_printf(3, "base addr=0x%x%x, length=0x%x%x, type=%u",
(uint32_t) (mmap->addr >> 32),
(uint32_t) (mmap->addr & 0xFFFFFFFF),
(uint32_t) (mmap->len >> 32),
(uint32_t) (mmap->len & 0xFFFFFFFF),
mmap->type);
*/
}
mmap = (struct multiboot_mmap_entry*) ((uint8_t*)mmap + mmap_tag->entry_size);
@@ -118,6 +118,8 @@ void kmain(multiboot2_info *mb_info)
printf("[debug] malloc test ptr1=0x%x, ptr2=0x%x\n", (unsigned int)ptr1, (unsigned int)ptr2);
free(ptr1); free(ptr2);
// usually the place where i do testing
timer_install();
keyboard_install();
printf("[kernel] spawning shell...\n");

View File

@@ -210,8 +210,39 @@ irq_common_stub:
add esp, 8
iret
; we'll be placing the syscall_common_stub here.
; push everything, then call syscall_handler (be sure to define it extern)
; then pop back everything and iret
extern syscall_handler
global syscall_common_stub
syscall_common_stub:
pusha
push ds
push es
push fs
push gs
mov eax, ds
push eax ; save ds
mov ax, 0x01 ; kernel segment YES I CHEATED I KNOW THIS SUCKS
mov ds, ax
mov es, ax
call syscall_handler
pop eax
mov ds, eax ; restore ds
pop gs
pop fs
pop es
pop ds
popa
iret
section .bss
align 4
resb KERNEL_STACK_SIZE
kernel_stack:
resb KERNEL_STACK_SIZE

View File

@@ -6,7 +6,7 @@
#include "system.h"
#include "../libc/stdio.h"
#include "../libc/string.h"
#include "../programs/programs.h"
#include "../utils/utils.h"
#include "../libc/crypto.h"
#include <stdint.h>
#include "../drivers/rtc.h"
@@ -146,6 +146,7 @@ void shell_install()
register_command("lspci", program_lspci);
register_command("naval", program_navalbattle);
register_command("snake", program_snake);
register_command("exec", program_exec);
for (;;)
{

33
src/kernel/syscalls.c Normal file
View File

@@ -0,0 +1,33 @@
// System calls
// Author: xamidev
// Licensed under the Unlicense. See the repo below.
// https://github.com/xamidev/blankos
#include "../libc/stdio.h"
void handle_syscall(int syscall_number)
{
switch(syscall_number)
{
case 1:
puts("Here's the syscall 1\n");
break;
default:
printf("[error] Invalid syscall number '%d'!\n", syscall_number);
break;
}
}
void syscall_handler()
{
int syscall_number;
void* arg;
// mov eax, syscall_number
// mov ebx, arg
asm volatile("mov %%eax, %0" : "=r"(syscall_number));
asm volatile("mov %%ebx, %0" : "=r"(arg));
printf("[syscall] syscall_number=%d, arg=%p\n", syscall_number, arg);
handle_syscall(syscall_number);
}

View File

@@ -39,5 +39,7 @@ extern volatile unsigned long global_ticks;
extern unsigned int g_multiboot_info_address;
void syscall_handler();
#endif

10
src/programs/hello.c Normal file
View File

@@ -0,0 +1,10 @@
void user_syscall(int syscall_no) {
asm volatile ("mov %0, %%eax" : : "r"(syscall_no));
asm volatile ("int $0x80");
}
void main()
{
user_syscall(1);
return;
}

View File

@@ -11,6 +11,8 @@
#include "../drivers/rtc.h"
#include "../kernel/io.h"
#include "../drivers/pci.h"
#include "../kernel/initrd.h"
#include "../kernel/kmain.h"
// Print a rainbow colorful text for testing
@@ -74,7 +76,7 @@ void program_uptime()
void program_help()
{
printf("help\tpanic\twords\tprimes\trainbow\tclear\nmath\tbf\t uptime echo\t sysinfo\tconway\nrot13 morse\tcowsay time\t read\t reboot\npi\t ls\t cat\t bmp\t lspci\t naval\nsnake\n");
printf("help\tpanic\twords\tprimes\trainbow\tclear\nmath\tbf\t uptime echo\t sysinfo\tconway\nrot13 morse\tcowsay time\t read\t reboot\npi\t ls\t cat\t bmp\t lspci\t naval\nsnake exec\n");
}
// Panic
@@ -133,7 +135,7 @@ void program_read(int argc, char* argv[])
}
}
// Reboots the machine (might just shutdown)
// Reboots the machine (might just shutdown) (or do nothing if youre lucky)
void program_reboot()
{
@@ -151,3 +153,24 @@ void program_lspci()
{
scan_pci_bus();
}
// Executes binary file
void program_exec(int argc, char* argv[])
{
if (argc < 2)
{
puts("Usage: exec <binary>\n");
return;
}
void* binary_file = load_file_from_initrd((uint8_t*)initrd_addr, argv[1]);
if (binary_file == NULL)
{
printf("[exec] Failed to load program '%s'.\n", argv[1]);
return;
}
void (*program_entry)() = (void (*)())binary_file;
program_entry();
}

72
src/utils/uhex.c Normal file
View File

@@ -0,0 +1,72 @@
// uhex (microhex) port for BlankOS; read-only version
// Author: xamidev
// Licensed under the Unlicense. See the repo below.
// https://github.com/xamidev/blankos
// This version is the port of a hex viewer which already was not great,
// and now by being here it is even worse because it is RO and will have
// hardcoded stuff in it (no ioctl, STDOUT, or other stuff here...)
/*
#define BYTES 1024
#define round(x) (int)(x < 0 ? (x -0.5) : x + 0.5)
// WIP: pushed but not done yet
void print_hex(unsigned char* buf, int byteno, int pos, int BYTES_PER_LINE)
{
for (int i=0; i<byteno; i++)
{
if (i%BYTES_PER_LINE == 0)
{
if (i != 0)
{
printf(" ");
for (int j=i-BYTES_PER_LINE; j<i; j++)
{
if (isprint(buf[j])) colorprintf(salmon, black, "%c", buf[j]);
else printf(".");
}
}
puts("\n");
if (pos == 0) printf("%06d: ", i);
else printf("%06d: ", pos);
}
printf("%2x", buf[i]);
}
int padding = BYTES_PER_LINE - (byteno % BYTES_PER_LINE);
if (padding < BYTES_PER_LINE)
{
for (int i=0; i<padding; i++) printf(" ");
printf(" ");
}
int start = byteno-(byteno%BYTES_PER_LINE);
for (int j=start; j<byteno; j++)
{
if (isprint(buf[j])) {
colorprintf(salmon, black, "%c", buf[j]);
} else {
printf(".");
}
}
puts("\n");
}
void program_uhex(int argc, char* argv[])
{
if (argc < 2)
{
printf("Usage: uhex <file>\nInline commands:\n\tpX - print position X\n\teX - edit position X\n\tq - quit\n");
return;
}
int BYTES_PER_LINE = 20;
}
*/

View File

@@ -3,8 +3,8 @@
// Licensed under the Unlicense. See the repo below.
// https://github.com/xamidev/blankos
#ifndef PROGRAMS_H
#define PROGRAMS_H
#ifndef UTILS_H
#define UTILS_H
void program_words();
void program_primes();
@@ -45,4 +45,7 @@ void program_navalbattle();
void program_conway();
void program_snake();
// Binaries loading and execution
void program_exec();
#endif