Compare commits

..

No commits in common. "aaff5a65e1f7af1291b8395f3b6ab747f90e76a5" and "36d07065fb1fc07abc09d6a38aa99c558c5365ac" have entirely different histories.

5 changed files with 52 additions and 84 deletions

View File

@ -45,7 +45,7 @@ namespace Kernel
public:
static Process* create_kernel();
static Process* create_kernel(entry_t, void*);
static BAN::ErrorOr<Process*> create_userspace(const Credentials&, BAN::StringView path, BAN::Span<BAN::StringView> arguments);
static BAN::ErrorOr<Process*> create_userspace(const Credentials&, BAN::StringView);
~Process();
void cleanup_function();
@ -185,7 +185,7 @@ namespace Kernel
BAN::ErrorOr<long> sys_load_keymap(const char* path);
BAN::RefPtr<TTY> controlling_terminal() { return m_controlling_terminal; }
TTY& tty() { ASSERT(m_controlling_terminal); return *m_controlling_terminal; }
static Process& current() { return Thread::current().process(); }

View File

@ -108,7 +108,7 @@ namespace Kernel
return process;
}
BAN::ErrorOr<Process*> Process::create_userspace(const Credentials& credentials, BAN::StringView path, BAN::Span<BAN::StringView> arguments)
BAN::ErrorOr<Process*> Process::create_userspace(const Credentials& credentials, BAN::StringView path)
{
auto* process = create_process(credentials, 0);
TRY(process->m_credentials.initialize_supplementary_groups());
@ -124,13 +124,9 @@ namespace Kernel
auto executable = TRY(ELF::load_from_inode(executable_inode, process->m_credentials, process->page_table()));
process->m_mapped_regions = BAN::move(executable.regions);
char** argv_addr = nullptr;
char** argv = nullptr;
{
size_t needed_bytes = sizeof(char*) + path.size() + 1;
for (auto argument : arguments)
needed_bytes += sizeof(char*) + argument.size() + 1;
needed_bytes += sizeof(char*);
size_t needed_bytes = sizeof(char*) * 2 + path.size() + 1;
if (auto rem = needed_bytes % PAGE_SIZE)
needed_bytes += PAGE_SIZE - rem;
@ -139,33 +135,18 @@ namespace Kernel
needed_bytes,
{ .start = 0x400000, .end = KERNEL_OFFSET },
MemoryRegion::Type::PRIVATE,
PageTable::Flags::UserSupervisor | PageTable::Flags::Present
PageTable::Flags::UserSupervisor | PageTable::Flags::ReadWrite | PageTable::Flags::Present
));
argv_addr = reinterpret_cast<char**>(argv_region->vaddr());
uintptr_t offset = sizeof(char*) * (1 + arguments.size() + 1);
for (size_t i = 0; i <= arguments.size(); i++)
{
const uintptr_t addr = argv_region->vaddr() + offset;
TRY(argv_region->copy_data_to_region(i * sizeof(char*), reinterpret_cast<const uint8_t*>(&addr), sizeof(char*)));
uintptr_t temp = argv_region->vaddr() + sizeof(char*) * 2;
MUST(argv_region->copy_data_to_region(0, (const uint8_t*)&temp, sizeof(char*)));
dprintln("argv[{}] = {H}", i * sizeof(char*), addr);
temp = 0;
MUST(argv_region->copy_data_to_region(sizeof(char*), (const uint8_t*)&temp, sizeof(char*)));
const auto current = (i == 0) ? path : arguments[i - 1];
TRY(argv_region->copy_data_to_region(offset, reinterpret_cast<const uint8_t*>(current.data()), current.size()));
MUST(argv_region->copy_data_to_region(sizeof(char*) * 2, (const uint8_t*)path.data(), path.size()));
dprintln(" argv[{}] = '{}'", offset, current);
const uint8_t zero = 0;
TRY(argv_region->copy_data_to_region(offset + current.size(), &zero, 1));
offset += current.size() + 1;
}
const uintptr_t zero = 0;
TRY(argv_region->copy_data_to_region((1 + arguments.size()) * sizeof(char*), reinterpret_cast<const uint8_t*>(&zero), sizeof(char*)));
TRY(process->m_mapped_regions.push_back(BAN::move(argv_region)));
MUST(process->m_mapped_regions.push_back(BAN::move(argv_region)));
}
if (executable_inode->mode().mode & +Inode::Mode::ISUID)
@ -183,8 +164,8 @@ namespace Kernel
process->m_is_userspace = true;
process->m_userspace_info.entry = executable.entry_point;
process->m_userspace_info.argc = 1 + arguments.size();
process->m_userspace_info.argv = argv_addr;
process->m_userspace_info.argc = 1;
process->m_userspace_info.argv = argv;
process->m_userspace_info.envp = nullptr;
auto* thread = MUST(Thread::create_userspace(process, process->page_table()));

View File

@ -20,42 +20,6 @@
namespace Kernel
{
class DevTTY : public TmpInode
{
public:
static BAN::ErrorOr<BAN::RefPtr<DevTTY>> create(mode_t mode, uid_t uid, gid_t gid)
{
return TRY(BAN::RefPtr<DevTTY>::create(mode | Inode::Mode::IFLNK, uid, gid));
}
protected:
BAN::ErrorOr<BAN::String> link_target_impl() override
{
auto terminal = Process::current().controlling_terminal();
if (!terminal)
return BAN::Error::from_errno(ENODEV);
return TRY(BAN::String::formatted("/dev/{}", terminal->name()));
}
bool can_read_impl() const override { return false; }
bool can_write_impl() const override { return false; }
bool has_error_impl() const override { return false; }
private:
DevTTY(mode_t mode, uid_t uid, gid_t gid)
: TmpInode(
DevFileSystem::get(),
MUST(DevFileSystem::get().allocate_inode(create_inode_info(mode, uid, gid))),
create_inode_info(mode, uid, gid)
)
{
ASSERT(this->mode().iflnk());
}
private:
friend class BAN::RefPtr<DevTTY>;
};
static BAN::RefPtr<TTY> s_tty;
static dev_t next_tty_rdev()
@ -87,6 +51,20 @@ namespace Kernel
{
s_tty = this;
clear();
auto inode_or_error = DevFileSystem::get().root_inode()->find_inode("tty"_sv);
if (inode_or_error.is_error())
{
if (inode_or_error.error().get_error_code() == ENOENT)
DevFileSystem::get().add_inode("tty"_sv, MUST(TmpSymlinkInode::create_new(DevFileSystem::get(), 0666, 0, 0, s_tty->name())));
else
dwarnln("{}", inode_or_error.error());
return;
}
auto inode = inode_or_error.release_value();
if (inode->mode().iflnk())
MUST(static_cast<TmpSymlinkInode&>(*inode.ptr()).set_link_target(name()));
}
BAN::ErrorOr<void> TTY::tty_ctrl(int command, int flags)
@ -160,8 +138,6 @@ namespace Kernel
auto* thread = MUST(Thread::create_kernel(&TTY::keyboard_task, nullptr, nullptr));
MUST(Processor::scheduler().add_thread(thread));
DevFileSystem::get().add_inode("tty", MUST(DevTTY::create(0666, 0, 0)));
initialized = true;
}

View File

@ -254,11 +254,7 @@ static void init2(void*)
TTY::initialize_devices();
MUST(Process::create_userspace({ 0, 0, 0, 0 }, "/usr/bin/init"_sv, {}));
auto console_path = MUST(BAN::String::formatted("/dev/{}", cmdline.console));
auto console_path_sv = console_path.sv();
MUST(Process::create_userspace({ 0, 0, 0, 0 }, "/usr/bin/init"_sv, BAN::Span<BAN::StringView>(&console_path_sv, 1)));
MUST(Process::create_userspace({ 0, 0, 0, 0 }, "/usr/bin/init"_sv));
}
extern "C" void ap_main()

View File

@ -2,6 +2,7 @@
#include <BAN/Optional.h>
#include <BAN/Vector.h>
#include <ctype.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdio.h>
@ -10,16 +11,18 @@
#include <sys/banan-os.h>
#include <termios.h>
int main(int argc, char** argv)
void initialize_stdio()
{
ASSERT(argc == 2);
const char* tty_name = argv[1];
if (open(tty_name, O_RDONLY | O_TTY_INIT) != 0) _exit(1);
if (open(tty_name, O_WRONLY) != 1) _exit(1);
if (open(tty_name, O_WRONLY) != 2) _exit(1);
const char* tty = "/dev/tty";
if (open(tty, O_RDONLY | O_TTY_INIT) != 0) _exit(1);
if (open(tty, O_WRONLY) != 1) _exit(1);
if (open(tty, O_WRONLY) != 2) _exit(1);
if (open("/dev/debug", O_WRONLY) != 3) _exit(1);
}
int main()
{
initialize_stdio();
if (signal(SIGINT, [](int) {}) == SIG_ERR)
perror("signal");
@ -77,6 +80,18 @@ int main(int argc, char** argv)
if (pwd == nullptr)
continue;
if (chown("/dev/tty", pwd->pw_uid, pwd->pw_gid) == -1)
{
perror("chown");
continue;
}
if (chmod("/dev/tty", 0600) == -1)
{
perror("chmod");
continue;
}
pid_t pid = fork();
if (pid == 0)
{