Add: initrd filesystem utilities (ls, cat) + docs
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
104
src/kernel/initrd.c
Normal 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
37
src/kernel/initrd.h
Normal 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
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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
|
||||
#endif
|
||||
|
||||
@@ -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
24
src/programs/fs.c
Normal 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]);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user