mirror of
https://github.com/usatiuk/ficus.git
synced 2025-10-29 00:27:52 +01:00
TarFs: janky tarfs for initramfs
This commit is contained in:
@@ -60,6 +60,9 @@ void PS2Keyboard::this_pooler() {
|
|||||||
case 0x34:
|
case 0x34:
|
||||||
r = 'g';
|
r = 'g';
|
||||||
break;
|
break;
|
||||||
|
case 0x4A:
|
||||||
|
r = '/';
|
||||||
|
break;
|
||||||
case 0x3C:
|
case 0x3C:
|
||||||
r = 'u';
|
r = 'u';
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include <FbTty.hpp>
|
#include <FbTty.hpp>
|
||||||
#include <LimineFramebuffer.hpp>
|
#include <LimineFramebuffer.hpp>
|
||||||
|
#include <TarFs.hpp>
|
||||||
|
|
||||||
void templates_tester() {
|
void templates_tester() {
|
||||||
// GlobalTtyManager.all_tty_putstr("Testing templates\n");
|
// GlobalTtyManager.all_tty_putstr("Testing templates\n");
|
||||||
@@ -53,31 +54,33 @@ void ktask_main() {
|
|||||||
|
|
||||||
(new Task(Task::TaskMode::TASKMODE_KERN, templates_tester, "templates_tester"))->start();
|
(new Task(Task::TaskMode::TASKMODE_KERN, templates_tester, "templates_tester"))->start();
|
||||||
(new Task(Task::TaskMode::TASKMODE_KERN, templates_tester, "templates_tester2"))->start();
|
(new Task(Task::TaskMode::TASKMODE_KERN, templates_tester, "templates_tester2"))->start();
|
||||||
VFSGlobals::mounts.add_mount(new MemFs(&VFSGlobals::root));
|
// (new Task(Task::TaskMode::TASKMODE_KERN, vfs_tester, "vfs_tester"))->start();
|
||||||
(new Task(Task::TaskMode::TASKMODE_KERN, vfs_tester, "vfs_tester"))->start();
|
|
||||||
Task *init;
|
|
||||||
for (int i = 0; i < saved_modules_size; i++) {
|
for (int i = 0; i < saved_modules_size; i++) {
|
||||||
auto &mod = saved_modules[i];
|
auto &mod = saved_modules[i];
|
||||||
|
|
||||||
VFSApi::touch(StrToPath(saved_modules_names[i]));
|
if (strcmp(saved_modules_names[i], "/sysroot.tar") == 0) {
|
||||||
FDT::FD fd = VFSApi::open(StrToPath(saved_modules_names[i]));
|
VFSGlobals::mounts.add_mount(new TarFs((char *) mod.address, mod.size, &VFSGlobals::root));
|
||||||
File *f = VFSApi::get(fd);
|
|
||||||
f->write(static_cast<const char *>(mod.address), mod.size);
|
|
||||||
|
|
||||||
if (strcmp(saved_modules_names[i], "/init") == 0) {
|
|
||||||
Vector<char> read_data(mod.size);
|
|
||||||
memcpy(read_data.begin(), mod.address, mod.size);
|
|
||||||
ElfParser elfParser(std::move(read_data));
|
|
||||||
|
|
||||||
init = new Task(Task::TaskMode::TASKMODE_USER, (void (*)()) elfParser.get_entrypoint(), saved_modules_names[i]);
|
|
||||||
if (!elfParser.copy_to(init))
|
|
||||||
assert2(false, "Init couldn't be loaded!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VFSApi::close(fd);
|
|
||||||
}
|
}
|
||||||
GlobalTtyManager.all_tty_putstr("Setup finished \n");
|
GlobalTtyManager.all_tty_putstr("Setup finished \n");
|
||||||
GlobalTtyManager.all_tty_putstr("Starting init \n");
|
GlobalTtyManager.all_tty_putstr("Starting init \n");
|
||||||
|
|
||||||
|
Task *init;
|
||||||
|
FDT::FD fd = VFSApi::open(StrToPath("/init"));
|
||||||
|
File *f = VFSApi::get(fd);
|
||||||
|
|
||||||
|
{
|
||||||
|
Vector<char> read_data(f->size());
|
||||||
|
f->read(read_data.data(), f->size());
|
||||||
|
ElfParser elfParser(std::move(read_data));
|
||||||
|
|
||||||
|
init = new Task(Task::TaskMode::TASKMODE_USER, (void (*)()) elfParser.get_entrypoint(), "/init");
|
||||||
|
if (!elfParser.copy_to(init))
|
||||||
|
assert2(false, "Init couldn't be loaded!");
|
||||||
|
}
|
||||||
|
|
||||||
|
VFSApi::close(fd);
|
||||||
|
|
||||||
init->start();
|
init->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,13 @@ add_custom_target(iso_limine)
|
|||||||
|
|
||||||
add_custom_target(iso
|
add_custom_target(iso
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/isodir/
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/isodir/
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/initramfs/
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/limine.cfg ${CMAKE_CURRENT_BINARY_DIR}/isodir/
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/limine.cfg ${CMAKE_CURRENT_BINARY_DIR}/isodir/
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:kernel.elf> ${CMAKE_CURRENT_BINARY_DIR}/isodir/ficus.elf
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:kernel.elf> ${CMAKE_CURRENT_BINARY_DIR}/isodir/ficus.elf
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:init> ${CMAKE_CURRENT_BINARY_DIR}/isodir/init
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:init> ${CMAKE_CURRENT_BINARY_DIR}/initramfs/init
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:hello2> ${CMAKE_CURRENT_BINARY_DIR}/isodir/hello2
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:hello2> ${CMAKE_CURRENT_BINARY_DIR}/initramfs/hello2
|
||||||
|
# TODO: this might not work when there are special symbols in path...
|
||||||
|
COMMAND pax -wvf ${CMAKE_CURRENT_BINARY_DIR}/isodir/sysroot.tar -s ":^${CMAKE_CURRENT_BINARY_DIR}/initramfs/::" ${CMAKE_CURRENT_BINARY_DIR}/initramfs
|
||||||
COMMAND xorriso -as mkisofs -b limine-bios-cd.bin -no-emul-boot -boot-load-size 4 -boot-info-table --efi-boot limine-uefi-cd.bin -efi-boot-part --efi-boot-image --protective-msdos-label ${CMAKE_CURRENT_BINARY_DIR}/isodir -o ${CMAKE_CURRENT_BINARY_DIR}/ficus.iso
|
COMMAND xorriso -as mkisofs -b limine-bios-cd.bin -no-emul-boot -boot-load-size 4 -boot-info-table --efi-boot limine-uefi-cd.bin -efi-boot-part --efi-boot-image --protective-msdos-label ${CMAKE_CURRENT_BINARY_DIR}/isodir -o ${CMAKE_CURRENT_BINARY_DIR}/ficus.iso
|
||||||
COMMAND ${tools}/limine/prefix/bin/limine bios-install ${CMAKE_CURRENT_BINARY_DIR}/ficus.iso
|
COMMAND ${tools}/limine/prefix/bin/limine bios-install ${CMAKE_CURRENT_BINARY_DIR}/ficus.iso
|
||||||
VERBATIM
|
VERBATIM
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ TIMEOUT=1
|
|||||||
|
|
||||||
# Path to the kernel to boot. boot:/// represents the partition on which limine.cfg is located.
|
# Path to the kernel to boot. boot:/// represents the partition on which limine.cfg is located.
|
||||||
KERNEL_PATH=boot:///ficus.elf
|
KERNEL_PATH=boot:///ficus.elf
|
||||||
|
MODULE_PATH=boot:///sysroot.tar
|
||||||
MODULE_PATH=boot:///init
|
|
||||||
MODULE_PATH=boot:///hello2
|
|
||||||
|
|
||||||
# Same thing, but without KASLR.
|
# Same thing, but without KASLR.
|
||||||
:ficus (KASLR off)
|
:ficus (KASLR off)
|
||||||
@@ -20,5 +18,4 @@ TIMEOUT=1
|
|||||||
KASLR=no
|
KASLR=no
|
||||||
|
|
||||||
KERNEL_PATH=boot:///ficus.elf
|
KERNEL_PATH=boot:///ficus.elf
|
||||||
MODULE_PATH=boot:///init
|
MODULE_PATH=boot:///sysroot.tar
|
||||||
MODULE_PATH=boot:///hello2
|
|
||||||
|
|||||||
@@ -13,4 +13,5 @@ target_sources(kernel.elf PRIVATE
|
|||||||
File.cpp
|
File.cpp
|
||||||
PipeFs.cpp
|
PipeFs.cpp
|
||||||
TtyPipe.cpp
|
TtyPipe.cpp
|
||||||
|
TarFs.cpp
|
||||||
)
|
)
|
||||||
147
src/kernel/vfs/TarFs.cpp
Normal file
147
src/kernel/vfs/TarFs.cpp
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 01.05.2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "TarFs.hpp"
|
||||||
|
|
||||||
|
#include <TtyManager.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
TarFs::TarFs(char *backing, size_t backing_size, NodeDir *mounted_on) : Filesystem(mounted_on), _backing((tar_header *) backing), _backing_size(backing_size) {
|
||||||
|
int i = 2;
|
||||||
|
|
||||||
|
const tar_header *header = _backing;
|
||||||
|
|
||||||
|
SkipListMap<String, ino_t> dir_map;
|
||||||
|
|
||||||
|
dir_map.emplace("", 1);
|
||||||
|
_dir_map.emplace(1, Vector<DirEntry>());
|
||||||
|
|
||||||
|
// FIXME: all this is extremely inefficient
|
||||||
|
// Also recheck that directories are handled correctly
|
||||||
|
while (true) {
|
||||||
|
if (header->filename[0] == '\0')
|
||||||
|
break;
|
||||||
|
unsigned int size = header_size(header);
|
||||||
|
|
||||||
|
int new_ino = i++;
|
||||||
|
_off_map.emplace(new_ino, header);
|
||||||
|
|
||||||
|
String pref = "";
|
||||||
|
String name = "";
|
||||||
|
|
||||||
|
{
|
||||||
|
Path p = StrToPath(header->filename);
|
||||||
|
if (p.size() > 1) {
|
||||||
|
pref += p[0];
|
||||||
|
for (int i = 1; i < p.size() - 1; i++) {
|
||||||
|
pref += "/";
|
||||||
|
pref += p[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
name = p.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header->typeflag[0] == '5') {
|
||||||
|
String fullname;
|
||||||
|
if (pref.length() > 0) {
|
||||||
|
fullname += pref;
|
||||||
|
fullname += "/";
|
||||||
|
}
|
||||||
|
fullname += name;
|
||||||
|
if (dir_map.find(fullname) == dir_map.end()) {
|
||||||
|
dir_map.emplace(fullname, new_ino);
|
||||||
|
_dir_map.emplace(new_ino, Vector<DirEntry>());
|
||||||
|
}
|
||||||
|
if (dir_map.find(pref) == dir_map.end()) {
|
||||||
|
int dir_ino = i++;
|
||||||
|
dir_map.emplace(pref, dir_ino);
|
||||||
|
_dir_map.emplace(dir_ino, Vector<DirEntry>());
|
||||||
|
}
|
||||||
|
auto p = dir_map.find(pref);
|
||||||
|
auto d = _dir_map.find(p->second);
|
||||||
|
d->second.emplace_back(name, new_ino);
|
||||||
|
} else if (header->typeflag[0] == '\0' || header->typeflag[0] == '0') {
|
||||||
|
if (dir_map.find(pref) == dir_map.end()) {
|
||||||
|
int dir_ino = i++;
|
||||||
|
dir_map.emplace(pref, dir_ino);
|
||||||
|
_dir_map.emplace(dir_ino, Vector<DirEntry>());
|
||||||
|
}
|
||||||
|
auto p = dir_map.find(pref);
|
||||||
|
auto d = _dir_map.find(p->second);
|
||||||
|
d->second.emplace_back(name, new_ino);
|
||||||
|
} else {
|
||||||
|
GlobalTtyManager.all_tty_putstr("Skipping tar: ");
|
||||||
|
GlobalTtyManager.all_tty_putstr(pref.c_str());
|
||||||
|
GlobalTtyManager.all_tty_putstr("/");
|
||||||
|
GlobalTtyManager.all_tty_putstr(name.c_str());
|
||||||
|
GlobalTtyManager.all_tty_putstr("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
header = (const tar_header *) (((char *) (header)) + ((size / 512) + 1) * 512);
|
||||||
|
|
||||||
|
if (size % 512)
|
||||||
|
header = (const tar_header *) (((char *) (header)) + 512);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedPtr<NodeDir> TarFs::root() {
|
||||||
|
return static_ptr_cast<NodeDir>(get_node(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedPtr<Node> TarFs::get_node(ino_t inode) {
|
||||||
|
if (_dir_map.find(inode) != _dir_map.end()) {
|
||||||
|
return static_ptr_cast<Node>(TarFsNodeDir::create(this, inode));
|
||||||
|
} else {
|
||||||
|
return static_ptr_cast<Node>(TarFsNodeFile::create(this, inode));
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<DirEntry> TarFs::TarFsNodeDir::children() {
|
||||||
|
return static_cast<TarFs *>(_fs)->_dir_map.find(_ino)->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
ino_t TarFs::TarFsNodeDir::mkdir(const String &name) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ino_t TarFs::TarFsNodeDir::mkfile(const String &name) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t TarFs::TarFsNodeFile::read(char *buf, size_t start, size_t num) {
|
||||||
|
TarFs *tar_fs = static_cast<TarFs *>(_fs);
|
||||||
|
|
||||||
|
if (auto entry = tar_fs->_off_map.find(_ino); entry != tar_fs->_off_map.end()) {
|
||||||
|
num = std::min(num, size() - start);
|
||||||
|
for (size_t i = 0; i < num; i++) {
|
||||||
|
buf[i] = (((char *) entry->second) + 512)[start + i];
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t TarFs::TarFsNodeFile::write(const char *buf, size_t start, size_t num) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t TarFs::TarFsNodeFile::size() {
|
||||||
|
TarFs *tar_fs = static_cast<TarFs *>(_fs);
|
||||||
|
|
||||||
|
if (auto entry = tar_fs->_off_map.find(_ino); entry != tar_fs->_off_map.end()) {
|
||||||
|
return header_size(entry->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t TarFs::header_size(const tar_header *hdr) {
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
|
size_t count = 1;
|
||||||
|
for (int j = 11; j > 0; j--, count *= 8)
|
||||||
|
size += ((hdr->size[j - 1] - '0') * count);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
79
src/kernel/vfs/TarFs.hpp
Normal file
79
src/kernel/vfs/TarFs.hpp
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 01.05.2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef TARFS_HPP
|
||||||
|
#define TARFS_HPP
|
||||||
|
|
||||||
|
#include <Filesystem.hpp>
|
||||||
|
|
||||||
|
class TarFs : public Filesystem {
|
||||||
|
public:
|
||||||
|
TarFs(char *backing, size_t backing_size, NodeDir *mounted_on);
|
||||||
|
~TarFs() override = default;
|
||||||
|
|
||||||
|
SharedPtr<NodeDir> root() override;
|
||||||
|
SharedPtr<Node> get_node(ino_t inode) override;
|
||||||
|
|
||||||
|
|
||||||
|
struct TarFsNodeDir : public ::NodeDir {
|
||||||
|
public:
|
||||||
|
~TarFsNodeDir() override = default;
|
||||||
|
|
||||||
|
Vector<DirEntry> children() override;
|
||||||
|
ino_t mkdir(const String &name) override;
|
||||||
|
ino_t mkfile(const String &name) override;
|
||||||
|
|
||||||
|
static SharedPtr<TarFsNodeDir> create(Filesystem *fs, ino_t id) {
|
||||||
|
auto shared = SharedPtr(new TarFsNodeDir(fs, id));
|
||||||
|
shared->_self_weak = static_ptr_cast<Node>(shared);
|
||||||
|
return shared;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TarFsNodeDir(Filesystem *fs, ino_t id) : ::NodeDir(fs, id) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TarFsNodeFile : public ::NodeFile {
|
||||||
|
public:
|
||||||
|
~TarFsNodeFile() override = default;
|
||||||
|
|
||||||
|
int64_t read(char *buf, size_t start, size_t num) override;
|
||||||
|
int64_t write(const char *buf, size_t start, size_t num) override;
|
||||||
|
size_t size() override;
|
||||||
|
bool is_tty() override { return false; }
|
||||||
|
|
||||||
|
static SharedPtr<TarFsNodeFile> create(Filesystem *fs, ino_t id) {
|
||||||
|
auto shared = SharedPtr(new TarFsNodeFile(fs, id));
|
||||||
|
shared->_self_weak = static_ptr_cast<Node>(shared);
|
||||||
|
return shared;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TarFsNodeFile(Filesystem *fs, ino_t id) : ::NodeFile(fs, id) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct tar_header {
|
||||||
|
char filename[100];
|
||||||
|
char mode[8];
|
||||||
|
char uid[8];
|
||||||
|
char gid[8];
|
||||||
|
char size[12];
|
||||||
|
char mtime[12];
|
||||||
|
char chksum[8];
|
||||||
|
char typeflag[1];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
const tar_header *_backing;
|
||||||
|
size_t _backing_size;
|
||||||
|
|
||||||
|
SkipListMap<ino_t, const tar_header *> _off_map;
|
||||||
|
SkipListMap<ino_t, Vector<DirEntry>> _dir_map;
|
||||||
|
// SkipListMap<ino_t, SharedPtr<Node>> _vnode_map;
|
||||||
|
|
||||||
|
static size_t header_size(const tar_header *hdr);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //TARFS_HPP
|
||||||
Reference in New Issue
Block a user