diff --git a/docs/DEVELOPERS.md b/docs/DEVELOPERS.md index 8883249..5c880e8 100644 --- a/docs/DEVELOPERS.md +++ b/docs/DEVELOPERS.md @@ -7,6 +7,7 @@ - Emulated booting in UEFI mode - Writing programs for BlankOS - Changing the TTY font +- Changing the initial ramdisk content ## Getting Started @@ -119,3 +120,10 @@ readelf -s -W build/fonts/YOUR_FONT_8x16.o Get the symbol name that ends with `_start` and replace all occurences of it in the `src/drivers/framebuffer.c` file. Then, run `make` again and the font should have changed properly. + +## Changing the initial ramdisk content + +The system loads an initial ramdisk as a simple TAR file located in `iso/boot/initrd.tar`. +You can add, delete, or modify this file's contents by doing that in the `src/initrd` folder. Anything in that folder will be added to the initial ramdisk and will therefore be loaded into the system. + +The ramdisk gets loaded as a GRUB2 module. diff --git a/docs/USERS.md b/docs/USERS.md index 3adbd6d..44a2e2c 100644 --- a/docs/USERS.md +++ b/docs/USERS.md @@ -113,3 +113,15 @@ Makes a cow speak! #### `pi ` Computes Pi up to a couple of digits using the Leibniz series; takes one integer argument, the number of terms of the series to compute. + +### Initrd utilities + +You can browse the (really) simple TAR filesystem with the following commands: + +#### `ls` + +Lists all files present in `initrd.tar`. + +#### `cat ` + +Prints file content to terminal. Filename must be specified the same way as it is outputted when using `ls`. diff --git a/src/kernel/initrd.c b/src/kernel/initrd.c new file mode 100644 index 0000000..384549c --- /dev/null +++ b/src/kernel/initrd.c @@ -0,0 +1,104 @@ +// Initial TAR ramdisk kernel module +// Author: xamidev +// Licensed under the Unlicense. See the repo below. +// https://github.com/xamidev/blankos + +#include "../libc/stdio.h" +#include +#include "../libc/string.h" +#include "initrd.h" +#include "system.h" + +static unsigned int octal_to_int(const char* str, size_t size) +{ + unsigned int result = 0; + while (*str && size-- > 0) + { + result = (result << 3) | (*str - '0'); + str++; + } + return result; +} + +uint32_t tar_parse_size(const char* in) +{ + uint32_t size = 0; + while (*in >= '0' && *in <= '7') + { + size = (size*8) + (*in - '0'); + in++; + } + return size; +} + +void tar_find_file(uint8_t *tar_start, const char* filename) +{ + uint8_t *ptr = tar_start; + + while (1) + { + tar_header_t *header = (tar_header_t*)ptr; + + if (header->filename[0] == '\0') + { + puts("[tar] EOF\n"); + break; + } + + unsigned int filesize = octal_to_int(header->size, 11); + + if (strcmp(header->filename, filename) == 0) + { + printf("[tar] found file '%s', size=%u bytes\n", header->filename, filesize); + + uint8_t *file_data = ptr+TAR_BLOCK_SIZE; + printf("[tar] content of '%s':\n", filename); + for (unsigned int i=0; ifilename[0] != '\0') + { + printf("%s\n", header->filename); + uint32_t size = tar_parse_size(header->size); + + uint32_t next_file_offset = ((size+TAR_BLOCK_SIZE-1)/TAR_BLOCK_SIZE)*TAR_BLOCK_SIZE; + header = (tar_header_t*)((uint8_t*)header + next_file_offset + TAR_BLOCK_SIZE); + } +} + +void cat_initrd(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) + { + uint32_t size = tar_parse_size(header->size); + uint8_t* file_content = (uint8_t*)header + 512; + + for (uint32_t i=0; isize)+TAR_BLOCK_SIZE-1)/TAR_BLOCK_SIZE)*TAR_BLOCK_SIZE; + header = (tar_header_t*)((uint8_t*)header + next_file_offset + TAR_BLOCK_SIZE); + } + + printf("File '%s' not found\n", filename); +} diff --git a/src/kernel/initrd.h b/src/kernel/initrd.h new file mode 100644 index 0000000..2bc28ee --- /dev/null +++ b/src/kernel/initrd.h @@ -0,0 +1,37 @@ +// Initial TAR ramdisk kernel module header +// Author: xamidev +// Licensed under the Unlicense. See the repo below. +// https://github.com/xamidev/blankos + +#ifndef INITRD_H +#define INITRD_H + +#define TAR_BLOCK_SIZE 512 + +#include "system.h" + +typedef struct +{ + char filename[100]; + char mode[8]; + char owner[8]; + char group[8]; + char size[12]; + char mtime[12]; + char checksum[8]; + char typeflag; + char linkname[100]; + char magic[6]; + char version[2]; + char uname[32]; + char gname[32]; + char devmajor[8]; + char devminor[8]; + char prefix[155]; +} tar_header_t; + +void tar_find_file(uint8_t *tar_start, const char* filename); +void ls_initrd(uint8_t* initrd); +void cat_initrd(uint8_t* initrd, const char* filename); + +#endif diff --git a/src/kernel/kmain.c b/src/kernel/kmain.c index 5482248..d0d0177 100644 --- a/src/kernel/kmain.c +++ b/src/kernel/kmain.c @@ -14,6 +14,7 @@ #include "kmain.h" #include "multiboot2.h" #include "kheap.h" +#include "initrd.h" void kmain(multiboot2_info *mb_info) { @@ -89,11 +90,15 @@ void kmain(multiboot2_info *mb_info) } if (initrd_module) { + initrd_addr = initrd_module->mod_start; + uint32_t initrd_start = initrd_module->mod_start; uint32_t initrd_end = initrd_module->mod_end; uint32_t initrd_size = initrd_end - initrd_start; printf("[kernel] TAR initrd module found at 0x%x, size=%u bytes\n", initrd_start, initrd_size); + //tar_find_file((uint8_t*)initrd_start, "./hello.txt"); + } else { puts("[kernel] TAR initrd module not found\n"); } diff --git a/src/kernel/kmain.h b/src/kernel/kmain.h index 7c7ce2d..0cf54ba 100644 --- a/src/kernel/kmain.h +++ b/src/kernel/kmain.h @@ -28,9 +28,10 @@ unsigned int g_multiboot_info_address; uint32_t* framebuffer; int scanline; +uint32_t initrd_addr; // in characters, not pixels uint32_t VGA_WIDTH; uint32_t VGA_HEIGHT; -#endif \ No newline at end of file +#endif diff --git a/src/kernel/shell.c b/src/kernel/shell.c index 5189f63..50af365 100644 --- a/src/kernel/shell.c +++ b/src/kernel/shell.c @@ -136,6 +136,8 @@ void shell_install() register_command("read", program_read); register_command("reboot", program_reboot); register_command("pi", program_pi); + register_command("ls", program_ls); + register_command("cat", program_cat); for (;;) { diff --git a/src/programs/fs.c b/src/programs/fs.c new file mode 100644 index 0000000..79785c4 --- /dev/null +++ b/src/programs/fs.c @@ -0,0 +1,24 @@ +// Filesystem utilities (for initrd) +// Author: xamidev +// Licensed under the Unlicense. See the repo below. +// https://github.com/xamidev/blankos + +#include "../kernel/initrd.h" +#include "../kernel/kmain.h" +#include "../libc/stdio.h" + +void program_ls() +{ + ls_initrd((uint8_t*)initrd_addr); +} + +// Basic cat just to read, no concatenation here +void program_cat(int argc, char* argv[]) +{ + if (argc != 2) + { + puts("Usage: cat \n"); + return; + } + cat_initrd((uint8_t*)initrd_addr, argv[1]); +} diff --git a/src/programs/misc.c b/src/programs/misc.c index fa3be2c..23a5210 100644 --- a/src/programs/misc.c +++ b/src/programs/misc.c @@ -73,7 +73,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\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\n"); } // Panic diff --git a/src/programs/programs.h b/src/programs/programs.h index 4150b6a..495e957 100644 --- a/src/programs/programs.h +++ b/src/programs/programs.h @@ -13,7 +13,7 @@ void program_bf(); void program_sysinfo(); void get_cpuid(); -void get_meminfo(unsigned int multiboot_info_address); +void get_meminfo(unsigned int multiboot_info_address); // to be fixed: cannot get full memory map (sysinfo -v) void program_conway(); void program_cowsay(); void cowsay(); // Splash screen @@ -34,4 +34,8 @@ void program_time(); void program_read(); void program_reboot(); +// Filesystem (initrd) +void program_ls(); +void program_cat(); + #endif