diff --git a/.gitignore b/.gitignore index 6827c05..ee3f05e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ blankos.iso iso/ i386-elf-7.5.0-Linux-x86_64/ i386-elf-7.5.0-Linux-x86_64.tar.xz +src/initrd/*.bin diff --git a/hello.bin b/hello.bin new file mode 100755 index 0000000..2021365 Binary files /dev/null and b/hello.bin differ diff --git a/makefile b/makefile index 0e216e4..ab2aa73 100644 --- a/makefile +++ b/makefile @@ -1,22 +1,27 @@ CC = i386-elf-7.5.0-Linux-x86_64/bin/i386-elf-gcc CFLAGS = -ffreestanding -g -Wall -Wextra -Wno-builtin-declaration-mismatch -mno-sse -mno-mmx -mno-avx -march=i386 -c -I src/ +LD = ld LDFLAGS = -T link.ld -melf_i386 AS = nasm ASFLAGS = -f elf +AR = i386-elf-7.5.0-Linux-x86_64/bin/i386-elf-ar SRC_DIR = src KERNEL_DIR = $(SRC_DIR)/kernel LIBC_DIR = $(SRC_DIR)/libc UTILS_DIR = $(SRC_DIR)/utils DRIVERS_DIR = $(SRC_DIR)/drivers +PROGRAMS_DIR = $(SRC_DIR)/programs INCLUDE_DIR = include FONTS_DIR = $(INCLUDE_DIR)/fonts OBJ_DIR = build C_SOURCES = $(wildcard $(KERNEL_DIR)/*.c) $(wildcard $(LIBC_DIR)/*.c) $(wildcard $(UTILS_DIR)/*.c) $(wildcard $(DRIVERS_DIR)/*.c) ASM_SOURCES = $(wildcard $(KERNEL_DIR)/*.s) $(wildcard $(LIBC_DIR)/*.s) $(wildcard $(UTILS_DIR)/*.s) $(wildcard $(DRIVERS_DIR)/*.s) +PROGRAM_SOURCES = $(wildcard $(PROGRAMS_DIR)/*.c) OBJECTS = $(patsubst $(SRC_DIR)/%, $(OBJ_DIR)/%, $(C_SOURCES:.c=.o) $(ASM_SOURCES:.s=.o)) +PROGRAM_OBJECTS = $(patsubst $(SRC_DIR)/%, $(OBJ_DIR)/%, $(PROGRAM_SOURCES:.c=.o)) TOOLCHAIN_SRC = https://newos.org/toolchains/i386-elf-7.5.0-Linux-x86_64.tar.xz TOOLCHAIN_FILE = i386-elf-7.5.0-Linux-x86_64.tar.xz @@ -24,14 +29,24 @@ TOOLCHAIN_FILE = i386-elf-7.5.0-Linux-x86_64.tar.xz FONT_OBJ = $(OBJ_DIR)/fonts/UniCyr_8x16.o FONT_SRC = $(FONTS_DIR)/UniCyr_8x16.psf -all: $(OBJ_DIR) kernel.elf +all: $(OBJ_DIR) lib kernel.elf programs $(OBJ_DIR): mkdir -p $(OBJ_DIR) - mkdir -p $(OBJ_DIR)/kernel $(OBJ_DIR)/libc $(OBJ_DIR)/utils $(OBJ_DIR)/drivers $(OBJ_DIR)/fonts + mkdir -p $(OBJ_DIR)/kernel $(OBJ_DIR)/libc $(OBJ_DIR)/utils $(OBJ_DIR)/drivers $(OBJ_DIR)/fonts $(OBJ_DIR)/programs +lib: $(OBJECTS) $(FONT_OBJ) + $(AR) rcs $(OBJ_DIR)/lib.a $(OBJECTS) $(FONT_OBJ) + kernel.elf: $(OBJECTS) $(FONT_OBJ) - ld $(LDFLAGS) $(OBJECTS) $(FONT_OBJ) -o kernel.elf + $(LD) $(LDFLAGS) $(OBJECTS) $(FONT_OBJ) -o kernel.elf + +programs: $(PROGRAM_OBJECTS) + @mkdir -p $(SRC_DIR)/initrd + @for prog in $(PROGRAM_OBJECTS); do \ + base=$$(basename $$prog .o); \ + $(LD) -melf_i386 -T program.ld $$prog $(OBJ_DIR)/lib.a -o $(SRC_DIR)/initrd/$$base.bin; \ + done $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(CC) $(CFLAGS) $< -o $@ @@ -66,5 +81,5 @@ debug: ./debug.sh clean: - rm -rf $(OBJ_DIR) kernel.elf blankos.iso $(TOOLCHAIN_FILE) + rm -rf $(OBJ_DIR) kernel.elf blankos.iso $(TOOLCHAIN_FILE) $(SRC_DIR)/initrd/*.bin diff --git a/program.ld b/program.ld new file mode 100644 index 0000000..dc36352 --- /dev/null +++ b/program.ld @@ -0,0 +1,10 @@ +OUTPUT_FORMAT(binary) +ENTRY(main) + +SECTIONS +{ + . = 0x1000; + .text : { *(.text*) } + .data : { *(.data*) } + .bss : { *(.bss*) } +} diff --git a/src/kernel/initrd.c b/src/kernel/initrd.c index 0742d4f..3183f20 100644 --- a/src/kernel/initrd.c +++ b/src/kernel/initrd.c @@ -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; @@ -174,3 +187,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("Loaded '%s' at 0x%x, size=%u\n", filename, (unsigned int)file_data, file_size); + + return file_data; +} diff --git a/src/kernel/initrd.h b/src/kernel/initrd.h index 714bf84..3772153 100644 --- a/src/kernel/initrd.h +++ b/src/kernel/initrd.h @@ -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 diff --git a/src/kernel/kmain.c b/src/kernel/kmain.c index b506a74..e64b0bb 100644 --- a/src/kernel/kmain.c +++ b/src/kernel/kmain.c @@ -118,6 +118,16 @@ 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 + + void* binary_file = load_file_from_initrd((uint8_t*)initrd_addr, "./hello.bin"); + if (binary_file == NULL) + { + printf("NOT LOADED...\n"); + } else { + printf("LOADED!\n"); + } + timer_install(); keyboard_install(); printf("[kernel] spawning shell...\n"); diff --git a/src/programs/hello.c b/src/programs/hello.c new file mode 100644 index 0000000..8cffe15 --- /dev/null +++ b/src/programs/hello.c @@ -0,0 +1,6 @@ +#include "../libc/stdio.h" + +void main() +{ + printf("Hello, world, from a PROGRAM!\n"); +}