From 532952f63cfa708a04aba837f68ffe321489cdef Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 31 Dec 2022 00:49:10 +0100 Subject: [PATCH 1/9] cmd: avoid endless loop in sound play command A parameter starting with a hyphen leads to an endless loop in the sound play command. Leave it to dectoul() to handle the hyphen. It will return 0 for a negative number. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- cmd/sound.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/sound.c b/cmd/sound.c index cef71be5e3..0b7f959971 100644 --- a/cmd/sound.c +++ b/cmd/sound.c @@ -48,12 +48,12 @@ static int do_play(struct cmd_tbl *cmdtp, int flag, int argc, ++argv; while (argc || first) { first = false; - if (argc && *argv[0] != '-') { + if (argc) { msec = dectoul(argv[0], NULL); --argc; ++argv; } - if (argc && *argv[0] != '-') { + if (argc) { freq = dectoul(argv[0], NULL); --argc; ++argv; From 566b7b2f518797540413bf55862b6562158aced9 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 30 Dec 2022 05:05:31 +0100 Subject: [PATCH 2/9] doc: building documentation Provide a man-page describing how to build the U-Boot documentation. Signed-off-by: Heinrich Schuchardt --- doc/build/documentation.rst | 90 +++++++++++++++++++++++++++++++++++++ doc/build/index.rst | 1 + 2 files changed, 91 insertions(+) create mode 100644 doc/build/documentation.rst diff --git a/doc/build/documentation.rst b/doc/build/documentation.rst new file mode 100644 index 0000000000..896264dd7c --- /dev/null +++ b/doc/build/documentation.rst @@ -0,0 +1,90 @@ +.. SPDX-License-Identifier: GPL-2.0+: + +Building documentation +====================== + +The U-Boot documentation is based on the Sphinx documentation generator. + +HTML documentation +------------------ + +The *htmldocs* target is used to build the HTML documentation. It uses the +`Read the Docs Sphinx theme `_. + +.. code-block:: bash + + # Create Python environment 'myenv' + python3 -m venv myenv + # Activate the Python environment + . myenv/bin/activate + # Install build requirements + python3 -m pip install -r doc/sphinx/requirements.txt + # Build the documentation + make htmldocs + # Deactivate the Python environment + deactivate + # Display the documentation in a graphical web browser + x-www-browser doc/output/index.html + +Infodoc documentation +--------------------- + +The *infodocs* target builds both a texinfo and an info file: + +.. code-block:: bash + + # Create Python environment 'myenv' + python3 -m venv myenv + # Activate the Python environment + . myenv/bin/activate + # Install build requirements + python3 -m pip install -r doc/sphinx/requirements.txt + # Build the documentation + make infodocs + # Deactivate the Python environment + deactivate + # Display the documentation + info doc/output/texinfo/u-boot.info + +PDF documentation +----------------- + +The *pdfdocs* target is meant to be used to build PDF documenation. +As v2023.01 it fails with 'LaTeX Error: Too deeply nested'. + +We can use texi2pdf instead: + +.. code-block:: bash + + # Create Python environment 'myenv' + python3 -m venv myenv + # Activate the Python environment + . myenv/bin/activate + # Install build requirements + python3 -m pip install -r doc/sphinx/requirements.txt + # Build the documentation + make texinfodocs + # Deactivate the Python environment + deactivate + # Convert to PDF + texi2pdf doc/output/texinfo/u-boot.texi + +Texinfo documentation +--------------------- + +To build only the texinfo documentation the *texinfodocs* target is used: + +.. code-block:: bash + + # Create Python environment 'myenv' + python3 -m venv myenv + # Activate the Python environment + . myenv/bin/activate + # Install build requirements + python3 -m pip install -r doc/sphinx/requirements.txt + # Build the documentation + make texinfodocs + # Deactivate the Python environment + deactivate + +The output is in file *doc/output/texinfo/u-boot.texi*. diff --git a/doc/build/index.rst b/doc/build/index.rst index 9a8105db21..dc9cde4001 100644 --- a/doc/build/index.rst +++ b/doc/build/index.rst @@ -12,3 +12,4 @@ Build U-Boot docker tools buildman + documentation From fbc595b4124de3d51cb00fe541b93a3d979a58ec Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 18 Dec 2022 08:05:02 +0100 Subject: [PATCH 3/9] doc: Fix eth_env_[gs]et_enetaddr() return value Per env/common.c, eth_env_get_enetaddr() returns the same return values as is_valid_ethaddr(), i.e. true if valid, false otherwise. Per env/common.c, eth_env_set_enetaddr() may return -EEXIST is the ethaddr is already set. Fix both. Signed-off-by: Marek Vasut Reviewed-by: Heinrich Schuchardt --- include/env.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/env.h b/include/env.h index 60acb5454e..1480efa59e 100644 --- a/include/env.h +++ b/include/env.h @@ -226,7 +226,7 @@ int env_complete(char *var, int maxv, char *cmdv[], int maxsz, char *buf, * * @name: Environment variable to get (e.g. "ethaddr") * @enetaddr: Place to put MAC address (6 bytes) - * Return: 0 if OK, 1 on error + * Return: 1 if OK, 0 on error */ int eth_env_get_enetaddr(const char *name, uint8_t *enetaddr); @@ -235,7 +235,7 @@ int eth_env_get_enetaddr(const char *name, uint8_t *enetaddr); * * @name: Environment variable to set (e.g. "ethaddr") * @enetaddr: Pointer to MAC address to put into the variable (6 bytes) - * Return: 0 if OK, 1 on error + * Return: 0 if OK, non-zero otherwise */ int eth_env_set_enetaddr(const char *name, const uint8_t *enetaddr); From 673a92c5d2c2b6dbcc5b530b0b1215db7afb8188 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 4 Jan 2023 12:18:54 +0100 Subject: [PATCH 4/9] efi_loader: defines for PE-COFF section flags Provide constants for the section flags used by binaries. Signed-off-by: Heinrich Schuchardt Reviewed-by: Ilias Apalodimas --- include/asm-generic/pe.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/asm-generic/pe.h b/include/asm-generic/pe.h index a1df747134..b9d674b6da 100644 --- a/include/asm-generic/pe.h +++ b/include/asm-generic/pe.h @@ -51,6 +51,19 @@ #define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 #define IMAGE_SUBSYSTEM_EFI_ROM 13 +/* Section flags */ +#define IMAGE_SCN_CNT_CODE 0x00000020 +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 +#define IMAGE_SCN_CNT_UNINITIALIZED_ DATA 0x00000080 +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 +#define IMAGE_SCN_MEM_SHARED 0x10000000 +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 +#define IMAGE_SCN_MEM_READ 0x40000000 +#define IMAGE_SCN_MEM_WRITE 0x80000000 + #define LINUX_ARM64_MAGIC 0x644d5241 #endif /* _ASM_PE_H */ From d7ddeb66a6ce55672ba89496c621fbfc9465b4c2 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 31 Dec 2022 11:58:54 +0100 Subject: [PATCH 5/9] efi_loader: fix building aarch64 EFI binaries While our EFI binaries execute without problems on EDK II they crash on a Lenovo X13s. Let our binaries look more like what EDK II produces: * move all writable data to a .data section * align sections to 4 KiB boundaries (matching EFI page size) * remove IMAGE_SCN_LNK_NRELOC_OVFL from .reloc section flags Signed-off-by: Heinrich Schuchardt Reviewed-by: Ilias Apalodimas --- arch/arm/lib/crt0_aarch64_efi.S | 47 +++++++++++++++++++++++--------- arch/arm/lib/elf_aarch64_efi.lds | 6 ++-- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/arch/arm/lib/crt0_aarch64_efi.S b/arch/arm/lib/crt0_aarch64_efi.S index b4fc263adf..3c2cef6ec7 100644 --- a/arch/arm/lib/crt0_aarch64_efi.S +++ b/arch/arm/lib/crt0_aarch64_efi.S @@ -25,7 +25,7 @@ pe_header: .long IMAGE_NT_SIGNATURE /* 'PE' */ coff_header: .short IMAGE_FILE_MACHINE_ARM64 /* AArch64 */ - .short 2 /* nr_sections */ + .short 3 /* nr_sections */ .long 0 /* TimeDateStamp */ .long 0 /* PointerToSymbolTable */ .long 0 /* NumberOfSymbols */ @@ -40,7 +40,7 @@ optional_header: .short IMAGE_NT_OPTIONAL_HDR64_MAGIC /* PE32+ format */ .byte 0x02 /* MajorLinkerVersion */ .byte 0x14 /* MinorLinkerVersion */ - .long _edata - _start /* SizeOfCode */ + .long _etext - _start /* SizeOfCode */ .long 0 /* SizeOfInitializedData */ .long 0 /* SizeOfUninitializedData */ .long _start - ImageBase /* AddressOfEntryPoint */ @@ -48,7 +48,7 @@ optional_header: extra_header_fields: .quad 0 /* ImageBase */ - .long 0x200 /* SectionAlignment */ + .long 0x1000 /* SectionAlignment */ .long 0x200 /* FileAlignment */ .short 0 /* MajorOperatingSystemVersion */ .short 0 /* MinorOperatingSystemVersion */ @@ -100,25 +100,46 @@ section_table: .long 0 /* PointerToLineNumbers */ .short 0 /* NumberOfRelocations */ .short 0 /* NumberOfLineNumbers */ - .long 0x42100040 /* Characteristics (section flags) */ - + /* Characteristics (section flags) */ + .long (IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_DISCARDABLE | \ + IMAGE_SCN_CNT_INITIALIZED_DATA) .ascii ".text" .byte 0 .byte 0 .byte 0 /* end of 0 padding of section name */ - .long _edata - _start /* VirtualSize */ + .long _etext - _start /* VirtualSize */ .long _start - ImageBase /* VirtualAddress */ - .long _edata - _start /* SizeOfRawData */ + .long _etext - _start /* SizeOfRawData */ .long _start - ImageBase /* PointerToRawData */ + .long 0 /* PointerToRelocations */ + .long 0 /* PointerToLineNumbers */ + .short 0 /* NumberOfRelocations */ + .short 0 /* NumberOfLineNumbers */ + /* Characteristics (section flags) */ + .long (IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_EXECUTE | \ + IMAGE_SCN_CNT_CODE) - .long 0 /* PointerToRelocations (0 for executables) */ - .long 0 /* PointerToLineNumbers (0 for executables) */ - .short 0 /* NumberOfRelocations (0 for executables) */ - .short 0 /* NumberOfLineNumbers (0 for executables) */ - .long 0xe0500020 /* Characteristics (section flags) */ + .ascii ".data" + .byte 0 + .byte 0 + .byte 0 /* end of 0 padding of section name */ + .long _data_size /* VirtualSize */ + .long _data - ImageBase /* VirtualAddress */ + .long _data_size /* SizeOfRawData */ + .long _data - ImageBase /* PointerToRawData */ + .long 0 /* PointerToRelocations */ + .long 0 /* PointerToLineNumbers */ + .short 0 /* NumberOfRelocations */ + .short 0 /* NumberOfLineNumbers */ + /* Characteristics (section flags) */ + .long (IMAGE_SCN_MEM_WRITE | \ + IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_CNT_INITIALIZED_DATA) - .align 9 + .align 12 _start: stp x29, x30, [sp, #-32]! mov x29, sp diff --git a/arch/arm/lib/elf_aarch64_efi.lds b/arch/arm/lib/elf_aarch64_efi.lds index c0604dad46..ffc6f6e604 100644 --- a/arch/arm/lib/elf_aarch64_efi.lds +++ b/arch/arm/lib/elf_aarch64_efi.lds @@ -18,11 +18,13 @@ SECTIONS *(.gnu.linkonce.t.*) *(.srodata) *(.rodata*) + . = ALIGN(16); + *(.dynamic); . = ALIGN(512); } _etext = .; _text_size = . - _text; - .dynamic : { *(.dynamic) } + . = ALIGN(4096); .data : { _data = .; *(.sdata) @@ -48,11 +50,11 @@ SECTIONS _bss_end = .; _edata = .; } + _data_size = _edata - _data; .rela.dyn : { *(.rela.dyn) } .rela.plt : { *(.rela.plt) } .rela.got : { *(.rela.got) } .rela.data : { *(.rela.data) *(.rela.data*) } - _data_size = . - _etext; . = ALIGN(4096); .dynsym : { *(.dynsym) } From 7a9b366cd9b7c1c880fda82509054a06fbac208c Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 29 Dec 2022 14:44:03 +0100 Subject: [PATCH 6/9] lib: add function u16_strcasecmp() Provide a function for comparing UTF-16 strings in a case insensitive manner. Signed-off-by: Heinrich Schuchardt --- include/charset.h | 13 +++++++++++++ lib/charset.c | 26 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/include/charset.h b/include/charset.h index e900fd789a..6e79d7152e 100644 --- a/include/charset.h +++ b/include/charset.h @@ -173,6 +173,19 @@ s32 utf_to_lower(const s32 code); */ s32 utf_to_upper(const s32 code); +/** + * u16_strcasecmp() - compare two u16 strings case insensitively + * + * @s1: first string to compare + * @s2: second string to compare + * @n: maximum number of u16 to compare + * Return: 0 if the first n u16 are the same in s1 and s2 + * < 0 if the first different u16 in s1 is less than the + * corresponding u16 in s2 + * > 0 if the first different u16 in s1 is greater than the + */ +int u16_strcasecmp(const u16 *s1, const u16 *s2); + /** * u16_strncmp() - compare two u16 string * diff --git a/lib/charset.c b/lib/charset.c index bece4985bf..b1842755eb 100644 --- a/lib/charset.c +++ b/lib/charset.c @@ -350,6 +350,32 @@ s32 utf_to_upper(const s32 code) return ret; } +/* + * u16_strcasecmp() - compare two u16 strings case insensitively + * + * @s1: first string to compare + * @s2: second string to compare + * @n: maximum number of u16 to compare + * Return: 0 if the first n u16 are the same in s1 and s2 + * < 0 if the first different u16 in s1 is less than the + * corresponding u16 in s2 + * > 0 if the first different u16 in s1 is greater than the + */ +int u16_strcasecmp(const u16 *s1, const u16 *s2) +{ + int ret = 0; + s32 c1, c2; + + for (;;) { + c1 = utf_to_upper(utf16_get(&s1)); + c2 = utf_to_upper(utf16_get(&s2)); + ret = c1 - c2; + if (ret || !c1 || c1 == -1 || c2 == -1) + break; + } + return ret; +} + /* * u16_strncmp() - compare two u16 string * From 07355760b1759cc4c8cee402a67f7089b6a06da9 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 29 Dec 2022 14:44:04 +0100 Subject: [PATCH 7/9] test: unit test for u16_strcasecmp() Provide a unit test for u16_strcasecmp(). Signed-off-by: Heinrich Schuchardt --- test/unicode_ut.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/unicode_ut.c b/test/unicode_ut.c index 3547aeffe7..382b796516 100644 --- a/test/unicode_ut.c +++ b/test/unicode_ut.c @@ -624,6 +624,31 @@ static int unicode_test_utf_to_upper(struct unit_test_state *uts) } UNICODE_TEST(unicode_test_utf_to_upper); +static int unicode_test_u16_strcasecmp(struct unit_test_state *uts) +{ + ut_assert(u16_strcasecmp(u"abcd", u"abcd") == 0); + ut_assert(u16_strcasecmp(u"aBcd", u"abcd") == 0); + ut_assert(u16_strcasecmp(u"abcd", u"abCd") == 0); + ut_assert(u16_strcasecmp(u"abcdE", u"abcd") > 0); + ut_assert(u16_strcasecmp(u"abcd", u"abcdE") < 0); + ut_assert(u16_strcasecmp(u"abcE", u"abcd") > 0); + ut_assert(u16_strcasecmp(u"abcd", u"abcE") < 0); + ut_assert(u16_strcasecmp(u"abcd", u"abcd") == 0); + ut_assert(u16_strcasecmp(u"abcd", u"abcd") == 0); + if (CONFIG_IS_ENABLED(EFI_UNICODE_CAPITALIZATION)) { + /* Cyrillic letters */ + ut_assert(u16_strcasecmp(u"\x043a\x043d\x0438\x0433\x0430", + u"\x041a\x041d\x0418\x0413\x0410") == 0); + ut_assert(u16_strcasecmp(u"\x043a\x043d\x0438\x0433\x0430", + u"\x041a\x041d\x0418\x0413\x0411") < 0); + ut_assert(u16_strcasecmp(u"\x043a\x043d\x0438\x0433\x0431", + u"\x041a\x041d\x0418\x0413\x0410") > 0); + } + + return 0; +} +UNICODE_TEST(unicode_test_u16_strcasecmp); + static int unicode_test_u16_strncmp(struct unit_test_state *uts) { ut_assert(u16_strncmp(u"abc", u"abc", 3) == 0); From 93cdb952382b3fa0110245e1fa34dadd7a52df45 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 29 Dec 2022 14:44:05 +0100 Subject: [PATCH 8/9] efi_loader: adjust sorting of capsules Up to now we only compared the first letter of the capsule name to sort them alphabetically. Properly sort by the Unicode alphabet. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_capsule.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index 1163a2ee30..0997cd248f 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -1108,10 +1108,13 @@ static efi_status_t efi_capsule_scan_dir(u16 ***files, unsigned int *num) /* ignore an error */ EFI_CALL((*dirh->close)(dirh)); - /* in ascii order */ - /* FIXME: u16 version of strcasecmp */ + /* + * Capsule files are applied in case insensitive alphabetic order + * + * TODO: special handling of rightmost period + */ qsort(tmp_files, count, sizeof(*tmp_files), - (int (*)(const void *, const void *))strcasecmp); + (int (*)(const void *, const void *))u16_strcasecmp); *files = tmp_files; *num = count; ret = EFI_SUCCESS; From 60bba6e2052c281afe401247e10aebcb4c17049b Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 4 Jan 2023 05:56:09 +0100 Subject: [PATCH 9/9] efi_loader: populate console handles in system table The fields ConsoleInHandle, ConsoleOutHandle, ConsoleErrHandle must point to the handles with the respective console protocols. Failure to do so leads to an error in the EFI Shell: No SimpleTextInputEx was found. CTRL-based features are not usable. Signed-off-by: Heinrich Schuchardt Reviewed-by: Ilias Apalodimas --- lib/efi_loader/efi_boottime.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 253f9f75ef..e65ca6a4cb 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -3956,8 +3956,11 @@ efi_status_t efi_initialize_system_table(void) * These entries will be set to NULL in ExitBootServices(). To avoid * relocation in SetVirtualAddressMap(), set them dynamically. */ + systab.con_in_handle = efi_root; systab.con_in = &efi_con_in; + systab.con_out_handle = efi_root; systab.con_out = &efi_con_out; + systab.stderr_handle = efi_root; systab.std_err = &efi_con_out; systab.boottime = &efi_boot_services;