Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions kernel/arch/aarch64/clock/clock.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "clock/clock.h"
#include "hw/hwtimer.h"
#include "hw/rtc.h"
#include "common/logging.h"
#include "sync/atomic.h"

Expand All @@ -10,7 +9,6 @@ static uint64_t g_cnt_freq;
static uint64_t g_mult;
static uint32_t g_shift;
static sync::atomic<bool> g_calibrated;
static uint64_t g_boot_realtime_ns;

constexpr uint64_t NS_PER_SEC = 1000000000ULL;

Expand Down Expand Up @@ -58,7 +56,6 @@ __PRIVILEGED_CODE int32_t init() {
}

compute_mult_shift(g_cnt_freq, &g_mult, &g_shift);
g_boot_realtime_ns = rtc::boot_unix_ns();
enable_el0_counter_access();
g_calibrated.store_release(true);

Expand Down Expand Up @@ -94,9 +91,4 @@ uint64_t now_ns() {
uint64_t freq_hz() {
return g_cnt_freq;
}

uint64_t boot_realtime_ns() {
return g_boot_realtime_ns;
}

} // namespace clock
1 change: 1 addition & 0 deletions kernel/arch/aarch64/syscall/linux_syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ constexpr uint64_t FCNTL = 25;
constexpr uint64_t IOCTL = 29;
constexpr uint64_t MKDIRAT = 34;
constexpr uint64_t UNLINKAT = 35;
constexpr uint64_t SYMLINKAT = 36;
constexpr uint64_t RENAMEAT = 38;
constexpr uint64_t FTRUNCATE = 46;
constexpr uint64_t FACCESSAT = 48;
Expand Down
8 changes: 0 additions & 8 deletions kernel/arch/x86_64/clock/clock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include "hw/portio.h"
#include "hw/mmio.h"
#include "hw/cpu.h"
#include "hw/rtc.h"
#include "hw/cpu_features.h"
#include "common/logging.h"
#include "sync/atomic.h"
Expand All @@ -14,7 +13,6 @@ static uint64_t g_tsc_freq;
static uint64_t g_mult;
static uint32_t g_shift;
static sync::atomic<bool> g_calibrated;
static uint64_t g_boot_realtime_ns;

constexpr uint64_t NS_PER_SEC = 1000000000ULL;

Expand Down Expand Up @@ -91,7 +89,6 @@ __PRIVILEGED_CODE int32_t init() {
}

compute_mult_shift(g_tsc_freq, &g_mult, &g_shift);
g_boot_realtime_ns = rtc::boot_unix_ns();
g_calibrated.store_release(true);

log::info("clock: TSC freq=%lu Hz, mult=%lu shift=%u%s",
Expand Down Expand Up @@ -126,9 +123,4 @@ uint64_t now_ns() {
uint64_t freq_hz() {
return g_tsc_freq;
}

uint64_t boot_realtime_ns() {
return g_boot_realtime_ns;
}

} // namespace clock
2 changes: 2 additions & 0 deletions kernel/arch/x86_64/syscall/linux_syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ constexpr uint64_t RENAME = 82;
constexpr uint64_t MKDIR = 83;
constexpr uint64_t RMDIR = 84;
constexpr uint64_t UNLINK = 87;
constexpr uint64_t SYMLINK = 88;
constexpr uint64_t READLINK = 89;
constexpr uint64_t CHMOD = 90;
constexpr uint64_t UMASK = 95;
Expand Down Expand Up @@ -89,6 +90,7 @@ constexpr uint64_t MKDIRAT = 258;
constexpr uint64_t NEWFSTATAT = 262;
constexpr uint64_t UNLINKAT = 263;
constexpr uint64_t RENAMEAT = 264;
constexpr uint64_t SYMLINKAT = 266;
constexpr uint64_t READLINKAT = 267;
constexpr uint64_t FACCESSAT = 269;
constexpr uint64_t PSELECT6 = 270;
Expand Down
13 changes: 10 additions & 3 deletions kernel/clock/clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define STELLUX_CLOCK_CLOCK_H

#include "common/types.h"
#include "hw/rtc.h"

namespace clock {

Expand Down Expand Up @@ -43,10 +44,16 @@ uint64_t freq_hz();

/**
* @brief Unix epoch in nanoseconds at boot time.
* Returns 0 if no RTC was available or rtc::init() was not called.
* Unprivileged: reads a cached value from regular .bss.
* Valid as soon as rtc::init() has run, which precedes init() here.
* Returns 0 if no RTC was available.
*/
uint64_t boot_realtime_ns();
inline uint64_t boot_realtime_ns() { return rtc::boot_unix_ns(); }

/**
* @brief Unix epoch in nanoseconds now. Counts from 0 when no RTC was
* available, so ordering between readings holds even without wall time.
*/
inline uint64_t realtime_ns() { return boot_realtime_ns() + now_ns(); }

} // namespace clock

Expand Down
8 changes: 0 additions & 8 deletions kernel/drivers/graphics/gfxfb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,6 @@ class gfxfb_node : public fs::node {
return rc;
}

int32_t getattr(fs::vattr* attr) override {
if (!attr) return fs::ERR_INVAL;

attr->type = fs::node_type::char_device;
attr->size = m_fb_size;
return fs::OK;
}

private:
uint64_t m_phys;
uint64_t m_width;
Expand Down
10 changes: 0 additions & 10 deletions kernel/drivers/input/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,6 @@ class input_device_node : public fs::node {
return ring_buffer_poll_read(m_rb, pt);
}

int32_t getattr(fs::vattr* attr) override {
if (!attr) {
return fs::ERR_INVAL;
}

attr->type = fs::node_type::char_device;
attr->size = 0;
return fs::OK;
}

private:
ring_buffer* m_rb;
};
Expand Down
41 changes: 39 additions & 2 deletions kernel/fs/cpio/cpio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "boot/boot_services.h"
#include "mm/vmm.h"
#include "mm/paging.h"
#include "mm/heap.h"
#include "common/string.h"
#include "common/logging.h"

Expand All @@ -14,6 +15,8 @@ constexpr char CPIO_TRAILER[] = "TRAILER!!!";
constexpr uint32_t S_IFMT = 0170000;
constexpr uint32_t S_IFDIR = 0040000;
constexpr uint32_t S_IFREG = 0100000;
constexpr uint32_t S_IFLNK = 0120000;
constexpr uint64_t NS_PER_SEC = 1000000000ULL;

static uint32_t hex_to_u32(const char* s, size_t len) {
uint32_t val = 0;
Expand Down Expand Up @@ -86,8 +89,16 @@ __PRIVILEGED_CODE int32_t load_initrd() {
const auto* archive = reinterpret_cast<const uint8_t*>(usable_va);
size_t archive_len = static_cast<size_t>(size);

// Link targets are copied out so they can be null terminated
char* target_buf = static_cast<char*>(heap::uzalloc(fs::PATH_MAX));
if (!target_buf) {
vmm::free(base_va);
return ERR_MAP_FAILED;
}

uint32_t files_extracted = 0;
uint32_t dirs_created = 0;
uint32_t links_created = 0;
size_t offset = 0;

while (offset + sizeof(cpio_newc_header) <= archive_len) {
Expand All @@ -100,6 +111,7 @@ __PRIVILEGED_CODE int32_t load_initrd() {
uint32_t namesize = hex_to_u32(hdr->c_namesize, 8);
uint32_t filesize = hex_to_u32(hdr->c_filesize, 8);
uint32_t mode = hex_to_u32(hdr->c_mode, 8);
uint32_t mtime = hex_to_u32(hdr->c_mtime, 8);

offset += sizeof(cpio_newc_header);

Expand Down Expand Up @@ -159,21 +171,46 @@ __PRIVILEGED_CODE int32_t load_initrd() {
if (filesize > 0 && offset + filesize <= archive_len) {
fs::write(f, file_data, filesize);
}

// Files keep their archived timestamps so build tools see real ages
fs::vattr attr = {};
attr.atime_ns = static_cast<uint64_t>(mtime) * NS_PER_SEC;
attr.mtime_ns = attr.atime_ns;
fs::fsetattr(f, attr, fs::VATTR_ATIME | fs::VATTR_MTIME);

fs::close(f);
files_extracted++;
} else {
log::warn("cpio: failed to create file %s", path_buf);
}
} else if ((mode & S_IFMT) == S_IFLNK) {
bool target_ok = filesize > 0 && filesize < fs::PATH_MAX &&
offset + filesize <= archive_len;

if (target_ok) {
string::memcpy(target_buf, file_data, filesize);
target_buf[filesize] = '\0';
ensure_parents(path_buf);

if (fs::symlink(target_buf, path_buf) == fs::OK) {
links_created++;
} else {
log::warn("cpio: failed to create link %s", path_buf);
}
} else {
log::warn("cpio: rejecting link with bad target: %s", path_buf);
}
}

offset += filesize;
offset = align4(offset);
}

heap::ufree(target_buf);
vmm::free(base_va);

log::info("cpio: extracted %u files and %u directories into /",
files_extracted, dirs_created);
log::info("cpio: extracted %u files, %u directories, and %u links into /",
files_extracted, dirs_created, links_created);
return OK;
}

Expand Down
100 changes: 4 additions & 96 deletions kernel/fs/devfs/devfs.cpp
Original file line number Diff line number Diff line change
@@ -1,106 +1,22 @@
#include "fs/devfs/devfs.h"
#include "fs/node.h"
#include "fs/file.h"
#include "fs/dir_node.h"
#include "fs/mount.h"
#include "fs/fs.h"
#include "common/list.h"
#include "common/string.h"
#include "mm/heap.h"
#include "common/logging.h"

namespace devfs {

class devfs_dir_node : public fs::node {
class devfs_dir_node : public fs::dir_node {
public:
devfs_dir_node(fs::instance* fs, const char* name)
: fs::node(fs::node_type::directory, fs, name)
, m_child_count(0) {
m_children.init();
}

~devfs_dir_node() override {
while (!m_children.empty()) {
fs::node* child = m_children.pop_front();
child->set_parent(nullptr);
if (child->release()) {
fs::node::ref_destroy(child);
}
}
m_child_count = 0;
}

int32_t lookup(const char* name, size_t len, fs::node** out) override {
if (!name || !out) return fs::ERR_INVAL;

sync::irq_lock_guard guard(m_lock);
fs::node* child = find_child(name, len);
if (!child) return fs::ERR_NOENT;

child->add_ref();
*out = child;
return fs::OK;
}

ssize_t readdir(fs::file* f, fs::dirent* entries, size_t count) override {
if (!f || !entries) return fs::ERR_BADF;

if (count == 0) return 0;

sync::irq_lock_guard guard(m_lock);

size_t idx = static_cast<size_t>(f->offset());
size_t written = 0;

size_t cur_idx = 0;
for (auto& child : m_children) {
if (written >= count) break;

if (cur_idx >= idx) {
size_t name_len = string::strlen(child.name());
if (name_len > fs::NAME_MAX) name_len = fs::NAME_MAX;
string::memcpy(entries[written].name, child.name(), name_len);
entries[written].name[name_len] = '\0';
entries[written].type = child.type();
written++;
}
cur_idx++;
}

f->set_offset(static_cast<int64_t>(idx + written));
return static_cast<ssize_t>(written);
}

int32_t getattr(fs::vattr* attr) override {
if (!attr) return fs::ERR_INVAL;

attr->type = fs::node_type::directory;
attr->size = m_child_count;
return fs::OK;
}
: fs::dir_node(fs, name) {}

void add_child(fs::node* child) {
sync::irq_lock_guard guard(m_lock);

child->set_parent(this);
child->set_filesystem(m_fs);
child->add_ref();
m_children.push_back(child);
m_child_count++;
}

private:
fs::node* find_child(const char* name, size_t len) {
for (auto& child : m_children) {
size_t child_len = string::strlen(child.name());
if (child_len == len && string::strncmp(child.name(), name, len) == 0) {
return &child;
}
}
return nullptr;
attach_child(child);
}

list::head<fs::node, &fs::node::m_child_link> m_children;
uint32_t m_child_count;
};

/* Built-in /dev/null: reads return EOF, writes are discarded. */
Expand All @@ -114,14 +30,6 @@ class devfs_null_node : public fs::node {
ssize_t write(fs::file*, const void*, size_t count) override {
return static_cast<ssize_t>(count);
}

int32_t getattr(fs::vattr* attr) override {
if (!attr) return fs::ERR_INVAL;

attr->type = fs::node_type::char_device;
attr->size = 0;
return fs::OK;
}
};

__PRIVILEGED_BSS static devfs_dir_node* g_devfs_root;
Expand Down
Loading
Loading