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
3 changes: 3 additions & 0 deletions config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ endif
# Kernel Configuration
# ============================================================================

# Kernel version string
STLX_VERSION ?= 3.0.1

# Maximum number of CPUs supported
MAX_CPUS ?= 64

Expand Down
1 change: 1 addition & 0 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ CXXFLAGS_LOG := -DLOG_LEVEL=$(LOG_LEVEL)
# Configuration defines (from config.mk)
CXXFLAGS_CONFIG := -DMAX_CPUS=$(MAX_CPUS)
CXXFLAGS_CONFIG += -DSTLX_BUILD_EPOCH=$(STLX_BUILD_EPOCH)
CXXFLAGS_CONFIG += -DSTLX_VERSION='"$(STLX_VERSION)"'

# Platform define (e.g., PLATFORM=rpi4 → -DSTLX_PLATFORM_RPI4)
ifneq ($(PLATFORM),qemu-virt)
Expand Down
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 @@ -34,6 +34,7 @@ constexpr uint64_t CLOCK_GETTIME = 113;
constexpr uint64_t CLOCK_GETRES = 114;
constexpr uint64_t RT_SIGACTION = 134;
constexpr uint64_t RT_SIGPROCMASK = 135;
constexpr uint64_t UNAME = 160;
constexpr uint64_t GETTIMEOFDAY = 169;
constexpr uint64_t GETPID = 172;
constexpr uint64_t GETUID = 174;
Expand Down
1 change: 1 addition & 0 deletions kernel/arch/x86_64/syscall/linux_syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ constexpr uint64_t SOCKETPAIR = 53;
constexpr uint64_t SETSOCKOPT = 54;
constexpr uint64_t GETSOCKOPT = 55;
constexpr uint64_t EXIT = 60;
constexpr uint64_t UNAME = 63;
constexpr uint64_t FCNTL = 72;
constexpr uint64_t FSYNC = 74;
constexpr uint64_t FTRUNCATE = 77;
Expand Down
49 changes: 49 additions & 0 deletions kernel/syscall/handlers/sys_uname.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "syscall/handlers/sys_uname.h"
#include "mm/uaccess.h"
#include "common/string.h"

constexpr size_t UTS_FIELD_LEN = 65;

struct new_utsname {
char sysname[UTS_FIELD_LEN];
char nodename[UTS_FIELD_LEN];
char release[UTS_FIELD_LEN];
char version[UTS_FIELD_LEN];
char machine[UTS_FIELD_LEN];
char domainname[UTS_FIELD_LEN];
};

__PRIVILEGED_CODE static void fill_field(char* dst, const char* src) {
size_t len = string::strnlen(src, UTS_FIELD_LEN - 1);
string::memcpy(dst, src, len);
string::memset(dst + len, 0, UTS_FIELD_LEN - len);
}

DEFINE_SYSCALL1(uname, u_buf) {
if (u_buf == 0) {
return syscall::EFAULT;
}

new_utsname kbuf;

fill_field(kbuf.sysname, "Stellux");
fill_field(kbuf.nodename, "stellux");
fill_field(kbuf.release, STLX_VERSION);
fill_field(kbuf.version, "Stellux " STLX_VERSION);
#if defined(__x86_64__)
fill_field(kbuf.machine, "x86_64");
#elif defined(__aarch64__)
fill_field(kbuf.machine, "aarch64");
#else
#error "unsupported architecture for uname"
#endif
Comment thread
FlareCoding marked this conversation as resolved.
fill_field(kbuf.domainname, "(none)");

int32_t rc = mm::uaccess::copy_to_user(
reinterpret_cast<void*>(u_buf), &kbuf, sizeof(kbuf));
if (rc != mm::uaccess::OK) {
return syscall::EFAULT;
}

return 0;
}
8 changes: 8 additions & 0 deletions kernel/syscall/handlers/sys_uname.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef STELLUX_SYSCALL_HANDLERS_SYS_UNAME_H
#define STELLUX_SYSCALL_HANDLERS_SYS_UNAME_H

#include "syscall/syscall_table.h"

DECLARE_SYSCALL(uname);

#endif // STELLUX_SYSCALL_HANDLERS_SYS_UNAME_H
2 changes: 2 additions & 0 deletions kernel/syscall/syscall_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "syscall/handlers/sys_signal.h"
#include "syscall/handlers/sys_select.h"
#include "syscall/handlers/sys_pipe.h"
#include "syscall/handlers/sys_uname.h"

namespace syscall {

Expand Down Expand Up @@ -65,6 +66,7 @@ __PRIVILEGED_CODE void init_syscall_table() {
REGISTER_SYSCALL(linux_nr::CLOCK_GETTIME, clock_gettime);
REGISTER_SYSCALL(linux_nr::CLOCK_GETRES, clock_getres);
REGISTER_SYSCALL(linux_nr::GETTIMEOFDAY, gettimeofday);
REGISTER_SYSCALL(linux_nr::UNAME, uname);

REGISTER_SYSCALL(linux_nr::SOCKET, socket);
REGISTER_SYSCALL(linux_nr::SOCKETPAIR, socketpair);
Expand Down
2 changes: 1 addition & 1 deletion userland/apps/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
APP_DIRS := init hello shell ls cat rm stat touch sleep true false clear ptytest date \
clockbench stlxdm stlxterm doom ping ifconfig nslookup arp udpecho tcpecho \
fetch polltest dropbear blackjack wordle hangman snake tetris \
grep wc head threadtest
grep wc head threadtest uname
APP_COUNT := $(words $(APP_DIRS))

all:
Expand Down
2 changes: 2 additions & 0 deletions userland/apps/uname/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
APP_NAME := uname
include ../../mk/app.mk
77 changes: 77 additions & 0 deletions userland/apps/uname/src/uname.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#include <stdio.h>
#include <string.h>
#include <sys/utsname.h>

#define FLAG_S (1 << 0)
#define FLAG_N (1 << 1)
#define FLAG_R (1 << 2)
#define FLAG_V (1 << 3)
#define FLAG_M (1 << 4)
#define FLAG_ALL (FLAG_S | FLAG_N | FLAG_R | FLAG_V | FLAG_M)

static void usage(void) {
printf("Usage: uname [OPTION]...\n"
"Print system information.\n\n"
" -a all information\n"
" -s kernel name\n"
" -n network node hostname\n"
" -r kernel release\n"
" -v kernel version\n"
" -m machine hardware name\n"
" --help display this help\n");
}

int main(int argc, char* argv[]) {
setvbuf(stdout, NULL, _IONBF, 0);

unsigned flags = 0;

for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--help") == 0) {
usage();
return 0;
}
if (argv[i][0] != '-' || argv[i][1] == '\0') {
printf("uname: invalid option '%s'\n", argv[i]);
return 1;
}
for (const char* p = argv[i] + 1; *p; p++) {
switch (*p) {
case 'a': flags |= FLAG_ALL; break;
case 's': flags |= FLAG_S; break;
case 'n': flags |= FLAG_N; break;
case 'r': flags |= FLAG_R; break;
case 'v': flags |= FLAG_V; break;
case 'm': flags |= FLAG_M; break;
default:
printf("uname: invalid option '-%c'\n", *p);
return 1;
}
}
}

if (flags == 0)
flags = FLAG_S;

struct utsname buf;
if (uname(&buf) != 0) {
printf("uname: uname syscall failed\n");
return 1;
}

int need_space = 0;
const char* fields[] = { buf.sysname, buf.nodename, buf.release,
buf.version, buf.machine };
unsigned field_flags[] = { FLAG_S, FLAG_N, FLAG_R, FLAG_V, FLAG_M };

for (int i = 0; i < 5; i++) {
if (flags & field_flags[i]) {
if (need_space) putchar(' ');
fputs(fields[i], stdout);
need_space = 1;
}
}
putchar('\n');

return 0;
}
Loading