summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--doc/develop/bootstd/android.rst39
-rw-r--r--doc/develop/bootstd/index.rst1
-rw-r--r--doc/develop/bootstd/overview.rst2
-rw-r--r--drivers/core/util.c14
-rw-r--r--include/dm/util.h8
-rw-r--r--include/linux/list.h15
-rw-r--r--include/smbios.h1
-rw-r--r--lib/efi_loader/Kconfig2
-rw-r--r--lib/efi_loader/efi_fdt.c3
-rw-r--r--lib/efi_loader/efi_helper.c2
-rw-r--r--lib/efi_loader/efi_memory.c33
-rw-r--r--lib/smbios.c9
-rw-r--r--test/dm/bus.c5
-rw-r--r--test/dm/core.c9
-rw-r--r--test/dm/test-fdt.c5
16 files changed, 97 insertions, 52 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index a6e47e8a217..c2832345ab1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -945,6 +945,7 @@ S: Maintained
T: git https://source.denx.de/u-boot/custodians/u-boot-dfu.git
F: boot/bootmeth_android.c
F: boot/bootmeth_android.h
+F: doc/develop/bootstd/android.rst
BTRFS
M: Marek BehĂșn <kabel@kernel.org>
diff --git a/doc/develop/bootstd/android.rst b/doc/develop/bootstd/android.rst
new file mode 100644
index 00000000000..41701d5bdff
--- /dev/null
+++ b/doc/develop/bootstd/android.rst
@@ -0,0 +1,39 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+Android Bootmeth
+================
+
+Android provides a mechanism for booting its Operating System from eMMC storage,
+described on `source.android.com <https://source.android.com/docs/core/architecture/bootloader>`_.
+
+Android has strong requirements about partitioning layout which are described
+`here <https://source.android.com/docs/core/architecture/partitions>`_.
+Because multiple partitions are required, this bootmeth only operates on whole mmc
+devices which have a valid partition table.
+
+When invoked on a bootdev, this bootmeth searches for the ``misc`` partition in order
+to read the *boot mode*, which can be one of following:
+
+Normal
+ Boot the regular Android Operating System.
+
+Recovery
+ Boot a slimmed down Recovery Operating System. Can be used
+ to factory reset the device or to apply system updates.
+
+Bootloader
+ Stay in U-Boot and wait for fastboot commands from the host.
+
+After the *boot mode* has been determined, this bootmeth will read the *slot suffix*
+from the ``misc`` partition. For details about slots, see
+`the AOSP documentation <https://source.android.com/docs/core/ota/ab#slots>`_.
+
+When both the *boot mode* and the *slot suffix* are known, the bootflow is created.
+
+When the bootflow is booted, the bootmeth reads the kernel, the boot arguments and
+the vendor ramdisk.
+It then boots the kernel using bootm. The relevant devicetree blob is extracted
+from the ``boot`` partition based on the ``adtb_idx`` environment variable.
+
+The compatible string "u-boot,android" is used for the driver. It is present
+if `CONFIG_BOOTMETH_ANDROID` is enabled.
diff --git a/doc/develop/bootstd/index.rst b/doc/develop/bootstd/index.rst
index 9d35b567d55..4c4e26ccdb7 100644
--- a/doc/develop/bootstd/index.rst
+++ b/doc/develop/bootstd/index.rst
@@ -10,6 +10,7 @@ Standard Boot
extlinux
pxelinux
qfw
+ android
cros
script
sandbox
diff --git a/doc/develop/bootstd/overview.rst b/doc/develop/bootstd/overview.rst
index ff3cc48eb64..c6f003851b2 100644
--- a/doc/develop/bootstd/overview.rst
+++ b/doc/develop/bootstd/overview.rst
@@ -429,7 +429,7 @@ Available bootmeth drivers
Bootmeth drivers are provided for booting from various media:
- - Android bootflow (boot image v4)
+ - :doc:`Android <android>` bootflow (boot image v4)
- :doc:`ChromiumOS <cros>` ChromiumOS boot from a disk
- EFI boot using bootefi from disk
- EFI boot using boot manager
diff --git a/drivers/core/util.c b/drivers/core/util.c
index 108a3bc4dac..fa893485a09 100644
--- a/drivers/core/util.c
+++ b/drivers/core/util.c
@@ -3,23 +3,13 @@
* Copyright (c) 2013 Google, Inc
*/
+#include <vsprintf.h>
#include <dm/device.h>
#include <dm/ofnode.h>
#include <dm/read.h>
#include <dm/util.h>
#include <linux/libfdt.h>
-#include <vsprintf.h>
-
-int list_count_items(struct list_head *head)
-{
- struct list_head *node;
- int count = 0;
-
- list_for_each(node, head)
- count++;
-
- return count;
-}
+#include <linux/list.h>
#if CONFIG_IS_ENABLED(OF_REAL)
int pci_get_devfn(struct udevice *dev)
diff --git a/include/dm/util.h b/include/dm/util.h
index 95c3527a37c..ec518c51d93 100644
--- a/include/dm/util.h
+++ b/include/dm/util.h
@@ -17,14 +17,6 @@ struct dm_stats;
struct list_head;
/**
- * list_count_items() - Count number of items in a list
- *
- * @param head: Head of list
- * Return: number of items, or 0 if empty
- */
-int list_count_items(struct list_head *head);
-
-/**
* Dump out a tree of all devices starting @uclass
*
* @dev_name: udevice name
diff --git a/include/linux/list.h b/include/linux/list.h
index 6910721c005..0f9d939b05f 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -547,6 +547,21 @@ static inline void list_splice_tail_init(struct list_head *list,
&pos->member != (head); \
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+/**
+ * list_count_nodes - count nodes in the list
+ * @head: the head for your list.
+ */
+static inline size_t list_count_nodes(struct list_head *head)
+{
+ struct list_head *pos;
+ size_t count = 0;
+
+ list_for_each(pos, head)
+ count++;
+
+ return count;
+}
+
/*
* Double linked lists with a single pointer list head.
* Mostly useful for hash tables where the two pointer list head is
diff --git a/include/smbios.h b/include/smbios.h
index a4fda9df7bd..00119d7a60c 100644
--- a/include/smbios.h
+++ b/include/smbios.h
@@ -105,6 +105,7 @@ struct __packed smbios_type0 {
u8 bios_minor_release;
u8 ec_major_release;
u8 ec_minor_release;
+ u16 extended_bios_rom_size;
char eos[SMBIOS_STRUCT_EOS_BYTES];
};
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 38e64af2531..1179c31bb13 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -220,6 +220,7 @@ config EFI_CAPSULE_ON_DISK
config EFI_IGNORE_OSINDICATIONS
bool "Ignore OsIndications for CapsuleUpdate on-disk"
depends on EFI_CAPSULE_ON_DISK
+ default y if !EFI_RT_VOLATILE_STORE
help
There are boards where U-Boot does not support SetVariable at runtime.
Select this option if you want to use the capsule-on-disk feature
@@ -486,6 +487,7 @@ config EFI_ECPT
config EFI_EBBR_2_1_CONFORMANCE
bool "Add the EBBRv2.1 conformance entry to the ECPT table"
+ depends on BOOTMETH_EFI_BOOTMGR
depends on EFI_ECPT
depends on EFI_LOADER_HII
depends on EFI_RISCV_BOOT_PROTOCOL || !RISCV
diff --git a/lib/efi_loader/efi_fdt.c b/lib/efi_loader/efi_fdt.c
index 4ccf2055be3..c5ecade3aeb 100644
--- a/lib/efi_loader/efi_fdt.c
+++ b/lib/efi_loader/efi_fdt.c
@@ -43,6 +43,9 @@ int efi_get_distro_fdt_name(char *fname, int size, int seq)
case 2:
prefix = "/dtb/current";
break;
+ case 3:
+ prefix = "/dtbs";
+ break;
default:
return log_msg_ret("pref", -EINVAL);
}
diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c
index 348612c3dad..65d2116381a 100644
--- a/lib/efi_loader/efi_helper.c
+++ b/lib/efi_loader/efi_helper.c
@@ -133,7 +133,7 @@ efi_status_t efi_load_option_dp_join(struct efi_device_path **dp,
*dp = efi_dp_concat(tmp_dp, fdt_dp, *dp_size);
efi_free_pool(tmp_dp);
- if (!dp)
+ if (!*dp)
return EFI_OUT_OF_RESOURCES;
*dp_size += efi_dp_size(fdt_dp) + sizeof(END);
}
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index 12cf23fa3fa..c6f1dd09456 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -127,7 +127,7 @@ static uint64_t desc_get_end(struct efi_mem_desc *desc)
*/
static void efi_mem_sort(void)
{
- struct list_head *lhandle;
+ struct efi_mem_list *lmem;
struct efi_mem_list *prevmem = NULL;
bool merge_again = true;
@@ -136,19 +136,18 @@ static void efi_mem_sort(void)
/* Now merge entries that can be merged */
while (merge_again) {
merge_again = false;
- list_for_each(lhandle, &efi_mem) {
- struct efi_mem_list *lmem;
- struct efi_mem_desc *prev = &prevmem->desc;
+ list_for_each_entry(lmem, &efi_mem, link) {
+ struct efi_mem_desc *prev;
struct efi_mem_desc *cur;
uint64_t pages;
- lmem = list_entry(lhandle, struct efi_mem_list, link);
if (!prevmem) {
prevmem = lmem;
continue;
}
cur = &lmem->desc;
+ prev = &prevmem->desc;
if ((desc_get_end(cur) == prev->physical_start) &&
(prev->type == cur->type) &&
@@ -268,7 +267,7 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages,
int memory_type,
bool overlap_only_ram)
{
- struct list_head *lhandle;
+ struct efi_mem_list *lmem;
struct efi_mem_list *newlist;
bool carve_again;
uint64_t carved_pages = 0;
@@ -308,11 +307,9 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages,
/* Add our new map */
do {
carve_again = false;
- list_for_each(lhandle, &efi_mem) {
- struct efi_mem_list *lmem;
+ list_for_each_entry(lmem, &efi_mem, link) {
s64 r;
- lmem = list_entry(lhandle, struct efi_mem_list, link);
r = efi_mem_carve_out(lmem, &newlist->desc,
overlap_only_ram);
switch (r) {
@@ -444,7 +441,7 @@ static efi_status_t efi_check_allocated(u64 addr, bool must_be_allocated)
*/
static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr)
{
- struct list_head *lhandle;
+ struct efi_mem_list *lmem;
/*
* Prealign input max address, so we simplify our matching
@@ -452,9 +449,7 @@ static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr)
*/
max_addr &= ~EFI_PAGE_MASK;
- list_for_each(lhandle, &efi_mem) {
- struct efi_mem_list *lmem = list_entry(lhandle,
- struct efi_mem_list, link);
+ list_for_each_entry(lmem, &efi_mem, link) {
struct efi_mem_desc *desc = &lmem->desc;
uint64_t desc_len = desc->num_pages << EFI_PAGE_SHIFT;
uint64_t desc_end = desc->physical_start + desc_len;
@@ -742,9 +737,9 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
efi_uintn_t *descriptor_size,
uint32_t *descriptor_version)
{
+ size_t map_entries;
efi_uintn_t map_size = 0;
- int map_entries = 0;
- struct list_head *lhandle;
+ struct efi_mem_list *lmem;
efi_uintn_t provided_map_size;
if (!memory_map_size)
@@ -752,8 +747,7 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
provided_map_size = *memory_map_size;
- list_for_each(lhandle, &efi_mem)
- map_entries++;
+ map_entries = list_count_nodes(&efi_mem);
map_size = map_entries * sizeof(struct efi_mem_desc);
@@ -774,10 +768,7 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
/* Copy list into array */
/* Return the list in ascending order */
memory_map = &memory_map[map_entries - 1];
- list_for_each(lhandle, &efi_mem) {
- struct efi_mem_list *lmem;
-
- lmem = list_entry(lhandle, struct efi_mem_list, link);
+ list_for_each_entry(lmem, &efi_mem, link) {
*memory_map = lmem->desc;
memory_map--;
}
diff --git a/lib/smbios.c b/lib/smbios.c
index 4126466e34a..7c24ea129eb 100644
--- a/lib/smbios.c
+++ b/lib/smbios.c
@@ -22,6 +22,7 @@
#include <cpu.h>
#include <dm/uclass-internal.h>
#endif
+#include <linux/sizes.h>
/* Safeguard for checking that U_BOOT_VERSION_NUM macros are compatible with U_BOOT_DMI */
#if U_BOOT_VERSION_NUM < 2000 || U_BOOT_VERSION_NUM > 2099 || \
@@ -348,7 +349,13 @@ static int smbios_write_type0(ulong *current, int handle,
#endif
t->bios_release_date = smbios_add_prop(ctx, NULL, U_BOOT_DMI_DATE);
#ifdef CONFIG_ROM_SIZE
- t->bios_rom_size = (CONFIG_ROM_SIZE / 65536) - 1;
+ if (CONFIG_ROM_SIZE < SZ_16M) {
+ t->bios_rom_size = (CONFIG_ROM_SIZE / 65536) - 1;
+ } else {
+ /* CONFIG_ROM_SIZE < 8 GiB */
+ t->bios_rom_size = 0xff;
+ t->extended_bios_rom_size = CONFIG_ROM_SIZE >> 20;
+ }
#endif
t->bios_characteristics = BIOS_CHARACTERISTICS_PCI_SUPPORTED |
BIOS_CHARACTERISTICS_SELECTABLE_BOOT |
diff --git a/test/dm/bus.c b/test/dm/bus.c
index a338c7f567c..95326f23dad 100644
--- a/test/dm/bus.c
+++ b/test/dm/bus.c
@@ -14,6 +14,7 @@
#include <dm/test.h>
#include <dm/uclass-internal.h>
#include <dm/util.h>
+#include <linux/list.h>
#include <test/test.h>
#include <test/ut.h>
@@ -27,14 +28,14 @@ static int dm_test_bus_children(struct unit_test_state *uts)
struct uclass *uc;
ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
- ut_asserteq(num_devices, list_count_items(&uc->dev_head));
+ ut_asserteq(num_devices, list_count_nodes(&uc->dev_head));
/* Probe the bus, which should yield 3 more devices */
ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
num_devices += 3;
ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
- ut_asserteq(num_devices, list_count_items(&uc->dev_head));
+ ut_asserteq(num_devices, list_count_nodes(&uc->dev_head));
ut_assert(!dm_check_devices(uts, num_devices));
diff --git a/test/dm/core.c b/test/dm/core.c
index dbad1b317db..5bc5e8e82ec 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -16,6 +16,7 @@
#include <dm/util.h>
#include <dm/test.h>
#include <dm/uclass-internal.h>
+#include <linux/list.h>
#include <test/test.h>
#include <test/ut.h>
@@ -123,15 +124,15 @@ static int dm_test_autobind(struct unit_test_state *uts)
* device with no children.
*/
ut_assert(uts->root);
- ut_asserteq(1, list_count_items(gd->uclass_root));
- ut_asserteq(0, list_count_items(&gd->dm_root->child_head));
+ ut_asserteq(1, list_count_nodes(gd->uclass_root));
+ ut_asserteq(0, list_count_nodes(&gd->dm_root->child_head));
ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_BIND]);
ut_assertok(dm_scan_plat(false));
/* We should have our test class now at least, plus more children */
- ut_assert(1 < list_count_items(gd->uclass_root));
- ut_assert(0 < list_count_items(&gd->dm_root->child_head));
+ ut_assert(1 < list_count_nodes(gd->uclass_root));
+ ut_assert(0 < list_count_nodes(&gd->dm_root->child_head));
/* Our 3 dm_test_infox children should be bound to the test uclass */
ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_POST_BIND]);
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 18c89eef43f..31effff59c2 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -19,6 +19,7 @@
#include <dm/util.h>
#include <dm/of_access.h>
#include <linux/ioport.h>
+#include <linux/list.h>
#include <test/test.h>
#include <test/ut.h>
@@ -162,7 +163,7 @@ static int dm_test_fdt(struct unit_test_state *uts)
ut_assert(!ret);
/* These are num_devices compatible root-level device tree nodes */
- ut_asserteq(num_devices, list_count_items(&uc->dev_head));
+ ut_asserteq(num_devices, list_count_nodes(&uc->dev_head));
/* Each should have platform data but no private data */
for (i = 0; i < num_devices; i++) {
@@ -217,7 +218,7 @@ static int dm_test_fdt_pre_reloc(struct unit_test_state *uts)
* one with "bootph-all" property (a-test node), and the other
* one whose driver marked with DM_FLAG_PRE_RELOC flag (h-test node).
*/
- ut_asserteq(2, list_count_items(&uc->dev_head));
+ ut_asserteq(2, list_count_nodes(&uc->dev_head));
return 0;
}