Pull request for efi-2022-04-rc5-2

Documentation:

* man-page for the wdt command

UEFI:

* Unit test for boot manager
This commit is contained in:
Tom Rini
2022-03-27 09:22:19 -04:00
7 changed files with 233 additions and 17 deletions
+2 -3
View File
@@ -810,7 +810,7 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
efi_guid_t guid;
size_t label_len, label_len16;
u16 *label;
struct efi_device_path *device_path = NULL, *file_path = NULL;
struct efi_device_path *file_path = NULL;
struct efi_device_path *fp_free = NULL;
struct efi_device_path *final_fp = NULL;
struct efi_device_path *initrd_dp = NULL;
@@ -865,7 +865,7 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
/* file path */
ret = efi_dp_from_name(argv[3], argv[4], argv[5],
&device_path, &fp_free);
NULL, &fp_free);
if (ret != EFI_SUCCESS) {
printf("Cannot create device path for \"%s %s\"\n",
argv[3], argv[4]);
@@ -953,7 +953,6 @@ out:
free(data);
efi_free_pool(final_fp);
efi_free_pool(initrd_dp);
efi_free_pool(device_path);
efi_free_pool(fp_free);
free(lo.label);
+1
View File
@@ -52,3 +52,4 @@ Shell commands
size
true
ums
wdt
+77
View File
@@ -0,0 +1,77 @@
.. SPDX-License-Identifier: GPL-2.0+:
wdt command
============
Synopsis
--------
::
wdt list
wdt dev [<name>]
wdt start <timeout_ms> [flags]
wdt stop
wdt reset
wdt expirer [flags]
Description
-----------
The wdt command is used to control watchdog timers.
The 'wdt list' command shows a list of all watchdog devices.
The 'wdt dev' command called without argument shows the current watchdog device.
The current device is set when passing the name of the device as argument.
The 'wdt start' command starts the current watchdog timer.
The 'wdt stop' command stops the current watchdog timer.
The 'wdt reset' command resets the current watchdog timer without stopping it.
The 'wdt expire' command let's the current watchdog timer expire immediately.
This will lead to a reset.
name
name of the watchdog device
timeout_ms
timeout interval in milliseconds
flags
unsigned long value passed to the driver. The usage is driver specific.
The value is ignored by most drivers.
Example
-------
::
=> wdt dev
No watchdog timer device set!
=> wdt list
watchdog@1c20ca0 (sunxi_wdt)
=> wdt dev watchdog@1c20ca0
=> wdt dev
dev: watchdog@1c20ca0
=> wdt start 3000
=> wdt reset
=> wdt stop
=> wdt expire
U-Boot SPL 2022.04-rc3 (Mar 25 2022 - 13:48:33 +0000)
In the example above '(sunxi_wdt)' refers to the driver for the watchdog
device.
Configuration
-------------
The command is only available if CONFIG_CMD_WDT=y.
Return value
------------
The return value $? is 0 if the command succeeds, 1 upon failure.
+1 -1
View File
@@ -137,7 +137,7 @@ int efi_dp_match(const struct efi_device_path *a,
*
* See UEFI spec (section 3.1.2, about short-form device-paths)
*
* @dp: original devie-path
* @dp: original device-path
* @Return: shortened device-path or NULL
*/
struct efi_device_path *efi_dp_shorten(struct efi_device_path *dp)
+78 -13
View File
@@ -4,6 +4,9 @@
*
* initrddump.efi saves the initial RAM disk provided via the
* EFI_LOAD_FILE2_PROTOCOL.
*
* Specifying 'nocolor' as load option data suppresses colored output and
* clearing of the screen.
*/
#include <common.h>
@@ -25,6 +28,7 @@ static const efi_guid_t guid_simple_file_system_protocol =
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
static const efi_guid_t load_file2_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
static efi_handle_t handle;
static bool nocolor;
/*
* Device path defined by Linux to identify the handle providing the
@@ -46,6 +50,17 @@ static const struct efi_initrd_dp initrd_dp = {
}
};
/**
* color() - set foreground color
*
* @color: foreground color
*/
static void color(u8 color)
{
if (!nocolor)
cout->set_attribute(cout, color | EFI_BACKGROUND_BLACK);
}
/**
* print() - print string
*
@@ -56,6 +71,17 @@ static void print(u16 *string)
cout->output_string(cout, string);
}
/**
* cls() - clear screen
*/
static void cls(void)
{
if (nocolor)
print(u"\r\n");
else
cout->clear_screen(cout);
}
/**
* error() - print error string
*
@@ -63,9 +89,9 @@ static void print(u16 *string)
*/
static void error(u16 *string)
{
cout->set_attribute(cout, EFI_LIGHTRED | EFI_BACKGROUND_BLACK);
color(EFI_LIGHTRED);
print(string);
cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);
color(EFI_LIGHTBLUE);
}
/*
@@ -94,6 +120,14 @@ static void printx(u64 val, u32 prec)
print(buf);
}
/**
* efi_drain_input() - drain console input
*/
static void efi_drain_input(void)
{
cin->reset(cin, true);
}
/**
* efi_input_yn() - get answer to yes/no question
*
@@ -111,8 +145,6 @@ static efi_status_t efi_input_yn(void)
efi_uintn_t index;
efi_status_t ret;
/* Drain the console input */
ret = cin->reset(cin, true);
for (;;) {
ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
if (ret != EFI_SUCCESS)
@@ -153,8 +185,6 @@ static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size)
u16 outbuf[2] = u" ";
efi_status_t ret;
/* Drain the console input */
ret = cin->reset(cin, true);
*buffer = 0;
for (;;) {
ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
@@ -215,10 +245,13 @@ static u16 *skip_whitespace(u16 *pos)
*
* @string: string to search for keyword
* @keyword: keyword to be searched
* Return: true fi @string starts with the keyword
* Return: true if @string starts with the keyword
*/
static bool starts_with(u16 *string, u16 *keyword)
{
if (!string || !keyword)
return false;
for (; *keyword; ++string, ++keyword) {
if (*string != *keyword)
return false;
@@ -364,6 +397,7 @@ static efi_status_t do_save(u16 *filename)
ret = root->open(root, &file, filename, EFI_FILE_MODE_READ, 0);
if (ret == EFI_SUCCESS) {
file->close(file);
efi_drain_input();
print(u"Overwrite existing file (y/n)? ");
ret = efi_input_yn();
print(u"\r\n");
@@ -400,6 +434,30 @@ out:
return ret;
}
/**
* get_load_options() - get load options
*
* Return: load options or NULL
*/
u16 *get_load_options(void)
{
efi_status_t ret;
struct efi_loaded_image *loaded_image;
ret = bs->open_protocol(handle, &loaded_image_guid,
(void **)&loaded_image, NULL, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (ret != EFI_SUCCESS) {
error(u"Loaded image protocol not found\r\n");
return NULL;
}
if (!loaded_image->load_options_size || !loaded_image->load_options)
return NULL;
return loaded_image->load_options;
}
/**
* efi_main() - entry point of the EFI application.
*
@@ -410,24 +468,30 @@ out:
efi_status_t EFIAPI efi_main(efi_handle_t image_handle,
struct efi_system_table *systab)
{
u16 *load_options;
handle = image_handle;
systable = systab;
cerr = systable->std_err;
cout = systable->con_out;
cin = systable->con_in;
bs = systable->boottime;
load_options = get_load_options();
cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);
cout->clear_screen(cout);
cout->set_attribute(cout, EFI_WHITE | EFI_BACKGROUND_BLACK);
if (starts_with(load_options, u"nocolor"))
nocolor = true;
color(EFI_WHITE);
cls();
print(u"INITRD Dump\r\n===========\r\n\r\n");
cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);
color(EFI_LIGHTBLUE);
for (;;) {
u16 command[BUFFER_SIZE];
u16 *pos;
efi_uintn_t ret;
efi_drain_input();
print(u"=> ");
ret = efi_input(command, sizeof(command));
if (ret == EFI_ABORTED)
@@ -443,7 +507,8 @@ efi_status_t EFIAPI efi_main(efi_handle_t image_handle,
do_help();
}
cout->set_attribute(cout, EFI_LIGHTGRAY | EFI_BACKGROUND_BLACK);
cout->clear_screen(cout);
color(EFI_LIGHTGRAY);
cls();
return EFI_SUCCESS;
}
@@ -0,0 +1,42 @@
# SPDX-License-Identifier: GPL-2.0+
"""Fixture for UEFI bootmanager test
"""
import os
import pytest
import shutil
from subprocess import call, check_call
@pytest.fixture(scope='session')
def efi_bootmgr_data(u_boot_config):
"""Set up a file system to be used in UEFI bootmanager
tests
Args:
u_boot_config: U-boot configuration.
Return:
A path to disk image to be used for testing
"""
mnt_point = u_boot_config.persistent_data_dir + '/test_efi_bootmgr'
image_path = u_boot_config.persistent_data_dir + '/efi_bootmgr.img'
shutil.rmtree(mnt_point, ignore_errors=True)
os.mkdir(mnt_point, mode = 0o755)
with open(mnt_point + '/initrd-1.img', 'w', encoding = 'ascii') as file:
file.write("initrd 1")
with open(mnt_point + '/initrd-2.img', 'w', encoding = 'ascii') as file:
file.write("initrd 2")
shutil.copyfile(u_boot_config.build_dir + '/lib/efi_loader/initrddump.efi',
mnt_point + '/initrddump.efi')
check_call('virt-make-fs --partition=gpt --size=+1M --type=vfat {} {}'
.format(mnt_point, image_path), shell=True)
print(image_path)
yield image_path
@@ -0,0 +1,32 @@
# SPDX-License-Identifier: GPL-2.0+
import pytest
@pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('cmd_efidebug')
@pytest.mark.buildconfigspec('cmd_bootefi_bootmgr')
def test_efi_bootmgr(u_boot_console, efi_bootmgr_data):
u_boot_console.run_command(cmd = 'host bind 0 {}'.format(efi_bootmgr_data))
u_boot_console.run_command(cmd = 'efidebug boot add ' \
'-b 0001 label-1 host 0:1 initrddump.efi ' \
'-i host 0:1 initrd-1.img -s nocolor')
u_boot_console.run_command(cmd = 'efidebug boot dump')
u_boot_console.run_command(cmd = 'efidebug boot order 0001')
u_boot_console.run_command(cmd = 'bootefi bootmgr')
response = u_boot_console.run_command(cmd = 'load', wait_for_echo=False)
assert 'crc32: 0x181464af' in response
u_boot_console.run_command(cmd = 'exit', wait_for_echo=False)
u_boot_console.run_command(cmd = 'efidebug boot add ' \
'-B 0002 label-2 host 0:1 initrddump.efi ' \
'-I host 0:1 initrd-2.img -s nocolor')
u_boot_console.run_command(cmd = 'efidebug boot dump')
u_boot_console.run_command(cmd = 'efidebug boot order 0002')
u_boot_console.run_command(cmd = 'bootefi bootmgr')
response = u_boot_console.run_command(cmd = 'load', wait_for_echo=False)
assert 'crc32: 0x811d3515' in response
u_boot_console.run_command(cmd = 'exit', wait_for_echo=False)
u_boot_console.run_command(cmd = 'efidebug boot rm 0001')
u_boot_console.run_command(cmd = 'efidebug boot rm 0002')