Up to now we configure the entire memory space for U-Boot as RWX.

For modern architectures and security requirements, it's better to
 map the memory properly.
 This pull request adds basics support for mapping the U-Boot binary with
 proper (RO, RW, RW^X) memory permissions on aarch64 right after we
 relocate U-Boot in the top of DRAM.
 It's worrth noting that the linker script annotations are only added for
 the aarch64 architecture. We can, in the future, try to unify the linker --
 at least for the architectures that have enough in common and expand this
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEgWII69YpahbL5iK5gS8AYozs+qIFAmfUFksACgkQgS8AYozs
 +qLa0hAAg/wmSJhOfzYw+7fMsQebtWMcY7dEa88u3I5QyUQfYFujXuVj+Y5PbguR
 o6DsO26HVRwzo/+YSdVih+GTS1C0BVGVdNE5HZmM1ju4lzgnsZHLuiNx7859Uq0H
 8PWpGb7okB9m22YBOqbXaj5o7QFryU6AU5gEBJYCV6aRxXv5Ha4VoQsdrOkj9eVN
 8QHm5m7EKApYPmjDRul1TNlFNUjhmDNkcEij4pmpNAOl92zbyn4r62c6/u3jYov7
 P9eFt9CLnkCm8k86e+ciXUvykSNxhNGSvCUMLwDJA3oqizBJPfvYF5yyHW0LeCi+
 pXYtxQ9igGfh+AYeEn4vxYcLqIf1Iqr78QKg/De3Vok6e7+UJBOspxCUS/gxjvAi
 Yn1/n31KzaP9hAJKcZ+NTAKOhgyENnDIZ/qSTMhEDwXbiWmn36hGJlnZZE610TbR
 zxgeYChCbcI7eXq/wCJDPNVP51xMh/MZUGup3rREp/0YG5Cl1dMJ1WjcX1O0W1u3
 WKv8MZ6XP5fKTR8dUr+H4V3tcJ6VGuMQ1oHH9xZ/dar4RMboFPMZeFFIzhBIOQT4
 rcQfjmORrQ/ES6Inv+7QgjpZScJ8E+8yFEW1o9y+7tOf+CL8Jq+l0OW9NdNcRRox
 MxrgAIRkdAiKQj2qvLqV2RGhc/OSa/U75cLbVEcTjcJ+ya/0wfg=
 =AKxY
 -----END PGP SIGNATURE-----

Merge tag 'mmu-next-14032025' of https://source.denx.de/u-boot/custodians/u-boot-tpm into next

Up to now we configure the entire memory space for U-Boot as RWX.
For modern architectures and security requirements, it's better to
map the memory properly.
This pull request adds basics support for mapping the U-Boot binary with
proper (RO, RW, RW^X) memory permissions on aarch64 right after we
relocate U-Boot in the top of DRAM.
It's worrth noting that the linker script annotations are only added for
the aarch64 architecture. We can, in the future, try to unify the linker --
at least for the architectures that have enough in common and expand this
This commit is contained in:
Tom Rini 2025-03-14 09:31:36 -06:00
commit 973c366ce6
21 changed files with 313 additions and 60 deletions

View file

@ -8,6 +8,7 @@
#include <asm/global_data.h>
#include <linux/bitops.h>
#include <linux/compiler.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/log2.h>
#include <asm/arcregs.h>
@ -819,3 +820,8 @@ void sync_n_cleanup_cache_all(void)
__ic_entire_invalidate();
}
int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
{
return -ENOSYS;
}

View file

@ -5,6 +5,7 @@
*/
#include <cpu_func.h>
#include <asm/cache.h>
#include <linux/errno.h>
#include <linux/types.h>
#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
@ -88,3 +89,8 @@ void enable_caches(void)
dcache_enable();
#endif
}
int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
{
return -ENOSYS;
}

View file

@ -6,6 +6,7 @@
*/
#include <cpu_func.h>
#include <asm/cache.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <asm/armv7.h>
#include <asm/utils.h>
@ -209,3 +210,8 @@ __weak void v7_outer_cache_flush_all(void) {}
__weak void v7_outer_cache_inval_all(void) {}
__weak void v7_outer_cache_flush_range(u32 start, u32 end) {}
__weak void v7_outer_cache_inval_range(u32 start, u32 end) {}
int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
{
return -ENOSYS;
}

View file

@ -11,6 +11,7 @@
#include <asm/cache.h>
#include <asm/io.h>
#include <linux/bitops.h>
#include <linux/errno.h>
/* Cache maintenance operation registers */
@ -370,3 +371,8 @@ void enable_caches(void)
dcache_enable();
#endif
}
int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
{
return -ENOSYS;
}

View file

@ -14,6 +14,7 @@
#include <asm/global_data.h>
#include <asm/system.h>
#include <asm/armv8/mmu.h>
#include <linux/errno.h>
DECLARE_GLOBAL_DATA_PTR;
@ -421,7 +422,7 @@ static int count_ranges(void)
return count;
}
#define ALL_ATTRS (3 << 8 | PMD_ATTRINDX_MASK)
#define ALL_ATTRS (3 << 8 | PMD_ATTRMASK)
#define PTE_IS_TABLE(pte, level) (pte_type(&(pte)) == PTE_TYPE_TABLE && (level) < 3)
enum walker_state {
@ -568,6 +569,20 @@ static void pretty_print_table_attrs(u64 pte)
static void pretty_print_block_attrs(u64 pte)
{
u64 attrs = pte & PMD_ATTRINDX_MASK;
u64 perm_attrs = pte & PMD_ATTRMASK;
char mem_attrs[16] = { 0 };
int cnt = 0;
if (perm_attrs & PTE_BLOCK_PXN)
cnt += snprintf(mem_attrs + cnt, sizeof(mem_attrs) - cnt, "PXN ");
if (perm_attrs & PTE_BLOCK_UXN)
cnt += snprintf(mem_attrs + cnt, sizeof(mem_attrs) - cnt, "UXN ");
if (perm_attrs & PTE_BLOCK_RO)
cnt += snprintf(mem_attrs + cnt, sizeof(mem_attrs) - cnt, "RO");
if (!mem_attrs[0])
snprintf(mem_attrs, sizeof(mem_attrs), "RWX ");
printf(" | %-10s", mem_attrs);
switch (attrs) {
case PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE):
@ -613,6 +628,7 @@ static void print_pte(u64 pte, int level)
{
if (PTE_IS_TABLE(pte, level)) {
printf(" %-5s", "Table");
printf(" %-12s", "|");
pretty_print_table_attrs(pte);
} else {
pretty_print_pte_type(pte);
@ -642,9 +658,9 @@ static bool pagetable_print_entry(u64 start_attrs, u64 end, int va_bits, int lev
printf("%*s", indent * 2, "");
if (PTE_IS_TABLE(start_attrs, level))
printf("[%#011llx]%14s", _addr, "");
printf("[%#016llx]%19s", _addr, "");
else
printf("[%#011llx - %#011llx]", _addr, end);
printf("[%#016llx - %#016llx]", _addr, end);
printf("%*s | ", (3 - level) * 2, "");
print_pte(start_attrs, level);
@ -952,6 +968,34 @@ void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
flush_dcache_range(real_start, real_start + real_size);
}
void mmu_change_region_attr_nobreak(phys_addr_t addr, size_t siz, u64 attrs)
{
int level;
u64 r, size, start;
/*
* Loop through the address range until we find a page granule that fits
* our alignment constraints and set the new permissions
*/
start = addr;
size = siz;
while (size > 0) {
for (level = 1; level < 4; level++) {
/* Set PTE to new attributes */
r = set_one_region(start, size, attrs, true, level);
if (r) {
/* PTE successfully updated */
size -= r;
start += r;
break;
}
}
}
flush_dcache_range(gd->arch.tlb_addr,
gd->arch.tlb_addr + gd->arch.tlb_size);
__asm_invalidate_tlb_all();
}
/*
* Modify MMU table for a region with updated PXN/UXN/Memory type/valid bits.
* The procecess is break-before-make. The target region will be marked as
@ -986,27 +1030,31 @@ void mmu_change_region_attr(phys_addr_t addr, size_t siz, u64 attrs)
gd->arch.tlb_addr + gd->arch.tlb_size);
__asm_invalidate_tlb_all();
/*
* Loop through the address range until we find a page granule that fits
* our alignment constraints, then set it to the new cache attributes
*/
start = addr;
size = siz;
while (size > 0) {
for (level = 1; level < 4; level++) {
/* Set PTE to new attributes */
r = set_one_region(start, size, attrs, true, level);
if (r) {
/* PTE successfully updated */
size -= r;
start += r;
mmu_change_region_attr_nobreak(addr, siz, attrs);
}
int pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
{
u64 attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE | PTE_TYPE_VALID;
switch (perm) {
case MMU_ATTR_RO:
attrs |= PTE_BLOCK_PXN | PTE_BLOCK_UXN | PTE_BLOCK_RO;
break;
case MMU_ATTR_RX:
attrs |= PTE_BLOCK_RO;
break;
case MMU_ATTR_RW:
attrs |= PTE_BLOCK_PXN | PTE_BLOCK_UXN;
break;
default:
log_err("Unknown attribute %d\n", perm);
return -EINVAL;
}
}
}
flush_dcache_range(gd->arch.tlb_addr,
gd->arch.tlb_addr + gd->arch.tlb_size);
__asm_invalidate_tlb_all();
mmu_change_region_attr_nobreak(addr, size, attrs);
return 0;
}
#else /* !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
@ -1112,3 +1160,8 @@ void __weak enable_caches(void)
icache_enable();
dcache_enable();
}
void arch_dump_mem_attrs(void)
{
dump_pagetable(gd->arch.tlb_addr, get_tcr(NULL, NULL));
}

View file

@ -36,9 +36,18 @@ SECTIONS
__efi_runtime_stop = .;
}
#ifdef CONFIG_MMU_PGPROT
.text_rest ALIGN(CONSTANT(COMMONPAGESIZE)) :
#else
.text_rest :
#endif
{
__text_start = .;
*(.text*)
#ifdef CONFIG_MMU_PGPROT
. = ALIGN(CONSTANT(COMMONPAGESIZE));
#endif
__text_end = .;
}
#ifdef CONFIG_ARMV8_PSCI
@ -97,24 +106,6 @@ SECTIONS
LONG(0x1d1071c); /* Must output something to reset LMA */
}
#endif
. = ALIGN(8);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(8);
.data : {
*(.data*)
}
. = ALIGN(8);
. = .;
. = ALIGN(8);
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
.efi_runtime_rel : {
__efi_runtime_rel_start = .;
*(.rel*.efi_runtime)
@ -122,10 +113,36 @@ SECTIONS
__efi_runtime_rel_stop = .;
}
#ifdef CONFIG_MMU_PGPROT
.rodata ALIGN(CONSTANT(COMMONPAGESIZE)): {
#else
.rodata ALIGN(8) : {
#endif
__start_rodata = .;
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
}
__u_boot_list ALIGN(8) : {
KEEP(*(SORT(__u_boot_list*)));
#ifdef CONFIG_MMU_PGPROT
. = ALIGN(CONSTANT(COMMONPAGESIZE));
#endif
__end_rodata = .;
}
#ifdef CONFIG_MMU_PGPROT
.data ALIGN(CONSTANT(COMMONPAGESIZE)) : {
#else
.data ALIGN(8) : {
#endif
__start_data = .;
*(.data*)
}
. = ALIGN(8);
__image_copy_end = .;
.rela.dyn : {
.rela.dyn ALIGN(8) : {
__rel_dyn_start = .;
*(.rela*)
__rel_dyn_end = .;
@ -136,11 +153,15 @@ SECTIONS
/*
* arch/arm/lib/crt0_64.S assumes __bss_start - __bss_end % 8 == 0
*/
.bss ALIGN(8) : {
.bss ADDR(.rela.dyn) (OVERLAY) : {
__bss_start = .;
*(.bss*)
. = ALIGN(8);
__bss_end = .;
#ifdef CONFIG_MMU_PGPROT
. = ALIGN(CONSTANT(COMMONPAGESIZE));
#endif
__end_data = .;
}
/DISCARD/ : { *(.dynsym) }

View file

@ -66,6 +66,7 @@
#define PTE_BLOCK_NG (1 << 11)
#define PTE_BLOCK_PXN (UL(1) << 53)
#define PTE_BLOCK_UXN (UL(1) << 54)
#define PTE_BLOCK_RO (UL(1) << 7)
/*
* AttrIndx[2:0]
@ -75,6 +76,7 @@
#define PMD_ATTRMASK (PTE_BLOCK_PXN | \
PTE_BLOCK_UXN | \
PMD_ATTRINDX_MASK | \
PTE_BLOCK_RO | \
PTE_TYPE_VALID)
/*

View file

@ -303,8 +303,26 @@ void flush_l3_cache(void);
* @emerg: Also map the region in the emergency table
*/
void mmu_map_region(phys_addr_t start, u64 size, bool emerg);
/**
* mmu_change_region_attr() - change a mapped region attributes
*
* @start: Start address of the region
* @size: Size of the region
* @aatrs: New attributes
*/
void mmu_change_region_attr(phys_addr_t start, size_t size, u64 attrs);
/**
* mmu_change_region_attr_nobreak() - change a mapped region attributes without doing
* break-before-make
*
* @start: Start address of the region
* @size: Size of the region
* @aatrs: New attributes
*/
void mmu_change_region_attr_nobreak(phys_addr_t addr, size_t size, u64 attrs);
/*
* smc_call() - issue a secure monitor call
*

View file

@ -10,6 +10,7 @@
#include <malloc.h>
#include <asm/cache.h>
#include <asm/global_data.h>
#include <linux/errno.h>
DECLARE_GLOBAL_DATA_PTR;
@ -170,3 +171,8 @@ __weak int arm_reserve_mmu(void)
return 0;
}
int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
{
return -ENOSYS;
}

View file

@ -8,6 +8,7 @@
#include <cpu_func.h>
#include <asm/immap.h>
#include <asm/cache.h>
#include <linux/errno.h>
volatile int *cf_icache_status = (int *)ICACHE_STATUS;
volatile int *cf_dcache_status = (int *)DCACHE_STATUS;
@ -151,3 +152,8 @@ __weak void flush_dcache_range(unsigned long start, unsigned long stop)
{
/* An empty stub, real implementation should be in platform code */
}
int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
{
return -ENOSYS;
}

View file

@ -8,6 +8,7 @@
#include <cpu_func.h>
#include <asm/cache.h>
#include <asm/global_data.h>
#include <linux/errno.h>
DECLARE_GLOBAL_DATA_PTR;
@ -127,3 +128,8 @@ void dcache_disable(void)
{
flush_dcache_all();
}
int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
{
return -ENOSYS;
}

View file

@ -8,6 +8,7 @@
#include <stdio.h>
#include <asm/cache.h>
#include <watchdog.h>
#include <linux/errno.h>
static ulong maybe_watchdog_reset(ulong flushed)
{
@ -58,3 +59,8 @@ void invalidate_icache_all(void)
{
puts("No arch specific invalidate_icache_all available!\n");
}
int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
{
return -ENOSYS;
}

View file

@ -8,6 +8,7 @@
#include <dm.h>
#include <asm/insn-def.h>
#include <linux/const.h>
#include <linux/errno.h>
#define CBO_INVAL(base) \
INSN_I(OPCODE_MISC_MEM, FUNC3(2), __RD(0), \
@ -151,3 +152,8 @@ __weak void enable_caches(void)
if (!zicbom_block_size)
log_debug("Zicbom not initialized.\n");
}
int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
{
return -ENOSYS;
}

View file

@ -11,6 +11,7 @@
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <linux/errno.h>
#define CACHE_VALID 1
#define CACHE_UPDATED 2
@ -126,3 +127,8 @@ int dcache_status(void)
{
return 0;
}
int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
{
return -ENOSYS;
}

View file

@ -6,6 +6,7 @@
#include <cpu_func.h>
#include <asm/cache.h>
#include <linux/errno.h>
/*
* We currently run always with caches enabled when running from memory.
@ -57,3 +58,8 @@ void invalidate_icache_all(void)
{
__invalidate_icache_all();
}
int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
{
return -ENOSYS;
}

View file

@ -15,6 +15,10 @@
DECLARE_GLOBAL_DATA_PTR;
void __weak arch_dump_mem_attrs(void)
{
}
static void print_region(const char *name, ulong base, ulong size, ulong *uptop)
{
ulong end = base + size;
@ -58,6 +62,8 @@ static int do_meminfo(struct cmd_tbl *cmdtp, int flag, int argc,
if (!IS_ENABLED(CONFIG_CMD_MEMINFO_MAP))
return 0;
arch_dump_mem_attrs();
printf("\n%-12s %8s %8s %8s %8s\n", "Region", "Base", "Size", "End",
"Gap");
printf("------------------------------------------------\n");

View file

@ -914,6 +914,19 @@ config STACKPROTECTOR
Enable stack smash detection through compiler's stack-protector
canary logic
config MMU_PGPROT
bool "Enable RO, RW and RX mappings"
help
U-Boot maps all pages as RWX. If selected pages will
be marked as RO(.rodata), RX(.text), RW(.data) right after
we relocate. Since code sections needs to be page aligned
the final binary size will increase. The mappings can be dumped
using the 'meminfo' command.
Enabling this feature can expose bugs in U-Boot where we have
code that violates read-only permissions for example. Use this
feature with caution.
config SPL_STACKPROTECTOR
bool "Stack Protector buffer overflow detection for SPL"
depends on STACKPROTECTOR && SPL

View file

@ -170,7 +170,27 @@ static int initr_reloc_global_data(void)
efi_save_gd();
efi_runtime_relocate(gd->relocaddr, NULL);
#endif
/*
* We are done with all relocations change the permissions of the binary
* NOTE: __start_rodata etc are defined in arm64 linker scripts and
* sections.h. If you want to add support for your platform you need to
* add the symbols on your linker script, otherwise they will point to
* random addresses.
*
*/
if (IS_ENABLED(CONFIG_MMU_PGPROT)) {
pgprot_set_attrs((phys_addr_t)(uintptr_t)(__start_rodata),
(size_t)(uintptr_t)(__end_rodata - __start_rodata),
MMU_ATTR_RO);
pgprot_set_attrs((phys_addr_t)(uintptr_t)(__start_data),
(size_t)(uintptr_t)(__end_data - __start_data),
MMU_ATTR_RW);
pgprot_set_attrs((phys_addr_t)(uintptr_t)(__text_start),
(size_t)(uintptr_t)(__text_end - __text_start),
MMU_ATTR_RX);
}
return 0;
}

View file

@ -18,7 +18,8 @@ Description
The meminfo command shows the amount of memory. If ``CONFIG_CMD_MEMINFO_MAP`` is
enabled, then it also shows the layout of memory used by U-Boot and the region
which is free for use by images.
which is free for use by images. In architectures that support it, it also prints
the mapped pages and their permissions. The latter is architecture specific.
The layout of memory is set up before relocation, within the init sequence in
``board_init_f()``, specifically the various ``reserve_...()`` functions. This
@ -26,8 +27,9 @@ The layout of memory is set up before relocation, within the init sequence in
ending with the stack. This results in the maximum possible amount of memory
being left free for image-loading.
The meminfo command writes the DRAM size, then the rest of its outputs in 5
columns:
The meminfo command writes the DRAM size. If the architecture also supports it,
page table entries will be shown next. Finally the rest of the outputs are
printed in 5 columns:
Region
Name of the region
@ -99,28 +101,61 @@ free
Free memory, which is available for loading images. The base address of
this is ``gd->ram_base`` which is generally set by ``CFG_SYS_SDRAM_BASE``.
Aarch64 specific flags
----------------------
More information on the output can be found
Chapter D8 - The AArch64 Virtual Memory System Architecture at
https://developer.arm.com/documentation/ddi0487/latest/
In short, for a stage 1 translation regime the following apply:
* RWX: Pages mapped with Read, Write and Execute permissions
* RO: Pages mapped with Read-Only permissions
* PXN: PXN (Privileged Execute Never) applies to execution at EL1 and above
* UXN: UXN (Unprivileged Execute Never) applies to EL0
Example
-------
This example shows output with both ``CONFIG_CMD_MEMINFO`` and
``CONFIG_CMD_MEMINFO_MAP`` enabled::
``CONFIG_CMD_MEMINFO_MAP`` enabled for aarch64 qemu::
=> meminfo
DRAM: 256 MiB
DRAM: 8 GiB
Walking pagetable at 000000023ffe0000, va_bits: 40. Using 4 levels
[0x0000023ffe1000] | Table | | |
[0x0000023ffe2000] | Table | | |
[0x00000000000000 - 0x00000008000000] | Block | RWX | Normal | Inner-shareable
[0x00000008000000 - 0x00000040000000] | Block | PXN UXN | Device-nGnRnE | Non-shareable
[0x00000040000000 - 0x00000200000000] | Block | RWX | Normal | Inner-shareable
[0x0000023ffea000] | Table | | |
[0x00000200000000 - 0x0000023f600000] | Block | RWX | Normal | Inner-shareable
[0x0000023ffeb000] | Table | | |
[0x0000023f600000 - 0x0000023f68c000] | Pages | RWX | Normal | Inner-shareable
[0x0000023f68c000 - 0x0000023f74f000] | Pages | RO | Normal | Inner-shareable
[0x0000023f74f000 - 0x0000023f794000] | Pages | PXN UXN RO | Normal | Inner-shareable
[0x0000023f794000 - 0x0000023f79d000] | Pages | PXN UXN | Normal | Inner-shareable
[0x0000023f79d000 - 0x0000023f800000] | Pages | RWX | Normal | Inner-shareable
[0x0000023f800000 - 0x00000240000000] | Block | RWX | Normal | Inner-shareable
[0x00000240000000 - 0x00004000000000] | Block | RWX | Normal | Inner-shareable
[0x0000023ffe3000] | Table | | |
[0x00004010000000 - 0x00004020000000] | Block | PXN UXN | Device-nGnRnE | Non-shareable
[0x0000023ffe4000] | Table | | |
[0x00008000000000 - 0x00010000000000] | Block | PXN UXN | Device-nGnRnE | Non-shareable
Region Base Size End Gap
------------------------------------------------
video f000000 1000000 10000000
code ec3a000 3c5d28 efffd28 2d8
malloc 8c38000 6002000 ec3a000 0
board_info 8c37f90 68 8c37ff8 8
global_data 8c37d80 208 8c37f88 8
devicetree 8c33000 4d7d 8c37d7d 3
bootstage 8c32c20 3c8 8c32fe8 18
bloblist 8c32000 400 8c32400 820
stack 7c31ff0 1000000 8c31ff0 10
free 0 7c31ff0 7c31ff0 0
video 23f7e0000 800000 23ffe0000
code 23f68a000 156000 23f7e0000 0
malloc 23e64a000 1040000 23f68a000 0
board_info 23e649f80 78 23e649ff8 8
global_data 23e649df0 188 23e649f78 8
devicetree 23e549df0 100000 23e649df0 0
bloblist 23e547000 2000 23e549000 df0
stack 23d546ff0 1000000 23e546ff0 10
lmb 23d546ff0 0 23d546ff0 0
lmb 23d543000 3ff0 23d546ff0 0
free 40000000 23d543000 27d543000 ffffffffc0000000
Return value
------------

View file

@ -23,6 +23,7 @@ extern char __kprobes_text_start[], __kprobes_text_end[];
extern char __entry_text_start[], __entry_text_end[];
extern char __initdata_begin[], __initdata_end[];
extern char __start_rodata[], __end_rodata[];
extern char __start_data[], __end_data[];
extern char __efi_helloworld_begin[];
extern char __efi_helloworld_end[];
extern char __efi_var_file_begin[];
@ -63,6 +64,7 @@ static inline int arch_is_kernel_data(unsigned long addr)
/* Start of U-Boot text region */
extern char __text_start[];
extern char __text_end[];
/* This marks the text region which must be relocated */
extern char __image_copy_start[], __image_copy_end[];

View file

@ -69,6 +69,23 @@ void flush_dcache_range(unsigned long start, unsigned long stop);
void invalidate_dcache_range(unsigned long start, unsigned long stop);
void invalidate_dcache_all(void);
void invalidate_icache_all(void);
enum pgprot_attrs {
MMU_ATTR_RO,
MMU_ATTR_RX,
MMU_ATTR_RW,
};
/** pgprot_set_attrs() - Set page table permissions
*
* @addr: Physical address start
* @size: size of memory to change
* @perm: New permissions
*
* Return: 0 on success, error otherwise.
**/
int pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm);
/**
* noncached_init() - Initialize non-cached memory region
*