Skip to content

Linux Kernel Integration

Overview

TimeNow provides two paths for Linux kernel integration:

  1. Userspace daemon (available now) — the C and Rust daemons communicate with the kernel through standard interfaces.
  2. Rust kernel module (experimental) — the timenow-solar crate is no_std compatible, making it usable inside a Rust-for-Linux kernel module.

Userspace Daemon

The primary integration path. The C and Rust daemons run in userspace and expose solar offset data through:

Interface Path Consumer
Plain-text file /run/timenow/solar_offset Any userspace program
JSON file /run/timenow/solar.json Monitoring, dashboards
SHM file /dev/shm/timenow chrony refclock driver

adjtimex() Integration

The adjtimex() syscall provides read/write access to the kernel's internal timekeeping parameters. A helper process can read the solar offset from the daemon and feed it to the kernel:

#include <sys/timex.h>

struct timex tx = {0};
tx.modes = ADJ_OFFSET | ADJ_STATUS;

// Read solar offset from daemon output
double solar_offset = read_offset("/run/timenow/solar_offset");

// Convert to microseconds for adjtimex
tx.offset = (long)(solar_offset * 1000000);
tx.status = STA_UNSYNC;  // Informational only

adjtimex(&tx);

Warning

Directly adjusting kernel time with solar offsets will break NTP synchronization. Use STA_UNSYNC or a separate clock domain for informational purposes only.

sysfs / procfs (Planned)

Future versions may expose solar data through:

  • /sys/class/timenow/solar_offset — kernel sysfs attribute
  • /proc/timenow/status — proc filesystem entry

Rust Kernel Module (Experimental)

The timenow-solar crate is no_std compatible, meaning it can be compiled for use inside a Rust-for-Linux kernel module.

Crate Configuration

# Disable std to use in kernel context
[dependencies]
timenow-solar = { version = "0.1", default-features = false }

The crate uses the libm library for math functions in no_std environments, avoiding any dependency on the C standard library.

SolarResult Struct

pub struct SolarResult {
    pub solar_noon_utc: f64,
    pub sunrise_utc: f64,
    pub sunset_utc: f64,
    pub elevation_deg: f64,
    pub azimuth_deg: f64,
    pub equation_of_time_min: f64,
    pub day_length_hours: f64,
    pub solar_offset_sec: f64,
    pub declination_deg: f64,
}

Conceptual Kernel Module

#![no_std]

use timenow_solar::{compute_solar, SolarResult};

// In a kernel timer callback:
fn compute_offset(lat: f64, lng: f64) -> f64 {
    let result = compute_solar(lat, lng, 2025, 6, 21, 12, 0, 0);
    result.solar_offset_sec
}

Floating-Point in Kernel Context

The Linux kernel restricts floating-point operations to avoid corrupting userspace FPU state. Wrap any solar calculations with kernel_fpu_begin() / kernel_fpu_end():

kernel_fpu_begin();
// ... call Rust solar code ...
kernel_fpu_end();

Alternatively, consider a fixed-point implementation for production kernel modules.

Test Coverage

The timenow-solar crate includes tests for correctness:

Test Validates
Julian day (J2000 epoch) Calendar-to-Julian conversion
Summer solstice elevation Solar position at known date/location
Equinox day length ~12 hours at equator
Equation of time range Within ±17 minutes
Arctic midnight sun Polar day at 69.65°N
Greenwich offset bounds Reasonable offset range

Run tests with:

cd daemon-rust && cargo test -p timenow-solar

Comparison with NTP/PTP

Feature NTP PTP TimeNow
Time source Atomic clocks Hardware clocks Solar position
Accuracy ~1ms ~1µs ~1s (astronomical)
Purpose Synchronize clocks Precision sync Solar awareness
Network required Yes Yes (L2) No
Kernel support ntpd / chronyd ptp4l Userspace daemon
Standard RFC 5905 IEEE 1588 IETF Internet-Draft

TimeNow is not a replacement for NTP or PTP. It provides solar time awareness — knowing where the sun is relative to your clock — which is useful for scientific, agricultural, religious, and health applications.

Future Work

  • sysfs interface — Expose solar data as kernel attributes.
  • eBPF integration — Attach solar-aware logic to kernel events.
  • Clock domain — Register solar time as a separate POSIX clock (CLOCK_SOLAR).
  • Fixed-point math — Eliminate FPU dependency for kernel modules.