fix: move RTL-SDR to userspace
This commit is contained in:
1 parent
b1f1cfe32b
commit
5cd5c2e6be
35 files changed
+1922
-1592
No files matched your search
@@ -12,4 +12,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define MONTAUK_BUILD_NUMBER 151
|
||||
#define MONTAUK_BUILD_NUMBER 155
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Sdr.hpp
|
||||
* Software-defined radio receive syscalls.
|
||||
* SYS_SDR_COUNT / INFO / OPEN / CLOSE / START / STOP / READ / SETPARAM / GETPARAM
|
||||
* Thin syscall layer over the generic SDR subsystem (Drivers::Radio::Sdr).
|
||||
* Copyright (c) 2026 Daniel Hammer
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <Drivers/Radio/Sdr.hpp>
|
||||
|
||||
#include "Syscall.hpp"
|
||||
|
||||
namespace montauk::abi {
|
||||
|
||||
static int64_t Sys_SdrCount() {
|
||||
return (int64_t)Drivers::Radio::Sdr::Count();
|
||||
}
|
||||
|
||||
static int64_t Sys_SdrInfo(int index, SdrDeviceInfo* out) {
|
||||
if (!out) return -1;
|
||||
return Drivers::Radio::Sdr::GetInfo(index, out) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int64_t Sys_SdrOpen(int index) {
|
||||
return (int64_t)Drivers::Radio::Sdr::Open(index);
|
||||
}
|
||||
|
||||
static int64_t Sys_SdrClose(int handle) {
|
||||
return (int64_t)Drivers::Radio::Sdr::Close(handle);
|
||||
}
|
||||
|
||||
static int64_t Sys_SdrStart(int handle) {
|
||||
return (int64_t)Drivers::Radio::Sdr::Start(handle);
|
||||
}
|
||||
|
||||
static int64_t Sys_SdrStop(int handle) {
|
||||
return (int64_t)Drivers::Radio::Sdr::Stop(handle);
|
||||
}
|
||||
|
||||
static int64_t Sys_SdrRead(int handle, uint8_t* buf, uint32_t len) {
|
||||
if (!buf) return -1;
|
||||
return (int64_t)Drivers::Radio::Sdr::Read(handle, buf, len);
|
||||
}
|
||||
|
||||
static int64_t Sys_SdrSetParam(int handle, int param, uint64_t value) {
|
||||
return (int64_t)Drivers::Radio::Sdr::SetParam(handle, param, value);
|
||||
}
|
||||
|
||||
static int64_t Sys_SdrGetParam(int handle, int param) {
|
||||
return (int64_t)Drivers::Radio::Sdr::GetParam(handle, param);
|
||||
}
|
||||
|
||||
}
|
||||
+37
-22
@@ -33,7 +33,7 @@
|
||||
#include "Window.hpp" // SYS_WINCREATE, SYS_WINDESTROY, SYS_WINPRESENT, SYS_WINPOLL, SYS_WINENUM, SYS_WINMAP, SYS_WINSENDEVENT, SYS_WINRESIZE, SYS_WINSETCURSOR, SYS_WINSETFLAGS, SYS_WINSETSCALE, SYS_WINGETSCALE
|
||||
#include "Audio.hpp" // SYS_AUDIOOPEN, SYS_AUDIOCLOSE, SYS_AUDIOWRITE, SYS_AUDIOCTL
|
||||
#include "BluetoothSyscall.hpp" // SYS_BTSCAN, SYS_BTCONNECT, SYS_BTDISCONNECT, SYS_BTLIST, SYS_BTINFO
|
||||
#include "Sdr.hpp" // SYS_SDR_COUNT, SYS_SDR_INFO, SYS_SDR_OPEN, SYS_SDR_CLOSE, SYS_SDR_START, SYS_SDR_STOP, SYS_SDR_READ, SYS_SDR_SETPARAM, SYS_SDR_GETPARAM
|
||||
#include "Usb.hpp" // generic process-owned USB interface access
|
||||
#include "WifiSyscall.hpp" // SYS_WIFI_SCAN, SYS_WIFI_INFO, SYS_WIFI_CONNECT, SYS_WIFI_DISCONNECT
|
||||
#include "IpcSyscall.hpp" // SYS_DUPHANDLE, SYS_WAIT_HANDLE, SYS_STREAM_CREATE, SYS_STREAM_READ, SYS_STREAM_WRITE, SYS_MAILBOX_CREATE, SYS_MAILBOX_SEND, SYS_MAILBOX_RECV, SYS_WAITSET_CREATE, SYS_WAITSET_ADD, SYS_WAITSET_REMOVE, SYS_WAITSET_WAIT, SYS_PROC_OPEN, SYS_SURFACE_CREATE, SYS_SURFACE_MAP, SYS_SURFACE_RESIZE
|
||||
#include "LibSyscall.hpp" // SYS_LOAD_LIB, SYS_UNLOAD_LIB, SYS_DLSYM
|
||||
@@ -420,26 +420,41 @@ namespace montauk::abi {
|
||||
return Sys_AudioList((AudioStreamInfo*)frame->arg1, (int)frame->arg2);
|
||||
case SYS_AUDIOWAIT:
|
||||
return Sys_AudioWait(frame->arg1, frame->arg2);
|
||||
case SYS_SDR_COUNT:
|
||||
return Sys_SdrCount();
|
||||
case SYS_SDR_INFO:
|
||||
if (!UserMemory::Writable<SdrDeviceInfo>(frame->arg2)) return -1;
|
||||
return Sys_SdrInfo((int)frame->arg1, (SdrDeviceInfo*)frame->arg2);
|
||||
case SYS_SDR_OPEN:
|
||||
return Sys_SdrOpen((int)frame->arg1);
|
||||
case SYS_SDR_CLOSE:
|
||||
return Sys_SdrClose((int)frame->arg1);
|
||||
case SYS_SDR_START:
|
||||
return Sys_SdrStart((int)frame->arg1);
|
||||
case SYS_SDR_STOP:
|
||||
return Sys_SdrStop((int)frame->arg1);
|
||||
case SYS_SDR_READ:
|
||||
if (!UserMemory::Range(frame->arg2, frame->arg3, true)) return -1;
|
||||
return Sys_SdrRead((int)frame->arg1, (uint8_t*)frame->arg2, (uint32_t)frame->arg3);
|
||||
case SYS_SDR_SETPARAM:
|
||||
return Sys_SdrSetParam((int)frame->arg1, (int)frame->arg2, frame->arg3);
|
||||
case SYS_SDR_GETPARAM:
|
||||
return Sys_SdrGetParam((int)frame->arg1, (int)frame->arg2);
|
||||
case SYS_USB_LIST: {
|
||||
if ((int64_t)frame->arg2 < 0) return USB_ERR_INVALID;
|
||||
uint64_t maxCount = frame->arg2 > 16 ? 16 : frame->arg2;
|
||||
if (!UserMemory::Range(frame->arg1,
|
||||
maxCount * sizeof(UsbInterfaceInfo), true)) return USB_ERR_INVALID;
|
||||
return Sys_UsbList((UsbInterfaceInfo*)frame->arg1, (int)maxCount);
|
||||
}
|
||||
case SYS_USB_CLAIM:
|
||||
if (frame->arg1 == 0 || frame->arg1 > 16 || frame->arg2 > 255)
|
||||
return USB_ERR_INVALID;
|
||||
return Sys_UsbClaim((uint8_t)frame->arg1, (uint8_t)frame->arg2);
|
||||
case SYS_USB_CLOSE:
|
||||
return Sys_UsbClose((int)frame->arg1);
|
||||
case SYS_USB_CONTROL: {
|
||||
if (!UserMemory::Readable<UsbControlRequest>(frame->arg2)) return USB_ERR_INVALID;
|
||||
UsbControlRequest request = *(const UsbControlRequest*)frame->arg2;
|
||||
if (frame->arg4 > 4096 || frame->arg4 != request.length) return USB_ERR_INVALID;
|
||||
bool deviceToHost = (request.requestType & 0x80) != 0;
|
||||
if (frame->arg4 != 0 &&
|
||||
!UserMemory::Range(frame->arg3, frame->arg4, deviceToHost)) return USB_ERR_INVALID;
|
||||
return Sys_UsbControl((int)frame->arg1, &request,
|
||||
(void*)frame->arg3, (uint32_t)frame->arg4);
|
||||
}
|
||||
case SYS_USB_BULK_IN_START:
|
||||
if (frame->arg2 > 0xffffffffULL || frame->arg3 > 0xffffffffULL)
|
||||
return USB_ERR_INVALID;
|
||||
return Sys_UsbBulkInStart((int)frame->arg1, (uint32_t)frame->arg2,
|
||||
(uint32_t)frame->arg3);
|
||||
case SYS_USB_BULK_IN_STOP:
|
||||
return Sys_UsbBulkInStop((int)frame->arg1);
|
||||
case SYS_USB_BULK_IN_READ:
|
||||
if (frame->arg3 > 0xffffffffULL) return USB_ERR_INVALID;
|
||||
if (!UserMemory::Range(frame->arg2, frame->arg3, true)) return USB_ERR_INVALID;
|
||||
return Sys_UsbBulkInRead((int)frame->arg1, (uint8_t*)frame->arg2,
|
||||
(uint32_t)frame->arg3);
|
||||
case SYS_POWERINFO:
|
||||
if (!UserMemory::Writable<PowerInfo>(frame->arg1)) return -1;
|
||||
return Sys_PowerInfo((PowerInfo*)frame->arg1);
|
||||
@@ -655,7 +670,7 @@ namespace montauk::abi {
|
||||
|
||||
Kt::KernelLogStream(Kt::OK, "Syscall") << "SYSCALL/SYSRET initialized (LSTAR="
|
||||
<< kcp::hex << (uint64_t)SyscallEntry << kcp::dec << ", "
|
||||
<< (SYS_TERMINAL_ATTACHED + 1) << " syscall slots)";
|
||||
<< (SYS_USB_BULK_IN_READ + 1) << " syscall slots)";
|
||||
}
|
||||
|
||||
}
|
||||
+63
-37
@@ -275,16 +275,16 @@ namespace montauk::abi {
|
||||
static constexpr uint64_t SYS_BTBONDS = 138;
|
||||
static constexpr uint64_t SYS_BTFORGET = 139;
|
||||
|
||||
/* Sdr.hpp -- software-defined radio receive API */
|
||||
static constexpr uint64_t SYS_SDR_COUNT = 140; // number of receivers
|
||||
static constexpr uint64_t SYS_SDR_INFO = 141; // (index, SdrDeviceInfo*)
|
||||
static constexpr uint64_t SYS_SDR_OPEN = 142; // (index) -> handle
|
||||
static constexpr uint64_t SYS_SDR_CLOSE = 143; // (handle)
|
||||
static constexpr uint64_t SYS_SDR_START = 144; // (handle) begin streaming
|
||||
static constexpr uint64_t SYS_SDR_STOP = 145; // (handle) stop streaming
|
||||
static constexpr uint64_t SYS_SDR_READ = 146; // (handle, buf, len) -> bytes
|
||||
static constexpr uint64_t SYS_SDR_SETPARAM = 147; // (handle, param, value)
|
||||
static constexpr uint64_t SYS_SDR_GETPARAM = 148; // (handle, param) -> value
|
||||
/* Reserved: former SDR API. Kept unavailable to preserve ABI numbering. */
|
||||
static constexpr uint64_t SYS_RESERVED_140 = 140;
|
||||
static constexpr uint64_t SYS_RESERVED_141 = 141;
|
||||
static constexpr uint64_t SYS_RESERVED_142 = 142;
|
||||
static constexpr uint64_t SYS_RESERVED_143 = 143;
|
||||
static constexpr uint64_t SYS_RESERVED_144 = 144;
|
||||
static constexpr uint64_t SYS_RESERVED_145 = 145;
|
||||
static constexpr uint64_t SYS_RESERVED_146 = 146;
|
||||
static constexpr uint64_t SYS_RESERVED_147 = 147;
|
||||
static constexpr uint64_t SYS_RESERVED_148 = 148;
|
||||
|
||||
/* Power.hpp -- CPU power/thermal status */
|
||||
static constexpr uint64_t SYS_POWERINFO = 149; // (PowerInfo*) -> 0, -1 unsupported
|
||||
@@ -327,17 +327,26 @@ namespace montauk::abi {
|
||||
static constexpr uint64_t SYS_SETENVIRON = 172;
|
||||
static constexpr uint64_t SYS_SPAWN_ENV = 173;
|
||||
|
||||
// Tunable parameters (for SYS_SDR_SETPARAM / SYS_SDR_GETPARAM).
|
||||
static constexpr int SDR_PARAM_FREQ = 0; // center frequency, Hz
|
||||
static constexpr int SDR_PARAM_SAMPLE_RATE = 1; // sample rate, Hz
|
||||
static constexpr int SDR_PARAM_GAIN_MODE = 2; // 0 = auto/AGC, 1 = manual
|
||||
static constexpr int SDR_PARAM_GAIN = 3; // tuner gain, tenths of dB
|
||||
static constexpr int SDR_PARAM_FREQ_CORR = 4; // frequency correction, ppm
|
||||
static constexpr int SDR_PARAM_AGC = 5; // demod digital AGC, 0/1
|
||||
static constexpr int SDR_PARAM_DIRECT_SAMP = 6; // direct sampling: 0=off,1=I,2=Q
|
||||
/* Generic userspace USB interface access */
|
||||
static constexpr uint64_t SYS_USB_LIST = 178; // (UsbInterfaceInfo*, max) -> count
|
||||
static constexpr uint64_t SYS_USB_CLAIM = 179; // (slot, interface) -> owned handle
|
||||
static constexpr uint64_t SYS_USB_CLOSE = 180; // (handle)
|
||||
static constexpr uint64_t SYS_USB_CONTROL = 181; // (handle, UsbControlRequest*, data, len)
|
||||
static constexpr uint64_t SYS_USB_BULK_IN_START = 182; // (handle, transferBytes, buffers)
|
||||
static constexpr uint64_t SYS_USB_BULK_IN_STOP = 183; // (handle)
|
||||
static constexpr uint64_t SYS_USB_BULK_IN_READ = 184; // (handle, data, len) -> bytes
|
||||
|
||||
// Sample formats reported in SdrDeviceInfo.sampleFormat.
|
||||
static constexpr uint8_t SDR_FORMAT_CU8 = 0; // 8-bit unsigned interleaved I/Q
|
||||
|
||||
// Generic USB errors. Claims are restricted to interfaces without a
|
||||
// bound in-kernel class driver and are owned by the claiming process.
|
||||
static constexpr int USB_ERR_INVALID = -1;
|
||||
static constexpr int USB_ERR_BUSY = -2;
|
||||
static constexpr int USB_ERR_DISCONNECTED = -3;
|
||||
static constexpr int USB_ERR_UNSUPPORTED = -4;
|
||||
static constexpr int USB_ERR_IO = -5;
|
||||
static constexpr int USB_ERR_NO_RESOURCES = -6;
|
||||
static constexpr int USB_ERR_NOT_FOUND = -7;
|
||||
static constexpr int USB_ERR_KERNEL_BOUND = -8;
|
||||
|
||||
// Graceful power-off request actions (SYS_POWER_REQUEST). The desktop posts
|
||||
// a pending action and exits; login.elf reads it, runs the shutdown stages,
|
||||
@@ -658,23 +667,40 @@ namespace montauk::abi {
|
||||
uint8_t _pad[2];
|
||||
};
|
||||
|
||||
// Software-defined radio receiver description (returned by SYS_SDR_INFO).
|
||||
struct SdrDeviceInfo {
|
||||
char name[64]; // e.g. "Realtek RTL2832U"
|
||||
char tuner[32]; // e.g. "Rafael Micro R820T2"
|
||||
char serial[32]; // device serial / bus location
|
||||
uint64_t freqMin; // minimum tunable center frequency, Hz
|
||||
uint64_t freqMax; // maximum tunable center frequency, Hz
|
||||
uint32_t sampleRateMin; // minimum sample rate, Hz
|
||||
uint32_t sampleRateMax; // maximum sample rate, Hz
|
||||
uint32_t numGains; // number of discrete tuner gain steps
|
||||
int32_t gains[32]; // available gains, tenths of dB
|
||||
uint8_t sampleFormat; // SDR_FORMAT_*
|
||||
uint8_t present; // 1 if the underlying hardware is connected
|
||||
uint8_t streaming; // 1 if currently delivering samples
|
||||
uint8_t _pad;
|
||||
uint32_t _pad2;
|
||||
};
|
||||
// One USB interface currently represented by the xHCI device table. A
|
||||
// nonzero kernelDriverBound interface cannot be claimed by userspace.
|
||||
struct UsbInterfaceInfo {
|
||||
uint8_t slotId;
|
||||
uint8_t portId;
|
||||
uint8_t speed; // xHCI speed ID
|
||||
uint8_t interfaceNumber;
|
||||
uint16_t vendorId;
|
||||
uint16_t productId;
|
||||
uint8_t deviceClass;
|
||||
uint8_t interfaceClass;
|
||||
uint8_t interfaceSubClass;
|
||||
uint8_t interfaceProtocol;
|
||||
uint8_t bulkInEndpoint; // USB address, including direction bit
|
||||
uint8_t bulkOutEndpoint;
|
||||
uint16_t bulkInMaxPacket;
|
||||
uint16_t bulkOutMaxPacket;
|
||||
uint8_t kernelDriverBound;
|
||||
uint8_t claimed;
|
||||
uint8_t _reserved[4];
|
||||
} __attribute__((packed));
|
||||
|
||||
// Standard USB setup packet fields. requestType bit 7 determines the data
|
||||
// direction. length must match the data length passed to SYS_USB_CONTROL.
|
||||
struct UsbControlRequest {
|
||||
uint8_t requestType;
|
||||
uint8_t request;
|
||||
uint16_t value;
|
||||
uint16_t index;
|
||||
uint16_t length;
|
||||
} __attribute__((packed));
|
||||
static_assert(sizeof(UsbInterfaceInfo) == 24);
|
||||
static_assert(sizeof(UsbControlRequest) == 8);
|
||||
|
||||
|
||||
// Wi-Fi security suites reported in WifiNetwork.security.
|
||||
static constexpr uint8_t WIFI_SEC_OPEN = 0;
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Usb.hpp
|
||||
* Generic userspace USB interface syscall layer.
|
||||
* Copyright (c) 2026 Daniel Hammer
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Drivers/USB/UserUsb.hpp>
|
||||
|
||||
namespace montauk::abi {
|
||||
|
||||
static int64_t Sys_UsbList(UsbInterfaceInfo* out, int maxCount) {
|
||||
return Drivers::USB::UserUsb::List(out, maxCount);
|
||||
}
|
||||
|
||||
static int64_t Sys_UsbClaim(uint8_t slotId, uint8_t interfaceNumber) {
|
||||
return Drivers::USB::UserUsb::Claim(slotId, interfaceNumber);
|
||||
}
|
||||
|
||||
static int64_t Sys_UsbClose(int handle) {
|
||||
return Drivers::USB::UserUsb::Close(handle);
|
||||
}
|
||||
|
||||
static int64_t Sys_UsbControl(int handle, const UsbControlRequest* request,
|
||||
void* data, uint32_t dataLen) {
|
||||
if (!request) return USB_ERR_INVALID;
|
||||
return Drivers::USB::UserUsb::Control(handle, *request, data, dataLen);
|
||||
}
|
||||
|
||||
static int64_t Sys_UsbBulkInStart(int handle, uint32_t transferBytes,
|
||||
uint32_t bufferCount) {
|
||||
return Drivers::USB::UserUsb::StartBulkIn(handle, transferBytes, bufferCount);
|
||||
}
|
||||
|
||||
static int64_t Sys_UsbBulkInStop(int handle) {
|
||||
return Drivers::USB::UserUsb::StopBulkIn(handle);
|
||||
}
|
||||
|
||||
static int64_t Sys_UsbBulkInRead(int handle, uint8_t* out, uint32_t maxLen) {
|
||||
return Drivers::USB::UserUsb::ReadBulkIn(handle, out, maxLen);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user