menios icon indicating copy to clipboard operation
menios copied to clipboard

Implement uname command for system information

Open pbalduino opened this issue 3 months ago • 0 comments

Summary

Implement the uname command to display system information including kernel name, version, architecture, and hostname.

Description

The uname command is a standard Unix utility that prints system information. It's commonly used in scripts to detect the operating system, architecture, and kernel version for platform-specific behavior.

Current State

  • No uname command exists in /bin
  • No way to query system information from shell
  • Scripts cannot detect meniOS or its version
  • No visibility into kernel version or build info

Proposed Behavior

Default Output (kernel name only)

$ uname
meniOS

Common Options

$ uname -s        # System/kernel name
meniOS

$ uname -n        # Network node hostname
menios-dev

$ uname -r        # Kernel release version
0.2.0

$ uname -v        # Kernel version (build date/info)
#1 SMP Sun Oct 19 2025

$ uname -m        # Machine hardware name
x86_64

$ uname -p        # Processor type
x86_64

$ uname -i        # Hardware platform
x86_64

$ uname -o        # Operating system
meniOS

$ uname -a        # All information
meniOS menios-dev 0.2.0 #1 SMP Sun Oct 19 2025 x86_64 x86_64 x86_64 meniOS

Option Combinations

$ uname -sr       # System and release
meniOS 0.2.0

$ uname -rvm      # Release, version, machine
0.2.0 #1 SMP Sun Oct 19 2025 x86_64

Implementation Strategy

Phase 1: Basic Command (Hardcoded Values)

Start with hardcoded values, no syscall needed:

#include <stdio.h>
#include <string.h>

// Compile-time constants
#define SYSNAME  "meniOS"
#define RELEASE  "0.2.0"
#define VERSION  "#1 SMP " __DATE__
#define MACHINE  "x86_64"
#define NODENAME "menios-dev"

int main(int argc, char **argv) {
    // Parse options
    if (argc == 1) {
        printf("%s\n", SYSNAME);
        return 0;
    }
    
    // Handle -a flag
    if (strcmp(argv[1], "-a") == 0) {
        printf("%s %s %s %s %s %s %s %s\n",
               SYSNAME, NODENAME, RELEASE, VERSION,
               MACHINE, MACHINE, MACHINE, SYSNAME);
        return 0;
    }
    
    // Handle other flags...
}

Phase 2: uname() Syscall Implementation

Implement proper uname() syscall for dynamic information:

Kernel Structure

// include/menios/utsname.h
#define UTSNAME_LENGTH 65

struct utsname {
    char sysname[UTSNAME_LENGTH];    // OS name: "meniOS"
    char nodename[UTSNAME_LENGTH];   // Network node hostname
    char release[UTSNAME_LENGTH];    // OS release: "0.2.0"
    char version[UTSNAME_LENGTH];    // OS version: "#1 SMP DATE"
    char machine[UTSNAME_LENGTH];    // Hardware: "x86_64"
};

Syscall Implementation

// src/kernel/syscall/sys_uname.c
#include <menios/utsname.h>
#include <menios/version.h>

static struct utsname system_utsname = {
    .sysname  = "meniOS",
    .nodename = "menios-dev",
    .release  = KERNEL_VERSION,      // From version.h
    .version  = KERNEL_BUILD_INFO,   // Build date/compiler
    .machine  = "x86_64",
};

int sys_uname(struct utsname *buf) {
    // Validate user pointer
    if (!valid_user_pointer(buf)) {
        return -EFAULT;
    }
    
    // Copy system info to userspace
    if (copy_to_user(buf, &system_utsname, sizeof(struct utsname)) != 0) {
        return -EFAULT;
    }
    
    return 0;
}

Version Header (Auto-Generated)

// include/menios/version.h (generated by build system)
#define KERNEL_VERSION "0.2.0"
#define KERNEL_BUILD_INFO "#1 SMP Sun Oct 19 08:30:00 UTC 2025"
#define KERNEL_COMPILER "gcc version 13.2.0"

libc Wrapper

// userland/libc/src/sys/utsname.c
#include <sys/utsname.h>
#include <syscall.h>

int uname(struct utsname *buf) {
    return syscall(SYS_UNAME, buf);
}

uname Command Using Syscall

#include <sys/utsname.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
    struct utsname uts;
    
    if (uname(&uts) < 0) {
        perror("uname");
        return 1;
    }
    
    // Parse flags and print requested info
    if (argc == 1) {
        printf("%s\n", uts.sysname);
    } else if (strcmp(argv[1], "-a") == 0) {
        printf("%s %s %s %s %s\n",
               uts.sysname, uts.nodename, uts.release,
               uts.version, uts.machine);
    }
    // ... handle other flags
    
    return 0;
}

Phase 3: Build System Integration

Generate version info at build time:

# Generate version.h from git describe or version file
KERNEL_VERSION := $(shell cat VERSION)
GIT_COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
BUILD_DATE := $(shell date -u "+%a %b %d %H:%M:%S UTC %Y")

version:
	@echo "Generating version.h..."
	@echo "#define KERNEL_VERSION \"$(KERNEL_VERSION)\"" > include/menios/version.h
	@echo "#define KERNEL_BUILD_INFO \"#1 SMP $(BUILD_DATE) ($(GIT_COMMIT))\"" >> include/menios/version.h
	@echo "#define KERNEL_COMPILER \"$(shell $(CC) --version | head -n1)\"" >> include/menios/version.h

Option Parsing

Single Character Options

  • -a - All information
  • -s - System name (default)
  • -n - Node name (hostname)
  • -r - Release version
  • -v - Kernel version/build info
  • -m - Machine hardware name
  • -p - Processor type
  • -i - Hardware platform
  • -o - Operating system

Multiple Options

uname -srm     # System, release, machine
uname -nrv     # Node, release, version

Use Cases

Platform Detection in Scripts

#!/bin/sh
OS=$(uname -s)
if [ "$OS" = "meniOS" ]; then
    echo "Running on meniOS!"
fi

Architecture Detection

ARCH=$(uname -m)
if [ "$ARCH" = "x86_64" ]; then
    ./configure --target=x86_64
fi

Version Checking

VERSION=$(uname -r)
echo "Kernel version: $VERSION"

# Check minimum version
MIN_VERSION="0.2.0"
if [ "$VERSION" \< "$MIN_VERSION" ]; then
    echo "Error: Requires kernel >= $MIN_VERSION"
    exit 1
fi

Build Configuration

# Configure script detects OS
case $(uname -s) in
    meniOS)
        CFLAGS="-D__MENIOS__"
        ;;
    Linux)
        CFLAGS="-D__LINUX__"
        ;;
esac

System Information Display

echo "System: $(uname -a)"
echo "Kernel: $(uname -r)"
echo "Arch: $(uname -m)"

Output Format Examples

meniOS Development Build

$ uname -a
meniOS menios-dev 0.2.0 #1 SMP Sun Oct 19 08:30:00 UTC 2025 x86_64 x86_64 x86_64 meniOS

After GCC Milestone

$ uname -a
meniOS menios-gcc 0.3.0 #15 SMP Mon Nov 01 12:00:00 UTC 2025 x86_64 x86_64 x86_64 meniOS

After Doom Milestone

$ uname -a
meniOS menios-doom 0.4.0 #42 SMP Sat Dec 15 18:00:00 UTC 2025 x86_64 x86_64 x86_64 meniOS

Error Handling

# Invalid option
$ uname -x
uname: invalid option -- 'x'
Try 'uname --help' for more information.

# Syscall failure (if syscall not implemented)
$ uname
uname: uname syscall failed: Function not implemented

Benefits

  • Script Compatibility: Enables portable shell scripts
  • Platform Detection: Scripts can detect meniOS vs other OSes
  • Version Checking: Software can verify kernel requirements
  • System Information: Users can see kernel/system details
  • Debugging: Build info helps track kernel versions
  • POSIX Compliance: Standard Unix utility

Testing

Basic Functionality

# Default output
uname               # Should print: meniOS

# All info
uname -a            # Should print full info string

# Individual fields
uname -s            # meniOS
uname -r            # 0.2.0
uname -m            # x86_64

Option Combinations

uname -sr           # meniOS 0.2.0
uname -npm          # menios-dev x86_64 x86_64

Integration Tests

# Use in script
if [ "$(uname -s)" = "meniOS" ]; then
    echo "Detected meniOS"
fi

# Version extraction
VERSION=$(uname -r | cut -d. -f1)

Dependencies

  • #193 (libc) ✅ - Standard library functions
  • Optional: SYS_UNAME syscall for dynamic info (can start with hardcoded)
  • #313 (Filesystem organization) - Installation to /bin

Priority

Medium - Useful utility but not critical; can start with simple hardcoded version

Installation

  • Install to /bin/uname
  • Add to default userland build (#195 ✅)
  • Include in base system utilities (#183 ✅)

Implementation Phases

Phase 1: Hardcoded Version (Quick Win)

  • Create /bin/uname command with compile-time constants
  • Support basic flags (-a, -s, -r, -m)
  • ~50 lines of C code
  • No syscall required

Phase 2: Syscall Implementation

  • Implement SYS_UNAME syscall
  • Kernel utsname structure
  • Dynamic hostname support
  • libc wrapper

Phase 3: Build Integration

  • Auto-generate version.h from git/VERSION file
  • Include build date, git commit
  • Compiler version info

Phase 4: Enhanced Features (Future)

  • --help and --version flags
  • Long option names (--all, --kernel-name, etc.)
  • Hostname modification (sethostname syscall)

Related Standards

  • POSIX.1-2001 uname specification
  • Single UNIX Specification
  • Linux uname(1) and uname(2) man pages

Related Issues

  • #183 (Basic /bin utilities) ✅ - Similar utility implementation
  • #313 (Filesystem organization) - Installation location
  • #193 (libc) ✅ - Standard library support

Inspiration

  • Linux uname command (coreutils)
  • BSD uname implementation
  • POSIX uname specification

pbalduino avatar Oct 19 '25 17:10 pbalduino