Source code for pyplugins.hyper.uboot
"""
U-Boot Plugin
=============
This module implements a plugin for the Penguin hypervisor environment that simulates U-Boot environment variable
management. It provides handlers for U-Boot hypercalls such as ``fw_setenv``, ``fw_getenv``, and ``fw_printenv``, allowing
the guest to set, get, and print U-Boot environment variables. All changes are logged to a file for auditing.
Usage
-----
The plugin is loaded by the Penguin framework and responds to U-Boot-related hypercalls.
Example Log Output
------------------
::
bootcmd=run boot_flash
baudrate=115200
ethaddr
Arguments
---------
- ``outdir``: Output directory for the U-Boot log file.
- ``conf``: Configuration dictionary, may contain ``uboot_env`` for initial environment.
- ``verbose``: If set, enables debug logging.
Classes
-------
- UBoot: Main plugin class for handling U-Boot environment variable operations.
"""
import os
from penguin import Plugin, plugins
UBOOT_LOG = "uboot.log"
[docs]
class UBoot(Plugin):
"""
UBoot is a plugin that simulates U-Boot environment variable management.
**Arguments:**
- `outdir` (str): Output directory for the U-Boot log file.
- `conf` (dict): Configuration dictionary, may contain `uboot_env` for initial environment.
- `verbose` (bool): Enables debug logging if True.
"""
def __init__(self) -> None:
"""
Initialize the UBoot plugin.
- Sets up the output directory and log file.
- Loads the initial U-Boot environment from configuration.
- Subscribes to U-Boot hypercalls.
**Returns:** None
"""
self.outdir = self.get_arg("outdir")
open(os.path.join(self.outdir, UBOOT_LOG), "w").close()
self.uboot_log = set()
if self.get_arg_bool("verbose"):
self.logger.setLevel("DEBUG")
# U-Boot
self.uboot_env = self.get_arg("conf").get("uboot_env", dict())
[docs]
@plugins.SendHypercall.subscribe("fw_setenv")
def cmd_fw_setenv(self, var: str, val: str) -> tuple[int, str]:
"""
Set a U-Boot environment variable and log the change.
**Parameters:**
- `var` (str): The environment variable name.
- `val` (str): The value to set.
**Returns:**
- `(int, str)`: Tuple containing status code (0 for success) and an empty string.
"""
if var not in self.uboot_log:
self.uboot_log.add(var)
with open(os.path.join(self.outdir, UBOOT_LOG), "a") as f:
f.write(f"{var}={val}\n")
self.uboot_env[var] = val
self.logger.debug(f"fw_setenv {var}={val}")
return 0, ""
[docs]
@plugins.SendHypercall.subscribe("fw_getenv")
def cmd_fw_getenv(self, var: str) -> tuple[int, str]:
"""
Get the value of a U-Boot environment variable.
**Parameters:**
- `var` (str): The environment variable name.
**Returns:**
- `(int, str)`: Tuple containing status code (0 for success, 1 if not found) and the value or empty string.
"""
try:
return 0, self.uboot_env[var]
except KeyError:
if var not in self.uboot_log:
self.uboot_log.add(var)
with open(os.path.join(self.outdir, UBOOT_LOG), "a") as f:
f.write(var + "\n")
self.logger.debug(f"fw_getenv {var}")
return 1, ""
[docs]
@plugins.SendHypercall.subscribe("fw_printenv")
def cmd_fw_printenv(self, arg: str) -> None:
"""
Print the U-Boot environment variables.
**Parameters:**
- `arg` (str): Argument for printenv (unused).
**Raises:** NotImplementedError
**Returns:** None
"""
raise NotImplementedError("fw_printenv shim unimplemented")