Compare commits

..

21 Commits

Author SHA1 Message Date
bb7d460149
kernel/ATA: Pass extra information to DeviceRegistry
All checks were successful
continuous-integration/drone/pr Build is passing
This is needed since merging e7d482e from main.
2023-05-20 22:01:07 +02:00
51ca93d2b4
kernel+init: Create a device node in /dev to access the CDROM from userspace!
Still using PIO, though.
2023-05-20 22:01:07 +02:00
e1a6282fee
kernel/ATA: Read the CDROM's first sector using ATAPI PIO!!
Sadly, for some reason, DMA is not working right now.
This is a problem, as PIO is inconvenient. But hey, it works for now!
2023-05-20 22:01:07 +02:00
1437127455
kernel/x86_64: Implement writing to PCI fields 2023-05-20 22:01:07 +02:00
18d21abe8f
kernel/PCI: Add bit enum for the Command field 2023-05-20 22:01:07 +02:00
2a04adfe06
kernel: Actually register interrupt handlers properly 2023-05-20 22:01:07 +02:00
61fc1e9548
kernel/ATA: Calculate block sizes for ATA devices as well 2023-05-20 22:01:06 +02:00
d8b9ea4157
kernel/ATA: Send a READ CAPACITY packet to an ATA drive on initialization 2023-05-20 22:01:06 +02:00
1fbc8d0dda
kernel/ATA: Read the PCI Busmaster registers and start preparing for DMA 2023-05-20 22:01:06 +02:00
ebb6452ee6
kernel/ATA: Read the Busmaster base port and verify it 2023-05-20 22:01:06 +02:00
36386e541b
kernel: Handle device BARs properly 2023-05-20 22:01:06 +02:00
e81acab407
kernel/ATA: Read ATA strings properly instead of backwards
Now we can see the model string. What does it say...

"QEMU DVD-ROM". Let's go!
2023-05-20 22:01:06 +02:00
4db6bb25b8
kernel/ATA: Implement enough to send an IDENTIFY command and read the model number :) 2023-05-20 22:01:06 +02:00
57ccac47aa
kernel/ATA: Handle drive IRQs in compatibility mode 2023-05-20 22:01:05 +02:00
f75c4c9d9a
kernel/CPU: Allow passing arbitrary data to interrupt handlers 2023-05-20 22:01:05 +02:00
ee080174fc
kernel/ATA: Start reading/writing registers and detecting drives 2023-05-20 22:01:05 +02:00
f7667b40e6
kernel: Warn if no ATA controller is found 2023-05-20 22:01:05 +02:00
fc86888547
kernel: Add a KMutex class and use that for ATA::Controller locking 2023-05-20 22:01:05 +02:00
51d45bd37e
kernel/x86_64: Add basic ATA controller and channel identification 2023-05-20 22:01:05 +02:00
f5dfe5faac
kernel/PCI: Add more PCI field types 2023-05-20 22:01:04 +02:00
6554b448e9
kernel/x86_64: Add a way to register IRQ handlers from other kernel subsystems 2023-05-20 22:01:04 +02:00
26 changed files with 68 additions and 241 deletions

View File

@ -4,20 +4,56 @@
#include <os/Directory.h>
#include <os/File.h>
#include <os/FileSystem.h>
#include <os/Mode.h>
#include <pwd.h>
void find_user_and_group(struct stat& st, StringView& owner, StringView& group)
struct UsernameCache
{
uid_t uid;
String name;
};
struct GroupCache
{
gid_t gid;
String name;
};
Vector<UsernameCache> g_user_cache;
Vector<GroupCache> g_group_cache;
Result<void> find_user_and_group(struct stat& st, StringView& owner, StringView& group)
{
for (const auto& user : g_user_cache)
{
if (user.uid == st.st_uid) owner = user.name.view();
}
if (owner.is_empty())
{
auto* pw = getpwuid(st.st_uid);
if (!pw) owner = "???";
else
owner = pw->pw_name;
auto name = TRY(String::from_string_view(owner));
TRY(g_user_cache.try_append({ st.st_uid, move(name) }));
}
for (const auto& grp : g_group_cache)
{
if (grp.gid == st.st_gid) group = grp.name.view();
}
if (group.is_empty())
{
auto* grp = getgrgid(st.st_gid);
if (!grp) group = "???";
else
group = grp->gr_name;
auto name = TRY(String::from_string_view(group));
TRY(g_group_cache.try_append({ st.st_gid, move(name) }));
}
return {};
}
Result<int> luna_main(int argc, char** argv)
@ -29,8 +65,6 @@ Result<int> luna_main(int argc, char** argv)
bool human_readable { false };
bool si { false };
bool follow_symlink_args { false };
bool one_per_line { false };
bool list_directories { false };
os::ArgumentParser parser;
parser.add_description("List files contained in a directory (defaults to '.', the current directory)"_sv);
@ -44,17 +78,13 @@ Result<int> luna_main(int argc, char** argv)
parser.add_switch_argument(si, ' ', "si"_sv, "same as -h, but show sizes in powers of 10"_sv);
parser.add_switch_argument(follow_symlink_args, 'H', "dereference-args"_sv,
"follow symbolic links listed as arguments"_sv);
parser.add_switch_argument(one_per_line, '1', ""_sv, "list one file per line"_sv);
parser.add_switch_argument(list_directories, 'd', "directory"_sv, "list directories instead of their contents"_sv);
parser.parse(argc, argv);
Vector<String> files;
int dirfd = AT_FDCWD;
SharedPtr<os::Directory> dir;
if (!long_list) follow_symlink_args = true;
if (os::FileSystem::is_directory(pathname, follow_symlink_args) && !list_directories)
if (os::FileSystem::is_directory(pathname, follow_symlink_args))
{
dir = TRY(os::Directory::open(pathname));
dirfd = dir->fd();
@ -76,7 +106,7 @@ Result<int> luna_main(int argc, char** argv)
if (!long_list)
{
auto list = TRY(String::join(files, one_per_line ? "\n"_sv : " "_sv));
auto list = TRY(String::join(files, " "_sv));
if (!list.is_empty()) os::println("%s", list.chars());
}
else
@ -86,26 +116,21 @@ Result<int> luna_main(int argc, char** argv)
struct stat st;
TRY(os::FileSystem::stat({ dirfd, file.view() }, st, false));
auto link = TRY(os::FileSystem::readlink({ dirfd, file.view() }));
StringView owner;
StringView group;
find_user_and_group(st, owner, group);
char formatted_mode[11];
os::format_mode(st.st_mode, formatted_mode);
TRY(find_user_and_group(st, owner, group));
if (!human_readable && !si)
{
os::println("%s %u %4s %4s %10lu %s%s%s", formatted_mode, st.st_nlink, owner.chars(), group.chars(),
st.st_size, file.chars(), link.is_empty() ? "" : " -> ", link.chars());
os::println("%6o %u %4s %4s %10lu %s", st.st_mode, st.st_nlink, owner.chars(), group.chars(),
st.st_size, file.chars());
}
else
{
auto size = TRY(to_dynamic_unit(st.st_size, 10, false, si ? Unit::SI : Unit::Binary, false));
os::println("%s %u %4s %4s %6s %s%s%s", formatted_mode, st.st_nlink, owner.chars(), group.chars(),
size.chars(), file.chars(), link.is_empty() ? "" : " -> ", link.chars());
os::println("%6o %u %4s %4s %6s %s", st.st_mode, st.st_nlink, owner.chars(), group.chars(),
size.chars(), file.chars());
}
}
}

View File

@ -88,7 +88,7 @@ Result<int> luna_main(int argc, char** argv)
auto cmd = TRY(input_file->read_line());
if (cmd.is_empty())
{
if (interactive) puts("exit");
puts("exit");
break;
}

View File

@ -1,6 +1,5 @@
#include <os/ArgumentParser.h>
#include <os/FileSystem.h>
#include <os/Mode.h>
#include <stdio.h>
#include <sys/stat.h>
@ -11,9 +10,7 @@ static const char* file_type(mode_t mode)
case S_IFREG: return "regular file";
case S_IFDIR: return "directory";
case S_IFCHR: return "character special device";
case S_IFBLK: return "block special device";
case S_IFLNK: return "symbolic link";
case S_IFIFO: return "pipe";
default: return "unknown file type";
}
}
@ -33,13 +30,10 @@ Result<int> luna_main(int argc, char** argv)
struct stat st;
TRY(os::FileSystem::stat(path, st, follow_symlinks));
char buf[11];
os::format_mode(st.st_mode, buf);
printf(" File: %s\n", path.chars());
printf(" Size: %zu (%s)\n", st.st_size, file_type(st.st_mode));
printf("Inode: %lu Links: %lu\n", st.st_ino, st.st_nlink);
printf(" Mode: (%#o/%s) UID: %u GID: %u\n", st.st_mode & ~S_IFMT, buf, st.st_uid, st.st_gid);
printf(" Mode: %#o UID: %u GID: %u\n", st.st_mode & ~S_IFMT, st.st_uid, st.st_gid);
return 0;
}

View File

@ -30,11 +30,6 @@ class Pipe
class PipeInodeBase : public VFS::FileInode
{
public:
VFS::InodeType type() const override
{
return VFS::InodeType::FIFO;
}
Result<void> truncate(usize) override
{
return err(ENOTSUP);

View File

@ -168,11 +168,6 @@ namespace VFS
return inode->mode() & S_ISGID;
}
bool is_seekable(SharedPtr<Inode> inode)
{
return inode->type() != InodeType::FIFO && inode->type() != InodeType::CharacterDevice;
}
Result<void> mount_root(SharedPtr<VFS::FileSystem> fs)
{
root_fs = fs;

View File

@ -1,5 +1,4 @@
#pragma once
#include <bits/makedev.h>
#include <luna/SharedPtr.h>
#include <luna/StaticString.h>
#include <luna/StringView.h>
@ -13,10 +12,8 @@ namespace VFS
{
RegularFile,
Directory,
CharacterDevice,
BlockDevice,
Symlink,
FIFO,
Device,
Symlink
};
class Inode;
@ -51,8 +48,6 @@ namespace VFS
m_handles--;
}
virtual dev_t host_device_id() const = 0;
virtual ~FileSystem() = default;
protected:
@ -106,11 +101,6 @@ namespace VFS
return StringView {};
}
virtual dev_t device_id() const
{
return luna_dev_makedev(0, 0);
}
// Metadata accessors
virtual usize size() const = 0;
@ -262,7 +252,7 @@ namespace VFS
InodeType type() const override
{
return InodeType::CharacterDevice;
return InodeType::Device;
}
virtual ~DeviceInode() = default;
@ -286,8 +276,6 @@ namespace VFS
bool is_setuid(SharedPtr<Inode> inode);
bool is_setgid(SharedPtr<Inode> inode);
bool is_seekable(VFS::InodeType type);
Inode& root_inode();
Result<void> mount_root(SharedPtr<VFS::FileSystem> fs);

View File

@ -18,11 +18,6 @@ class Device
return 0;
}
virtual bool is_block_device() const
{
return false;
}
virtual bool blocking() const = 0;
virtual ~Device() = default;

View File

@ -74,10 +74,4 @@ namespace DeviceRegistry
return {};
}
dev_t next_null_device_id()
{
static u32 next_minor = 0;
return luna_dev_makedev(0, next_minor++);
}
}

View File

@ -21,7 +21,4 @@ namespace DeviceRegistry
mode_t mode = 0666);
Result<void> init();
// Used for file systems (like tmpfs) that do not have a host device.
dev_t next_null_device_id();
}

View File

@ -55,18 +55,10 @@ namespace TmpFS
inode->set_fs(*this, {});
inode->set_inode_number(m_next_inode_number++, {});
inode->set_device(device, {});
// FIXME: This should be queried from Device directly, but Device doesn't have an API to store and retrieve its
// device ID atm.
inode->set_device_id(luna_dev_makedev(major, minor), {});
return (SharedPtr<VFS::Inode>)inode;
}
FileSystem::FileSystem()
{
m_host_device_id = DeviceRegistry::next_null_device_id();
}
Result<void> FileSystem::set_mount_dir(SharedPtr<VFS::Inode> parent)
{
return m_root_inode->replace_entry(parent, "..");

View File

@ -27,23 +27,16 @@ namespace TmpFS
static Result<SharedPtr<VFS::FileSystem>> create();
dev_t host_device_id() const override
{
return m_host_device_id;
}
virtual ~FileSystem() = default;
private:
FileSystem();
FileSystem() = default;
void set_root(SharedPtr<VFS::Inode> root);
SharedPtr<VFS::Inode> m_root_inode;
Atomic<usize> m_next_inode_number { 2 };
dev_t m_host_device_id;
};
class FileInode : public VFS::FileInode
@ -243,11 +236,6 @@ namespace TmpFS
public:
DeviceInode() = default;
VFS::InodeType type() const override
{
return m_device->is_block_device() ? VFS::InodeType::BlockDevice : VFS::InodeType::CharacterDevice;
}
void set_fs(FileSystem& fs, Badge<FileSystem>)
{
m_fs = &fs;
@ -263,21 +251,11 @@ namespace TmpFS
m_device = device;
}
void set_device_id(dev_t id, Badge<FileSystem>)
{
m_device_id = id;
}
VFS::FileSystem* fs() const override
{
return m_fs;
}
dev_t device_id() const override
{
return m_device_id;
}
usize inode_number() const override
{
return m_inode_number;
@ -362,7 +340,6 @@ namespace TmpFS
u32 m_uid { 0 };
u32 m_gid { 0 };
u32 m_nlinks { 0 };
dev_t m_device_id { 0 };
};
class DirInode : public VFS::Inode

View File

@ -33,7 +33,7 @@ Result<u64> sys_read(Registers*, SyscallArgs args)
usize nread = TRY(descriptor.inode->read(buf, descriptor.offset, size));
if (VFS::is_seekable(descriptor.inode->type())) descriptor.offset += nread;
descriptor.offset += nread;
return nread;
}
@ -52,12 +52,11 @@ Result<u64> sys_write(Registers*, SyscallArgs args)
if (!descriptor.is_writable()) return err(EBADF);
if (descriptor.should_append() && VFS::is_seekable(descriptor.inode->type()))
descriptor.offset = descriptor.inode->size();
if (descriptor.should_append()) descriptor.offset = descriptor.inode->size();
usize nwritten = TRY(descriptor.inode->write(buf, descriptor.offset, size));
if (VFS::is_seekable(descriptor.inode->type())) descriptor.offset += nwritten;
descriptor.offset += nwritten;
return nwritten;
}
@ -72,10 +71,6 @@ Result<u64> sys_lseek(Registers*, SyscallArgs args)
auto& descriptor = *TRY(current->resolve_fd(fd));
if (descriptor.inode->type() == VFS::InodeType::FIFO) return err(ESPIPE);
if (!VFS::is_seekable(descriptor.inode->type())) return descriptor.offset;
off_t new_offset;
switch (whence)

View File

@ -62,29 +62,3 @@ Result<u64> sys_symlinkat(Registers*, SyscallArgs args)
return 0;
}
Result<u64> sys_readlinkat(Registers*, SyscallArgs args)
{
int dirfd = (int)args[0];
auto path = TRY(MemoryManager::strdup_from_user(args[1]));
char* buf = (char*)args[2];
usize bufsiz = (usize)args[3];
auto* current = Scheduler::current();
auto symlink = TRY(current->resolve_atfile(dirfd, path, true, false));
if (symlink->type() != VFS::InodeType::Symlink) return err(EINVAL);
auto linkpath = TRY(symlink->readlink());
check(!linkpath.is_empty());
usize nread = linkpath.length();
if (nread > bufsiz) nread = bufsiz;
kdbgln("readlink: reading %zu bytes from symlink (%s)", nread, linkpath.chars());
if (!MemoryManager::copy_to_user(buf, linkpath.chars(), nread)) return err(EFAULT);
return nread;
}

View File

@ -13,10 +13,8 @@ static mode_t make_mode(mode_t mode, VFS::InodeType type)
{
case VFS::InodeType::RegularFile: result |= S_IFREG; break;
case VFS::InodeType::Directory: result |= S_IFDIR; break;
case VFS::InodeType::CharacterDevice: result |= S_IFCHR; break;
case VFS::InodeType::BlockDevice: result |= S_IFBLK; break;
case VFS::InodeType::Device: result |= S_IFCHR; break;
case VFS::InodeType::Symlink: result |= S_IFLNK; break;
case VFS::InodeType::FIFO: result |= S_IFIFO; break;
default: break;
}
@ -42,8 +40,6 @@ Result<u64> sys_fstatat(Registers*, SyscallArgs args)
kstat.st_uid = inode->uid();
kstat.st_gid = inode->gid();
kstat.st_size = inode->size();
kstat.st_dev = inode->fs() ? inode->fs()->host_device_id() : 0;
kstat.st_rdev = inode->device_id();
if (!MemoryManager::copy_to_user_typed(st, &kstat)) return err(EFAULT);

View File

@ -3,7 +3,7 @@
#ifndef _BITS_FIXED_SIZE_TYPES_H
#define _BITS_FIXED_SIZE_TYPES_H
#if !defined(_SYS_TYPES_H) && !defined(_BITS_SETJMP_TYPES_H) && !defined(_BITS_MAKEDEV_H)
#if !defined(_SYS_TYPES_H) && !defined(_BITS_SETJMP_TYPES_H)
#error "Never include bits/fixed-size-types.h, use the standard <stdint.h> header instead."
#endif

View File

@ -6,8 +6,6 @@
#define S_IFMT 070000
#define S_IFREG 000000
#define S_IFLNK 010000
#define S_IFIFO 020000
#define S_IFBLK 030000
#define S_IFDIR 040000
#define S_IFCHR 050000
@ -16,9 +14,7 @@
#define S_ISREG(mode) __CHECK_TYPE(mode, S_IFREG)
#define S_ISDIR(mode) __CHECK_TYPE(mode, S_IFDIR)
#define S_ISCHR(mode) __CHECK_TYPE(mode, S_IFCHR)
#define S_ISBLK(mode) __CHECK_TYPE(mode, S_IFBLK)
#define S_ISLNK(mode) __CHECK_TYPE(mode, S_IFLNK)
#define S_ISFIFO(mode) __CHECK_TYPE(mode, S_IFIFO)
#define S_IRWXU 0700
#define S_IRUSR 0400

View File

@ -10,11 +10,9 @@ struct stat
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
dev_t st_dev;
uid_t st_uid;
gid_t st_gid;
off_t st_size;
dev_t st_rdev;
};
#endif

View File

@ -139,12 +139,6 @@ extern "C"
/* Create a symbolic link relative to a file descriptor. */
int symlinkat(const char* target, int dirfd, const char* linkpath);
/* Read the contents of a symbolic link. */
ssize_t readlink(const char* path, char* buf, size_t max);
/* Read the contents of a symbolic link relative to a file descriptor. */
ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t max);
#ifdef __cplusplus
}
#endif

View File

@ -184,14 +184,11 @@ extern "C"
{
if (!cmd)
{
struct stat st;
if (stat("/bin/sh", &st) < 0) return 0;
return S_ISREG(st.st_mode);
// FIXME: Check if there is a shell available in the system.
errno = ENOTSUP;
return -1;
}
// FIXME: During the execution of system(), SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored, in
// the process that calls system().
pid_t child = fork();
if (child == 0)
{

View File

@ -418,16 +418,4 @@ extern "C"
long rc = syscall(SYS_symlinkat, target, dirfd, linkpath);
__errno_return(rc, int);
}
ssize_t readlink(const char* path, char* buf, size_t max)
{
long rc = syscall(SYS_readlinkat, AT_FDCWD, path, buf, max);
__errno_return(rc, ssize_t);
}
ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t max)
{
long rc = syscall(SYS_readlinkat, dirfd, path, buf, max);
__errno_return(rc, ssize_t);
}
}

View File

@ -5,7 +5,7 @@
_e(lseek) _e(mkdir) _e(execve) _e(fork) _e(waitpid) _e(getppid) _e(fcntl) _e(getdents) _e(getuid) _e(geteuid) \
_e(getgid) _e(getegid) _e(setuid) _e(setgid) _e(seteuid) _e(setegid) _e(fchmodat) _e(fchownat) _e(ioctl) \
_e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) _e(dup2) _e(pipe) _e(mount) \
_e(umount) _e(pstat) _e(getrusage) _e(symlinkat) _e(readlinkat)
_e(umount) _e(pstat) _e(getrusage) _e(symlinkat)
enum Syscalls
{

View File

@ -11,7 +11,6 @@ set(SOURCES
src/Directory.cpp
src/Main.cpp
src/Path.cpp
src/Mode.cpp
)
add_library(os ${SOURCES})

View File

@ -21,8 +21,6 @@ namespace os
Result<void> remove_tree(const Path& path);
Result<String> readlink(const Path& path);
Result<String> working_directory();
Result<String> home_directory();

View File

@ -1,8 +0,0 @@
#pragma once
#include <sys/types.h>
namespace os
{
void format_mode(mode_t mode, char out[11]);
}

View File

@ -2,7 +2,6 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <luna/PathParser.h>
#include <luna/String.h>
#include <os/Directory.h>
#include <os/FileSystem.h>
@ -69,23 +68,6 @@ namespace os::FileSystem
return remove(path);
}
Result<String> readlink(const Path& path)
{
struct stat st;
TRY(stat(path, st, false));
if (!S_ISLNK(st.st_mode)) return String {};
char* buf = TRY(make_array<char>(st.st_size + 1));
auto guard = make_scope_guard([buf] { delete[] buf; });
usize nread = TRY(
Result<usize>::from_syscall(syscall(SYS_readlinkat, path.dirfd(), path.name().chars(), buf, st.st_size)));
buf[nread] = '\0';
guard.deactivate();
return String { buf, nread };
}
Result<String> working_directory()
{
char* ptr = getcwd(NULL, 0);

View File

@ -1,34 +0,0 @@
#include <os/Mode.h>
#include <sys/stat.h>
namespace os
{
static char filetype(mode_t mode)
{
if (S_ISREG(mode)) return '-';
if (S_ISDIR(mode)) return 'd';
if (S_ISCHR(mode)) return 'c';
if (S_ISBLK(mode)) return 'b';
if (S_ISLNK(mode)) return 'l';
if (S_ISFIFO(mode)) return 'p';
return '?';
}
void format_mode(mode_t mode, char out[11])
{
out[0] = filetype(mode);
out[1] = (mode & S_IRUSR) ? 'r' : '-';
out[2] = (mode & S_IWUSR) ? 'w' : '-';
out[3] = (mode & S_ISUID) ? ((mode & S_IXUSR) ? 's' : 'S') : ((mode & S_IXUSR) ? 'x' : '-');
out[4] = (mode & S_IRGRP) ? 'r' : '-';
out[5] = (mode & S_IWGRP) ? 'w' : '-';
out[6] = (mode & S_ISGID) ? ((mode & S_IXGRP) ? 's' : 'S') : ((mode & S_IXGRP) ? 'x' : '-');
out[7] = (mode & S_IROTH) ? 'r' : '-';
out[8] = (mode & S_IWOTH) ? 'w' : '-';
// FIXME: Support the sticky bit.
out[9] = (mode & S_IXOTH) ? 'x' : '-';
out[10] = '\0';
}
}