Add: initrd filesystem utilities (ls, cat) + docs

This commit is contained in:
xamidev
2024-09-05 14:59:51 +02:00
parent b59af22897
commit d2034cd68b
10 changed files with 200 additions and 3 deletions

View File

@@ -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.

View File

@@ -113,3 +113,15 @@ Makes a cow speak!
#### `pi <terms>`
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 <file>`
Prints file content to terminal. Filename must be specified the same way as it is outputted when using `ls`.

104
src/kernel/initrd.c Normal file
View File

@@ -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 <stdint.h>
#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; i<filesize; i++)
{
putc(file_data[i]);
}
puts("\n");
return;
}
ptr += TAR_BLOCK_SIZE + ((filesize + TAR_BLOCK_SIZE-1) / TAR_BLOCK_SIZE) * TAR_BLOCK_SIZE;
}
printf("[tar] file '%s' not found\n", filename);
}
void ls_initrd(uint8_t* initrd)
{
tar_header_t *header = (tar_header_t*)initrd;
while (header->filename[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; i<size; i++) putc(file_content[i]);
return;
}
uint32_t next_file_offset = ((tar_parse_size(header->size)+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);
}

37
src/kernel/initrd.h Normal file
View File

@@ -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

View File

@@ -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");
}

View File

@@ -28,6 +28,7 @@ unsigned int g_multiboot_info_address;
uint32_t* framebuffer;
int scanline;
uint32_t initrd_addr;
// in characters, not pixels
uint32_t VGA_WIDTH;

View File

@@ -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 (;;)
{

24
src/programs/fs.c Normal file
View File

@@ -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 <file>\n");
return;
}
cat_initrd((uint8_t*)initrd_addr, argv[1]);
}

View File

@@ -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

View File

@@ -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