.. _barebox,state: Barebox state ============= A *state* variable set can be fully described as a devicetree based *state* node. This *state* node could be part of the regular platform's devicetree blob or it could be an extra devicetree solely for the *state*. Devicetree *state* Node ----------------------- A *state* node contains a description of a set of variables along with a place where the variable set gets stored. Required Properties ################### * ``compatible``: should be ``barebox,state`` * ``magic``: a 32bit number * ``backend``: phandle to persistent memory * ``backend-type``: defines the *state* variable set storage format * additionally a *state* node must have an alias in the ``/aliases`` node pointing to it. .. _barebox,state_magic: The ``magic`` property is a unique number which identifies the *state* variable set's variable types and their layout. It should be kept stable as long as the variable types and the layout are kept stable. It should also be kept stable if new trailing variables are added to the existing layout to be backward compatible. Only if the *state* variable set's variable types and/or their layout change, the ``magic`` property's number must be changed to be unique again with the new *state* variable set's content. .. important:: You should not use the values 0x2354fdf3 and 0x14fa2d02 for your magic value. They're already reserved by the ``direct`` and ``circular`` storage backends. The ``backend`` property uses the *phandle* mechanism to link the *state* to a real persistent memory. Refer :ref:`Backend ` for supported persistent memories. The ``backend-type`` should be ``raw`` or ``dtb``. Refer :ref:`Backend Types ` for further details. Optional Properties ################### * ``backend-stridesize``: stride counted in bytes. See note below. * ``backend-storage-type``: Defines the backend storage type to ``direct``, ``circular`` or ``noncircular``. If the backend memory needs to be erased prior a write it defaults to the ``circular`` storage backend type, for backend memories like RAMs or EEPROMs it defaults to the ``direct`` storage backend type. * ``algo``: An HMAC algorithm used to detect manipulation of the data or header, sensible values follow this pattern ``hmac()``, e.g. ``hmac(sha256)``. Only available for the ``backend-type`` ``raw``. * ``keep-previous-content``: Check if a the bucket meta magic field contains other data than the magic value. If so, the backend will not write the state to prevent unconditionally overwrites of existing data. .. note:: For the ``backend-storage-type`` the keyword ``noncircular`` is still supported as a fall back to an old storage format. Recommendation is to not use this type anymore. .. _barebox,state_backend_stridesize: The ``backend-stridesize`` is still optional but required whenever the underlying backend doesn't provide an information how to pad an instance of a *state* variable set. This is valid for all underlying backends which support writes on a byte-by-byte manner or don't have eraseblocks (EEPROM, SRAM and NOR type flash backends). The ``backend-stridesize`` value is used by the ``direct`` backend storage type to place the redundant *state* variable set copies side by side in the backend. And it's used by the ``circular`` backend storage type to place the *state* variable set copies side by side into the eraseblock. You should calculate the ``backend-stridesize`` value very carefully based on the used ``backend-type``, the size of the used backend (e.g. partition size for example) and its eraseblock size. Refer :ref:`Backend Types `. .. note:: It might be useful to add some spare space to the ``backend-stridesize`` to ensure the ability to extend the *state* variable set later on. .. _barebox,state_variable: Variable Subnodes ----------------- These are subnodes of a *state* node each describing a single variable. The node name may end with ``@
``, but the suffix is stripped from the variable name. State variables have a type. Currenty supported types are: ``uint8``, ``uint32``, ``enum32``, ``mac`` address or ``string`` (fixed length string). Variable length strings are not planned. Required Properties ################### * ``reg``: Standard ``reg`` property with ``#address-cells = <1>`` and ``#size-cells = <1>``. Defines the ``offset`` and ``size`` of the variable in the ``raw`` backend. ``size`` **must fit** the node ``type``. Variables are not allowed to overlap. * ``type``: Should be ``uint8``, ``uint32``, ``enum32``, ``mac`` or ``string`` for the type of the variable * ``names``: For ``enum32`` values only, this specifies the possible values for ``enum32``. Optional Properties ################### * ``default``: The default value if the variable's content cannot be read from the backend. For ``enum32`` values it is an integer representing an offset into the names array. .. note:: Since the ``default`` property is optional, keep in mind you may need a valid default value if other instances (like the bootchooser for example) depends on it. Due to this, a ``default`` might be a required property instead. Variable Examples ################# ``uint8``: .. code-block:: text uint8_example@0 { reg = <0x0 0x1>; type = "uint8"; default = <0x00>; }; ``uint32``: .. code-block:: text uint32_example@0 { reg = <0x0 0x4>; type = "uint32"; default = <100>; }; ``enum32``: .. code-block:: text enum_example@0 { reg = <0x0 0x4>; type = "enum32"; names = "value#1", "value#2"; default = <1>; /* selects "value#2" as the default */ }; ``mac``: .. code-block:: text mac_example@0 { reg = <0x0 0x6>; type = "mac"; }; Since a 'MAC' is a unique system identifier it makes no sense for a default value here. It must be set individually at run-time instead. ``string``: .. code-block:: text name { reg = <0x0 0x10>; type = "string"; }; In this example the length of the string is limited to 16 characters. .. _barebox,state_hmac: HMAC ---- With the optional property ``algo = "hmac()";`` an HMAC algorithm can be defined to detect unauthorized modification of the state's variable set header and/or data. For this to work the HMAC and the selected hash algorithm have to be compiled into barebox. The shared secret for the HMAC is requested via ``keystore_get_secret()``, using the state's name, from the barebox simple keystore. It's up to the developer to populate the keystore via ``keystore_set_secret()`` in beforehand. Refer :ref:`command_keystore` for further details. .. _barebox,state_setup: Configuring the *state* variable set ------------------------------------ Since the *state* variable set is intended to be shared between the bootloader and the kernel, the view to the *state* variable set must be the same in both worlds. This can be achieved by defining all *state* variable set related definitions inside the barebox's devicetree only. It's **not** required to keep and maintain the same information inside the Linux kernel's devicetree again. When barebox is instructed to load and forward a devicetree to a Linux kernel to be started, it "silently" copies all *state* variable set related definitions from its own devicetree into the Linux kernel devicetree. This way both worlds behave the same when *state* variable sets should be read or modified. In order to enable barebox to copy the required information to a dedicated location inside the Linux kernel devicetree the name of the memory node to store the *state* variable set must be the same in the barebox's devicetree and the operating system's devicetree. With this "interconnection" barebox extends the operating system's devicetree with: - the layout and variable definition of the *state* variable set (in case of the ``raw`` backend-type) - the store definition (backend type, backend storage type and so on) - partitioning information for the persistent memory in question (on demand) - the connection between the backend and the memory (device, partition) Example: Lets assume the barebox's devicetree uses the name ``persistent_state_memory@01`` to define its own *state* variable set backend. Barebox's devicetree defines: .. code-block:: text persistent_state_memory@01 { compatible = "somevalue"; reg = <1>; #address-cells = <1>; #size-cells = <1>; state: partition@0 { label = "state"; reg = <0x0 0x100>; }; }; The operating system's devicetree defines instead: .. code-block:: text persistent_state_memory@01 { compatible = "somevalue"; reg = <1>; };