kernel/ELF+Scheduler: Use VFS instead of TarStream
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
c6aa2fe4ad
commit
ff468db675
@ -26,13 +26,14 @@ static bool can_write_segment(u32 flags)
|
|||||||
namespace ELFLoader
|
namespace ELFLoader
|
||||||
{
|
{
|
||||||
// FIXME: Check that all calls to read_contents() read the proper amount of bytes.
|
// FIXME: Check that all calls to read_contents() read the proper amount of bytes.
|
||||||
Result<ELFData> load(const TarStream::Entry& elf_entry, const TarStream& stream)
|
Result<ELFData> load(SharedPtr<VFS::Inode> inode)
|
||||||
{
|
{
|
||||||
Elf64_Ehdr elf_header;
|
Elf64_Ehdr elf_header;
|
||||||
usize nread = stream.read_contents(elf_entry, &elf_header, 0, sizeof elf_header);
|
usize nread = TRY(inode->read((u8*)&elf_header, 0, sizeof elf_header));
|
||||||
|
|
||||||
if (nread < sizeof elf_header)
|
if (nread < sizeof elf_header)
|
||||||
{
|
{
|
||||||
kdbgln("Error while loading ELF: ELF header does not fit in entry");
|
kdbgln("Error while loading ELF: ELF header does not fit in file");
|
||||||
return err(ENOEXEC);
|
return err(ENOEXEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,10 +79,10 @@ namespace ELFLoader
|
|||||||
usize i;
|
usize i;
|
||||||
Elf64_Phdr program_header;
|
Elf64_Phdr program_header;
|
||||||
|
|
||||||
for (stream.read_contents(elf_entry, &program_header, elf_header.e_phoff, sizeof program_header), i = 0;
|
for (TRY(inode->read((u8*)&program_header, elf_header.e_phoff, sizeof program_header)), i = 0;
|
||||||
i < elf_header.e_phnum;
|
i < elf_header.e_phnum;
|
||||||
i++, stream.read_contents(elf_entry, &program_header, elf_header.e_phoff + (i * elf_header.e_phentsize),
|
i++, TRY(inode->read((u8*)&program_header, elf_header.e_phoff + (i * elf_header.e_phentsize),
|
||||||
sizeof program_header))
|
sizeof program_header)))
|
||||||
{
|
{
|
||||||
if (program_header.p_type == PT_LOAD)
|
if (program_header.p_type == PT_LOAD)
|
||||||
{
|
{
|
||||||
@ -103,8 +104,7 @@ namespace ELFLoader
|
|||||||
base_vaddr, get_blocks_from_size(program_header.p_memsz + vaddr_diff, ARCH_PAGE_SIZE), flags));
|
base_vaddr, get_blocks_from_size(program_header.p_memsz + vaddr_diff, ARCH_PAGE_SIZE), flags));
|
||||||
|
|
||||||
// Load the file section of the segment
|
// Load the file section of the segment
|
||||||
stream.read_contents(elf_entry, (void*)program_header.p_vaddr, program_header.p_offset,
|
inode->read((u8*)program_header.p_vaddr, program_header.p_offset, program_header.p_filesz);
|
||||||
program_header.p_filesz);
|
|
||||||
|
|
||||||
// Fill out the rest of the segment with 0s
|
// Fill out the rest of the segment with 0s
|
||||||
memset((void*)(program_header.p_vaddr + program_header.p_filesz), 0,
|
memset((void*)(program_header.p_vaddr + program_header.p_filesz), 0,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "fs/VFS.h"
|
||||||
#include <luna/LinkedList.h>
|
#include <luna/LinkedList.h>
|
||||||
#include <luna/TarStream.h>
|
|
||||||
#include <luna/Types.h>
|
#include <luna/Types.h>
|
||||||
|
|
||||||
#define ELFMAG "\177ELF"
|
#define ELFMAG "\177ELF"
|
||||||
@ -54,5 +54,5 @@ struct ELFData
|
|||||||
|
|
||||||
namespace ELFLoader
|
namespace ELFLoader
|
||||||
{
|
{
|
||||||
Result<ELFData> load(const TarStream::Entry& elf_entry, const TarStream& stream);
|
Result<ELFData> load(SharedPtr<VFS::Inode> inode);
|
||||||
};
|
};
|
||||||
|
@ -63,18 +63,9 @@ static void init_vfs()
|
|||||||
|
|
||||||
static Result<void> try_init_userspace()
|
static Result<void> try_init_userspace()
|
||||||
{
|
{
|
||||||
TarStream::Entry entry;
|
auto app = TRY(VFS::resolve_path("/bin/app"));
|
||||||
g_initrd.rewind();
|
|
||||||
while (TRY(g_initrd.read_next_entry(entry)))
|
|
||||||
{
|
|
||||||
if (entry.type == TarStream::EntryType::RegularFile)
|
|
||||||
{
|
|
||||||
kinfoln("Found file %s in initial ramdisk, of size %s and mode %#ho", entry.name,
|
|
||||||
to_dynamic_unit(entry.size).release_value().chars(), entry.mode);
|
|
||||||
|
|
||||||
if (!strcmp(entry.name, "bin/app")) { TRY(Scheduler::new_userspace_thread(entry, g_initrd)); }
|
TRY(Scheduler::new_userspace_thread(app));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ namespace Scheduler
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<void> new_userspace_thread(const TarStream::Entry& entry, const TarStream& stream)
|
Result<void> new_userspace_thread(SharedPtr<VFS::Inode> inode)
|
||||||
{
|
{
|
||||||
Thread* const thread = TRY(new_thread());
|
Thread* const thread = TRY(new_thread());
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ namespace Scheduler
|
|||||||
|
|
||||||
thread->init_regs_user();
|
thread->init_regs_user();
|
||||||
|
|
||||||
const ELFData data = TRY(ELFLoader::load(entry, stream));
|
const ELFData data = TRY(ELFLoader::load(inode));
|
||||||
|
|
||||||
thread->set_ip(data.entry);
|
thread->set_ip(data.entry);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "fs/VFS.h"
|
||||||
#include "thread/Thread.h"
|
#include "thread/Thread.h"
|
||||||
#include <luna/TarStream.h>
|
|
||||||
|
|
||||||
namespace Scheduler
|
namespace Scheduler
|
||||||
{
|
{
|
||||||
@ -13,7 +13,7 @@ namespace Scheduler
|
|||||||
Result<void> new_kernel_thread(void (*func)(void));
|
Result<void> new_kernel_thread(void (*func)(void));
|
||||||
Result<void> new_kernel_thread(void (*func)(void*), void* arg);
|
Result<void> new_kernel_thread(void (*func)(void*), void* arg);
|
||||||
|
|
||||||
Result<void> new_userspace_thread(const TarStream::Entry& entry, const TarStream& stream);
|
Result<void> new_userspace_thread(SharedPtr<VFS::Inode> inode);
|
||||||
|
|
||||||
Thread* pick_task();
|
Thread* pick_task();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user