nuttx/Documentation/os/drivers/device_nodes.rst
Vinicius May f6ecf80ebb Documentation: brand new layout for NuttX documentation.
The documentation grew one page at a time, so the tree follows the
history of who wrote what and not the shape of NuttX. Scheduling is
spread over three places, a driver page can sit above the subsystem
that owns it, and the front page lists everything at the same level.
That is a lot to face when all you want to know is where the scheduler
lives.

This change files every page under the code it describes. It is a move,
not a rewrite: outside the ten pages named below, every page keeps the
text that is already in master, and no page's text is deleted.

What it does:

* Groups the table of contents into nine chapters.
* Moves the OS subsystems under os/: scheduling, memory, drivers,
  filesystem, networking, IPC, interrupts, libs, time.
* Renames the platform pages to the names the source tree uses, and
  derives their tags from the tree instead of by hand.
* Splits guides/ by subject.
* Adds Documentation/redirects.py, with a rule for every page that left
  its old path, so old URLs keep working. The redirect page also carries
  a link's #anchor across to the new page.

Ten pages have text that is new or rewritten. Nine of them are the
landing page of a chapter, which has to exist for the new structure:

    index                  the front page
    os/index               OS Design
    os/scheduling/index    Scheduling
    os/interrupts/index    Interrupts
    os/ipc/index           IPC
    os/time/index          Time and timers
    about/index            About
    developing/index       Developing NuttX
    ReleaseNotes/index     Release notes

The tenth is os/libs/libbuiltin, the only page here with technical
content: libs/libbuiltin/ had no page at all. Five SVG diagrams come
with these pages, hand-written XML with no editor metadata.

Nothing outside Documentation/ is touched.

How it was checked:

* Sphinx builds with -W: no warnings, and no document left outside a
  toctree.
* A script, offered in the PR, proves the narrow claim this rests on.
  For every page outside the ten named above it erases what a move
  touches -- link target, path, tag line, toctree block, table border --
  from the whole old text and the whole new text, and requires the two
  to be byte for byte identical. It also requires every sentence of a
  deleted page to turn up somewhere, and every page that left its old
  path to have a redirect, from a URL that existed, to where its content
  went. It exits non-zero and names the page if any of that is not true,
  and it tests added pages too, so forgetting to declare one cannot make
  it pass.
* An independent audit checked 133 factual claims on these ten pages
  against the tree, one shell command per claim: 130 confirmed, 1
  refuted and fixed here, 2 not checkable.
* tools/checkpatch.sh is clean over the range.

The diff is large because moving a page changes every link that points
to it. Most of it is pure renames, and board pages that gained one tag
line.

Assisted-by: Claude:claude-opus-5
2026-10-08 01:40:54 +08:00

94 lines
3.9 KiB
ReStructuredText

.. _device-nodes:
============
Device Nodes
============
Linux Device Nodes
==================
I used to have good Linux expertise a decade or so ago.
But my current Linux knowledge is dated and rusty.
I don't know anything about udev, SystemD, devtmpfs, sysfs, or any of that.
So this is my simplified understanding.
Device files work quite a bit differently in Linux and NuttX.
A device node in Unix/Linux only really contains the only type of the device
and its major and minor device numbers, i.e., it just holds data.
So creating the device node does not install or create the driver;
it simply writes a tiny file containing some special data.
Nothing happens until you try to open the device.
If something in the operating system has not initialized and registered
a driver for that type and major/minor numbers,
then you fail to open the device.
So the device nodes and the device drivers are decoupled in Linux/Unix
and there is a rendezvous that must occur later for the device node
to actually refer to the device.
"(..) Linux maps the device special file passed in system calls
(say to mount a file system on a block device) to the device's
device driver using the major device number and a number of system
tables, ...The major number is actually the offset into the
kernel's device driver table, which tells the kernel what
kind of device it is (whether it is a hard disk or a serial
terminal) (..)"
-- Source:
www.linux-tutorial.info/modules.php?name=MContent&pageid=94.
Normally, when you create a Linux file system, you also create all of the
standard device nodes. But most of these do not map to real devices.
If you try to access most of the devices under ``/dev`` in Linux, they will
fail because the underlying driver that maps to that major/minor number
has not been initialized.
NuttX Device Nodes
==================
NuttX does not use major/minor device numbers and there are no device
"system tables" to associate major/minor numbers to a driver implementation.
NuttX simplifies this be removing the "man in the middle": When you register
the driver, you also create the device node.
.. important:: The device node IS the driver registry.
This is a tremendous simplification and one of the things that
makes NuttX usable in the constrained MCU environment.
In NuttX, device nodes are not really files at all.
They are special entries in the NuttX root pseudo-filesystem.
See :ref:`NuttX Pseudo File System <nuttx-pseudofs>` for more details.
Usage Differences
=================
.. important:: Only devices drivers can create device nodes and the existence
of the device node means that the device has been initialized,
registered, and is ready for use (with the exception of some
removable devices that may not actually be ready).
You cannot create device nodes from applications!
You could argue that this simplification is a deviation from my Unix/Linux
roadmap and would have to agree that you are right.
But it is also the kind of enabling simplification that makes a tiny
Unix-like operating system feasible on these lower end MCUs.
In Linux standard device drivers are initialized and registered as with NuttX.
A (privileged) application can create a device node, but cannot initialize
or register a device driver directly (as far as I know).
I believe that if you want to instantiate an uninitialized, unregistered
device driver you would have to install a kernel module containing
the driver (which would probably also create the device nodes corresponding
to the driver).
boardctl()
==========
NuttX does support a sneak interface to support interactions with board-level
OS logic. That sneak interface is ``boardctl()`` (see :ref:`board-ioctl` and
:ref:`nuttx-initialization-sequence` for more details).
That interface could potentially be used to force initialization of device
drivers by application code. That discussion is to be provided.