Perform pseudo-filesystem permission checks inside inode_reserve() and
inode_remove() while the inode tree lock is held, and hold that lock across
pseudorename mutations so symlink swaps cannot bypass directory checks.
Hold a read lock around pseudo-fs open permission checks.
On setuid/setgid exec, update saved set-IDs, mark the task group secure,
sanitize dangerous environment variables, clear debug/dumpable flags, and
add issetugid(), secure_getenv(), and PR_SET/GET_DUMPABLE support.
Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
The watchdog documentation includes the new functionality of the
driver's char device: When reading from it, it emits information
about the watchdog status including flags, timeout and timeleft
as milliseconds. An example has been included as well.
Signed-off-by: Javier Alonso <dev@javinator9889.com>
Currently, the `read` function of the watchdog device is dummy and
does nothing. Although this is fine, it's not useful at all from a
userspace perspective, where you may want to check the current WDOG
status.
A wrapper around the `ioctl` `WDIOC_GETSTATUS` has been added as
the `read` function for the WDOG.
Signed-off-by: Javier Alonso <javieralonso@geotab.com>
Allow pull requests targeting master to declare same- and
cross-repository dependencies. Parse declarations with a tested Python
helper, apply exact dependency commits before the existing build matrix,
and rerun heavy CI only when an edited description changes the dependency
state.
Keep fork builds read-only and use a trusted workflow_run to validate
artifacts and post per-build dependency results. Document the supported
declaration forms and operational limits.
Assisted-by: Kiro:gpt-5.6-sol
Signed-off-by: zhangning21 <zhangning21@xiaomi.com>
The strto* interfaces document explicit bases in the range 2 through 36, and lib_isbasedigit() already supports alphabetic digits through base 36. However, lib_checkbase() rejects every explicit base above 26 with EINVAL.
Raise the validation limit to 36 so the conversion interfaces accept the full documented range while continuing to reject base 37 and above.
Signed-off-by: hanzhijian <hanzhijian@zepp.com>
When querying the calling task itself (pid == 0 or the caller's own
pid), nxsched_get_param() only filled in sched_priority and never
touched the SCHED_SPORADIC related members (sched_ss_low_priority,
sched_ss_max_repl, sched_ss_repl_period and sched_ss_init_budget).
With CONFIG_SCHED_SPORADIC enabled, the caller received uninitialized
stack garbage in these fields, and a task running under the sporadic
policy could not retrieve its own sporadic parameters.
Fix this by factoring the sporadic parameter fill-in into a common
helper nxsched_get_sporadic_param() shared by both the self-query and
the lookup paths, so both paths now return identical information.
The self-query path keeps its original fast-path behavior: no TCB
lookup and a lock-free read of sched_priority. Only the read of the
sporadic state is wrapped in a critical section, because tcb->sporadic
may be freed concurrently, e.g. by sched_setscheduler() from another
CPU switching the task away from SCHED_SPORADIC.
Signed-off-by: yushuailong <yyyusl@qq.com>
- ISO1H812G is *output* only expander, not input.
- Warning make sense when we try to set the expander the wrong way.
Signed-off-by: Jiri Vlasak <jvlasak@elektroline.cz>
apache/nuttx#19586 removed HIDKBD_ENCODED and made USBHOST_HIDKBD select
INPUT, but four configurations still name one or both, so they do not
survive a refresh and the normalisation step fails:
boards/arm/sama5/sama5d4-ek/configs/ipv6
boards/arm/sama5/sama5d4-ek/configs/nsh
boards/arm/sama5/sama5d4-ek/configs/nxwm
boards/arm/stm32h7/linum-stm32h753bi/configs/lvglterm_kbda
Removing the lines is the whole fix. INPUT still ends up enabled through
the select, and encoding now comes from INPUT_KEYBOARD_BYTESTREAM, which
the one configuration that wanted it already sets.
Nothing changes in the resulting .config, which is why the build never
noticed: Kconfig drops an option that no longer exists without saying
anything, and only the refresh compares the file before and after.
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
The compiler-rt builtins build globs every arm/*.S source, but several of
those hand-written assembly files require FPU features the target may not
have. Upstream compiler-rt selects them conditionally; NuttX did not, so
BUILTIN_COMPILER_RT builds for single-precision-FPU Arm targets (e.g.
Cortex-M33, -mfpu=fpv5-sp-d16) failed to assemble with errors such as
"selected FPU does not support instruction -- vadd.f64".
Filter the source list to match the configured FPU, in both the Makefile
and CMake builds:
- chkstk.S / chkstk2.S are Windows/MinGW-only stack probes, always dropped;
- with no hardware FPU (!CONFIG_ARCH_FPU) all arm/*vfp.S are dropped;
- with a single-precision FPU (!CONFIG_ARCH_DPFPU) the double-precision
*df*vfp.S routines are dropped.
Reproduced against compiler-rt 17.0.1 with arm-none-eabi-gcc 14.2 using the
Cortex-M33 single-precision flags: 18 of 86 arm/*.S files failed to assemble
(17 double-precision *df*vfp.S plus chkstk.S); after the filter all remaining
68 files assemble cleanly.
Fixes: https://github.com/apache/nuttx/issues/17386
Generated-by: Claude (Anthropic)
Signed-off-by: Udit Jain <uditjainstjis@gmail.com>
The Fn cursor cluster was reported as ordinary key presses carrying 0x80
to 0x83, chosen to sit above the printable range so that an application
could tell them apart from characters. That is the collision this work
exists to remove: a key that produces no character is a special key, and
the event type is what says so.
Report them as KEYBOARD_SPECPRESS carrying KEYCODE_UP and friends, which
is what every other keyboard does and what the applications now expect.
The character tables are untouched, so the layout and the shift map behave
exactly as before. Only the four Fn cursor keys change.
Not tested on hardware: the board was not available. It builds, and the
change is confined to the two lines that pick the event type.
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
The X11 keyboard reported any keysym that its translation table did not
know as an ordinary key press carrying the raw keysym. An application
looking for a byte of text got 65307 for Escape and 65289 for Tab, and
the modifiers arrived as 65505 and friends.
That is not a character, so it cannot be a KEYBOARD_PRESS. NXDoom on
the simulator has therefore had no menu, no map and no fire, which is
most of the game.
Escape and Tab are control characters and are reported as such. The
eight modifiers get the keycodes that the codec now has for them. And a
keysym above the Latin-1 range that no table knows is not reported at
all, which closes the case rather than the three instances of it.
Verified by dumping the events while typing: Escape arrives as 27, Tab
as 9, the modifiers as keycodes 88 to 95, and the game plays.
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
The keyboard driver documentation described the byte stream codec and
nothing else. It never mentioned keyboard_register(), keyboard_event()
or the event types, so somebody writing a driver had no way to find the
interface that every keyboard in the tree actually uses.
That omission has a cost that can be counted: six of the nine drivers
that register a keyboard report only the press and release types and
never the special ones, which means their arrow keys are silently
dropped by any application that follows the contract. The header they
would read to find out declares two of the four types.
Document the contract, why the event type is what tells an arrow key
from the character that shares its value, what to name the device, how
to get a matrix keyboard working without writing a driver at all, and
how to test the result with or without the hardware.
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
The matrix driver reported every key with KEYBOARD_PRESS and
KEYBOARD_RELEASE, so a board whose matrix has arrows or function keys
had no way to say so: the keycode ranges overlap the character range,
and the event type is what tells them apart.
A keymap entry is a uint32_t, so wrap the entry in KMATRIX_SPECIAL() to
declare that it holds a value from enum kbd_keycode_e. Existing keymaps
hold characters and are unaffected.
While here, drop the cast that truncated the keycode to sixteen bits,
and default the device to /dev/kbd0. Applications look for a keyboard
under that name, and /dev/keypad0 kept the matrix out of reach of every
one of them.
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
These are the configurations whose application reads the USB HID keyboard
as a byte stream. Now that the driver reports through the keyboard upper
half, they need INPUT_KEYBOARD_BYTESTREAM to keep behaving as before.
INPUT drops out of the normalised defconfigs because USBHOST_HIDKBD now
selects it.
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
The driver kept a character device, a ring buffer, a poll waiter list
and an encoder of its own, in parallel with everything the keyboard
upper half already provides. A USB keyboard was therefore the one
keyboard an application could not read like any other.
Register with keyboard_register() and report with keyboard_event(),
which removes the private character device and the four hundred lines
that served it. Special keys are reported with the SPEC event types
carrying a keycode, so an application no longer has to guess whether a
value in the character range is a character or an arrow key.
HIDKBD_ENCODED and HIDKBD_NODEBOUNCE go away with the code they guarded.
Encoding is now inherent to the event, and the previous report is no
longer an optimisation: a HID keyboard reports the keys that are down
rather than the transitions, so it is what tells a new press from a key
still held, and what tells that a key has been released.
Reporting the modifiers as keys is new, so it is behind
HIDKBD_REPORT_MODIFIERS and off by default.
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
Both switches end with a bare default label and no statement after it,
which a compiler is entitled to reject: a label has to label something.
GCC for MIPS does, and the file is new enough that no configuration had
compiled it yet.
The next commit makes USBHOST_HIDKBD select INPUT_KEYBOARD, which pulls
this file into twenty five configurations for the first time, ci20:jumbo
among them, so fix it here rather than let that commit break them.
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
The USB HID keyboard driver is about to report through the upper half
rather than through a character device of its own, which changes what
read() returns from a byte stream to struct keyboard_event_s. Ten
in-tree configurations have an application that consumes the byte
stream.
Add INPUT_KEYBOARD_BYTESTREAM, which renders each event with the
keyboard codec instead of copying the event structure, so those
applications keep working while they are converted.
Only the press events are rendered. A byte stream has no way to say
that a key came up, which is exactly what a keyboard reporting through a
character device has always delivered, so this reproduces the previous
behaviour rather than adding to it.
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
keyboard.h declares KEYBOARD_PRESS and KEYBOARD_RELEASE only, but the
type field of struct keyboard_event_s has four values: the two special
key types live in kbd_codec.h, under a different prefix.
Somebody writing a keyboard driver reads keyboard.h, sees two types, and
implements two types. Six of the nine drivers that register a keyboard
never report a special key at all, and the failure is silent: the build
is clean and the symptom is a key that does nothing.
Define all four here, as aliases of the kbd_decode() return values so
that a driver can feed both this interface and the byte stream codec
from a single source.
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
A keyboard driver that tracks modifier state has no way to report it.
Folding the modifier into the character that it produces loses the fact
that the key is down, so an application cannot bind an action to Ctrl or
Shift, and cannot tell that one is being held.
Add the eight modifiers to enum kbd_keycode_e and move LAST_KEYCODE to
the new end of the enumeration. Leaving LAST_KEYCODE behind would make
kbd_specpress() assert and kbd_decode() reject the new keycodes, since
both range check against it.
The keycodes are appended, so the values of the existing ones do not
change.
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
Wire the shared Ameba GPIO driver into the RTL8721F (amebagreen2) build and
add the EVB board glue:
- arch/arm/src/rtl8721f: build ameba_gpio.c (CMake/Make.defs), source the
common Ameba Kconfig, and add ameba_gpio_chip.h describing the chip's
three GPIO ports (A/B/C), their IRQs and the APBPeriph clock bit.
- arch/arm/src/common/ameba: teach the driver that amebagreen2's ROM
GPIO_Init does not call PAD_PullCtrl or GPIO_INTMode, so call both
explicitly after GPIO_Init; on RTL8721Dx (ram_common) these are harmless
redundant writes. Add the AMEBA_PORT_C / AMEBA_PC() helpers.
- boards/arm/rtl8721f/rtl8721f_evb: register output/input/interrupt demo
pins, add the bringup hook, and provide a minimal 'gpio' NSH defconfig.
- Documentation: add a GPIO section for the RTL8721F EVB and fix a
rising/falling typo in the PKE8721DAF page.
Hardware-verified on the RTL8721F EVB: output, input, and all interrupt
trigger/polarity combinations (rising/falling edge, level high/low).
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
The shared port ISR clears interrupt status with GPIO_INTStatusClearEdge(),
which only clears edge latches. For a level-triggered pin the status stays
asserted as long as the level is active, so the ISR re-enters forever once
the level fires -- the system hangs before the application can even service
the event.
Remember at configure time whether a pin is level-triggered, and in the ISR
mask such a pin (GPIO_INTConfig DISABLE) before invoking the callback. The
application re-enables it via go_enable() after servicing. Edge pins are
left unmasked, so their behaviour is unchanged.
This fixes a hang reproducible on RTL8721Dx and RTL8721F when a
level-high/level-low interrupt pin is used.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
The fix was ported from the STM32G0 to all the STM32 platforms,
as the code is mostly the same hence presents the same failure
Signed-off-by: Javier Alonso <javieralonso@geotab.com>
When the interrupts get disabled, the callback(s) are still attached.
That structure is never cleared, causing several calls to attach/detach
to eventually fail as the callback queue gets full.
When the error occurs, the registration fails with error 12 (ENOMEM).
By detaching the IRQ and clearing the callbacks, this error doesn't
happen again
Signed-off-by: Javier Alonso <javieralonso@geotab.com>
Remove CONFIG_FSUTILS_PASSWD from 31 sim configs that do not use NSH
login or other passwd features. These configs lacked a cryptodev
backend required by FSUTILS_PASSWD after the PBKDF2 Kconfig tightening,
causing olddefconfig normalization failures in CI.
Fixes#19573
Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Restore the explicit signed conversion and parenthesize the sign-bit test
so it is evaluated before the bitwise AND. Without this, operator
precedence makes the decoder test bit zero instead of the sign bit and
negative inline operands are reported as large positive values.
Build the width mask without shifting by the full width of uint64_t.
This avoids recursively invoking UBSan while decoding a 64-bit inline
operand.
Signed-off-by: hanzhijian <hanzhijian@zepp.com>
Add platform documentation for the Realtek RTL8721F: a chip overview
page and the rtl8721f_evb board page, modelled on the existing RTL8720F
/ RTL8721Dx docs. The platform index picks them up automatically via
its */index glob.
The pages cover the vendor-SDK/toolchain dependency, the make and CMake
build/flash flow, and the hardware-verified features: NSH over the
LOG-UART console, littlefs at /data on the on-chip NOR flash, Wi-Fi
station and SoftAP via the wapi tool, and the DHCP client/server.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Co-Authored-By: Claude <noreply@anthropic.com>
Bring up the last two RTL8721F feature blocks and wire them into the
nsh board configuration:
- littlefs on the on-chip flash MTD region (P2).
- WHC/INIC WiFi with the on-chip IPC control plane, NuttX net stack,
DHCP client and the wapi command tool (P3).
Two porting fixes were required for the WiFi control plane:
- ameba_ipc.c: the AP IPC device base (IPCAP_DEV) was carried over
verbatim from the RTL8720F template (0x40804000). On this SoC IPC0
lives at 0x40815000; using the wrong base makes ipc_table_init()
program the RX-full mask in the wrong register block, so the NP->AP
interrupt never fires and WiFi bring-up hangs waiting for the device
to answer. Point IPCAP_DEV at the correct 0x40815000 base.
- ameba_board.mk: the EVB silicon is B-cut, so link against the
ameba_rom_symbol_bcut*.ld ROM symbol tables (the A-cut tables resolve
the WiFi ROM helpers to the wrong addresses and fault at run time).
Validated on hardware: NSH comes up, wapi scan lists real APs, a WPA2
connect succeeds, the DHCP client obtains a lease and ICMP to the
public internet round-trips.
The board defconfig keeps SSID/passphrase as placeholders; real
credentials are supplied at run time via the wapi commands.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Wire the RTL8721F km4tz core up to a working NuttShell:
- irq.h: renumber the KM4TZ external vector table to the RTL8721F
APIRQn map (UART_LOG=24, IPC=5, +GPIOB/C, TIMER7/8, ...).
- ameba_loguart.c: fix the LOG-UART base to 0x40810000. The former
0x401C6000 belongs to a different Ameba part; the wrong base bus-
faulted on the RX interrupt-enable write while TX still worked
(LOGUART_PutChar uses its own ROM-internal base).
- ameba_app_start.c: adjust the MPU read-only / RAM regions for the
RTL8721F memory map and seed the RTC on first power-on so the
SDM32K-clocked SYSTIMER comes up (mirrors the SDK app_rtc_init).
- ameba_ipc.c: move the km4tz<->km4ns IPC to APIRQn 5 (IPC_CPU0).
- ameba_board.mk: pull in fwlib ameba_rtc.c for the RTC_* symbols.
- defconfig: RTL8721F RAM map, enable TIMER/TIMER_ARCH/ARMV8M_SYSTICK
for a live system tick, and drop the WiFi/NET stack for now.
- scripts/Make.defs: use the RTL8721F_NOR flash profile.
Boots cleanly to nsh> on hardware; tick, RX and builtin apps verified.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Add a P0 skeleton port for the Realtek RTL8721F (SDK codename Green2 /
amebagreen2). Structurally the RTL8721F is a twin of the RTL8720F -- the
AP/host core is km4tz (ARMv8-M.main, TrustZone secure) and the WiFi MAC/PHY
runs on the km4ns network-processor core -- so this port is modelled on the
RTL8720F one and shares the IC-agnostic ameba glue in
arch/arm/src/common/ameba.
This is the "configures and links" skeleton (rtl8721f_evb:nsh builds an
image end to end). Four differences from the RTL8720F template were needed
to make the empty shell link against amebagreen2:
* km4tz has no FPU (cmsis_cpu.h defines __FPU_PRESENT 0), so the chip does
not select ARCH_HAVE_FPU and the image is built soft-float.
* ameba_app_start.c matches amebagreen2's ram_km4tz silicon init: the
nocache MPU map, the non-secure ROM BSS clear, OSC4M (not OSC2M)
calibration gated on EFUSE cut >= B and CHIP_TYPE_ASIC_POSTSIM.
* amebagreen2 ships no lib_rom.a, so the ROM archive whole-archive link is
dropped; the WiFi/OS/non-secure ROM symbols come from the SDK
ameba_rom_symbol_acut{,_wifi,_os}.ld maps appended to the image2 linker
script, exactly as green2's own image2 link does.
* the AP WiFi security lib is lib_wifi_common.a (was lib_wifi_com_sec.a).
The per-chip IRQ vector table (irq.h) and the RAM_START/RAM_SIZE layout
still carry RTL8720F values and are refined in the follow-up bring-up work.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
BOARD_ETC_ROMFS_PASSWD_ENABLE now depends on FSUTILS_PASSWD and a
cryptodev backend so PBKDF2 passwd autogen cannot be enabled without
the runtime login stack. Fixes#19573.
Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Enable BOARD_ETC_ROMFS_PASSWD_ENABLE and software cryptodev options on
all sim configs with CONFIG_NSH_CONSOLE_LOGIN so PBKDF2 login works on
NuttX 13.0+. Fixes#19573.
Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
As analyzed, the NuttX initial keyboard API design uses event
type KBD_SPECPRESS/KBD_SPECREL to deliver special keys
and KBD_PRESS/KBD_RELEASE to deliver ASCII codes.
But it seems that this design choice has not been followed
in virtio-input, goldfish_events and sim_keyboard designs
and result is that external keyboard special keys events
are mapped to KEYCODE_xxx values which start from 0 and
overlaps with ASCII keys.
The issue is tracked under #19527 number.
This set of changes correct events reporting for mentioned
keyboards to report right event type for special keys.
The solution is only partial at this phase.
Virtual and more complex keyboards usually deliver
key pressures as scancodes (key position on keyboard)
and mapping to ASCII for keys which corresponds to letter
and other similar keys lacks mapping of national alphabets,
second row symbols and switch to capital letter according
to modifiers.
Signed-off-by: Pavel Pisa <pisa@fel.cvut.cz>
When CONFIG_TESTING_OSTEST_MULTIUSER is enabled, default
CONFIG_LIBC_PASSWD_FILEPATH to a writable tmpfs path used by the
ostest multiuser passwd sub-test.
Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Document setreuid/setregid, getresuid/getresgid, and how inode_reserve
assigns owner and group for pseudo-filesystem objects.
Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Accept user#️⃣uid:gid:home lines produced by mkpasswd in addition
to the six-field gecos form, and raise the default line buffer to 256.
Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Use inode_checkopenperm() for message queues, named semaphores, and
shm, and reallocate mqueue state when reopening after the last close.
Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Set i_owner and i_group from the caller's effective credentials in
inode_reserve(), covering IPC objects, FIFOs, and pseudo-files.
Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Implement POSIX real/effective/saved credential getters and paired
setters in the task group layer, with libc stubs and syscalls.
Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
The USB device controller drivers invoke CLASS_DISCONNECT() on every
USB bus reset, and a bus reset is the first step of normal host
enumeration. Every other class driver (cdcacm, usbmsc, rndis)
re-asserts DEV_CONNECT() at the end of its disconnect() handler so
that the device remains attached; cdcecm and cdcncm did not, so on
controllers that soft-disconnect around bus reset (e.g. rp2040, which
drops the pull-up in its bus-reset handler) a standalone CDC-ECM or
CDC-NCM device is left soft-disconnected by the first bus reset and
never enumerates on the host.
Mirror the cdcacm behavior and perform the soft connect in the
disconnect() methods, unless part of a composite device (composite.c
already re-connects in its own disconnect handler).
Fixes the standalone CDC-ECM case of issue #15880.
Validated on raspberrypi-pico (RP2040): with this change a standalone
CONFIG_NET_CDCECM device that previously never appeared on the host
enumerates via cdc_ether and pings with 0% loss. cdcncm has the
identical defect and receives the identical fix.
Signed-off-by: Ricard Rosson <ricard@groundbits.com>
Co-authored-by: Xiang Xiao <xiaoxiang781216@gmail.com>
Assisted-by: Claude (Anthropic Claude Code)
rp2040_update_buffer_control()/rp23xx_update_buffer_control() re-arm an
endpoint buffer by setting the AVAILABLE bit in the buffer-control word,
which lives in DPSRAM. When a buffer is re-armed from the completion
path (rp2040_usbintr_buffstat/rp23xx_usbintr_buffstat), that runs after
the handler has cleared the endpoint's bit in BUFF_STATUS, which lives in
the USB controller register block -- a different peripheral region.
The bus fabric may reorder those two stores. If the controller observes
the AVAILABLE re-arm before the BUFF_STATUS clear lands, it can transmit
the next IN packet and latch its completion in BUFF_STATUS before the
clear arrives; the late clear then wipes that just-set completion bit.
The lost completion edge stops all further buffer interrupts for the
endpoint, so the class driver's write-complete callback never runs and
TX wedges permanently.
This is most visible on RP2350 (Cortex-M33) under dense/bursty IN traffic
such as CDC-NCM with TCP write buffers. Add a UP_DMB() at the top of the
AVAILABLE re-arm so the preceding BUFF_STATUS clear is ordered ahead of
it. (Non-SMP builds reduce spin_lock_irqsave to a barrier-free
up_irq_save, so nothing else orders these two stores.)
Assisted-by: Claude (Anthropic Claude Code)
Signed-off-by: Ricard Rosson <ricard@groundbits.com>
Adds both xipfs configurations to the board configuration list, and notes
that xipfs-nxflat needs the NXFLAT tools (mknxflat and ldnxflat), which a
standard toolchain installation does not provide.
Impact: documentation only.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
The xipfs configuration enabled CONFIG_NXFLAT and the nxflatxip example,
whose build runs mknxflat to generate the module thunk. The NXFLAT tools
are not installed in the CI container, so every CI build of this
configuration failed with "mknxflat: command not found".
* xipfs keeps the file system, the xipfs command and the test suite. It
builds with a plain toolchain, so CI still covers the file system code.
* xipfs-nxflat adds CONFIG_NXFLAT and CONFIG_EXAMPLES_NXFLATXIP and is
excluded from the CI build list, the same treatment the other NXFLAT
configurations already get (eagle100:nxflat, lm3s6965-ek:qemu-nxflat,
olimex-lpc1766stk:thttpd-nxflat).
Impact: CI and board configurations only. No source or runtime change.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
Pages for the three applications that come with xipfs: the command that
compacts a volume and prints its block map, the test suite and what each of
its sections covers, and the demo that downloads an NXFLAT module into a
volume and runs two instances of it in place.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
A configuration for the Pimoroni Pico Plus 2 that mounts xipfs on the flash
MTD and builds everything that exercises it: the test suite with fault
injection, the xipfs command, and the NXFLAT execute-in-place demo.
Building an NXFLAT module needs mknxflat and ldnxflat, so name them in the
rp23xx board Make.defs files, which already carry the rest of the NXFLAT
flags but not these.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
Describe the write-once usage model, the strict in-place mmap and what
MAP_XIP_STRICT is for, extent pinning, manual defragmentation and how to read
its result, the power-loss ordering, the on-media layout, and the
limitations.
The NXFLAT page said ROMFS was the only file system able to serve the XIP
mappings its loader needs. That is now one of two, so point at both, and at
what the writable one adds: a module can arrive at run time instead of being
baked into a host-built image.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
Give the QEMU boards the same directly addressable media the sim
configuration has: rammtd answers BIOC_XIPBASE with the base of its buffer,
so xipfs layered on it hands out real pointers and the in-place mmap path
can be exercised on an ARM target with no flash present. Registered as
/dev/rammtd and mounted at /mnt/xipfs when xipfs is configured.
Both mps2-an500 (Cortex-M7, armv7e-m) and mps2-an521 (Cortex-M33, armv8-m)
get it, which is what makes the filesystem testable on two different core
generations without either one needing flash.
Each board also gets a xipfs configuration that runs the test suite, so the
bringup above is exercised rather than only compiled. Both run the suite to
completion under QEMU 10.1, 90 checks apiece, the power loss sweeps included.
The an521 configuration carries CONFIG_CMSDK_UART0_RX_IRQ=48 and _TX_IRQ=49
rather than the reversed pair the an521 nsh configuration uses. That is the
SSE-200 order, receive first, and the one consistent both with the overflow
interrupt at 63 that nsh already has and with mps2-an500, which puts RX at 16
and TX at 17. With the pair reversed the TX interrupt reaches
uart_cmsdk_rx_interrupt, which acknowledges only UART_INTSTATUS_RX, so the
board live-locks on its first console write. Correcting nsh is left to a
separate change.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
rammtd answers BIOC_XIPBASE with the base of its RAM buffer, so it is a
usable stand-in for memory mapped NOR: extents are directly addressable and
the in-place mmap path can be exercised end to end without any flash. Mount
xipfs on it when it is the configured file system, and add a configuration
that runs the xipfs test suite, fault injection included.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
The flash MTD device answers BIOC_XIPBASE, which is what xipfs needs to
serve mappings straight out of the memory mapped QSPI flash. Mount it at
/mnt/xipfs when both are configured, formatting on first boot, so a board
comes up with somewhere to download and run a module from.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
A file system that answers statfs with a magic nothing maps to shows up as
"Unrecognized" in df. Give xipfs its constant alongside the others in
sys/statfs.h and the case in fs_gettype that turns it into a name.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
ROMFS is the usual way to carry executables on a NOMMU target with memory
mapped NOR flash: it can hand out a real flash pointer from mmap(), so the
NXFLAT loader maps a module's text in place instead of copying it into RAM.
But a ROMFS image is built on the host and is read only, so a module cannot
be downloaded onto the board at run time.
xipfs is a writable file system with the same in-place property. Each file
is stored as one physically contiguous, erase-block aligned extent, so an
mmap() of it resolves to flash_base + extent_offset and a loader can execute
the file where it already lies. This needs the underlying MTD driver to
answer BIOC_XIPBASE; on the RP2350 rp23xx_flash_mtd.c does.
Files are write once. A file is created, its size is declared, it is
written sequentially, closed, and is thereafter immutable until it is
deleted. That is the whole life cycle of a downloaded module, and it is
what licenses the design: the exact extent is reserved at create time, so
no file ever grows, moves, or fragments internally. Random writes, appends
and truncation of a written file are not supported and are refused.
The only source of fragmentation is therefore free space holes left by
deletes. Allocation fails with -ENOSPC when no single contiguous run is
large enough, and never defragments on its own; the caller decides whether
to compact and retry, through XIPFSIOC_DEFRAG. Defragmentation is manual,
best effort and interruptible: it is a loop of atomic single-extent
relocations, each one copy, commit, erase, so every stop point -- a time
budget, a pinned extent, an erase error -- leaves a consistent layout that
is simply less compact. It reports the largest contiguous run it achieved,
which is what tells the caller whether the retry will fit.
Metadata is committed power safely. Two metadata block sets are used in
ping-pong, each generation carrying a sequence number and a CRC, and every
state change is ordered as write the new data, flip the metadata reference,
then erase what the old one referenced. Mount scans both sets and selects
the last fully valid generation, so a torn write costs the interrupted
operation and nothing else.
A mapping takes a pin on the extent, and the pin lives on the extent rather
than on the file descriptor, so three running instances of one module hold
three pins and the extent becomes movable only when the last one goes.
Defragmentation skips pinned extents, which is what stops it relocating
code that is executing. The pin is released by munmap() or by the task
teardown walk, so a task that dies without unmapping does not leak it.
Directories are records in that same generation, carrying their own identity
and the identity of the directory holding them; the root is implicit and owns
identity zero. They are deliberately NOT objects in the data region, which
is what keeps the commit story in one piece: mkdir and rmdir add or remove a
record and commit one generation, exactly as create and unlink do, so there
is never a multi-object update to journal or an orphan to collect at mount.
An empty directory therefore exists, survives a remount, and costs one entry
out of the volume's fixed supply and no flash blocks at all.
A name is one path component; depth comes from the parent, so XIPFS_NAME_MAX
bounds a component, which is what statfs reports it as. Mount rebuilds the
tree and checks that it is one: identities unique, names unique within a
directory, every parent a live directory, and following parents reaching the
root -- a cycle on the medium would otherwise hang a path walk rather than
merely answering wrongly. '.' and '..' are refused as components, since an
entry stored under either could never be reached again.
The commands that act on the volume rather than on one file --
XIPFSIOC_DEFRAG and XIPFSIOC_LISTPINNED -- are reached through the ioctldir
method, on a descriptor for the mountpoint directory. They are accepted on
a descriptor for a file inside the volume too, but that route holds the file
open for the duration and an open extent cannot be relocated, so a pass
asked for that way is obstructed by the act of asking.
mmap() falls back to the generic RAM copy for ordinary readers when the
media cannot be addressed directly. A module loader must not silently get
a RAM copy, so MAP_XIP_STRICT is added: with it the mapping either resolves
in place or fails with -ENXIO, which the caller can turn into defragment
and retry.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>