Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
piggy_data
vmlinux
vmlinux.lds
@@ -0,0 +1,160 @@
# SPDX-License-Identifier: GPL-2.0
#
# linux/arch/arm/boot/compressed/Makefile
#
# create a compressed vmlinuz image from the original vmlinux
#
OBJS =
HEAD = head.o
OBJS += misc.o decompress.o
ifeq ($(CONFIG_DEBUG_UNCOMPRESS),y)
OBJS += debug.o
AFLAGS_head.o += -DDEBUG
endif
# string library code (-Os is enforced to keep it much smaller)
OBJS += string.o
CFLAGS_string.o := -Os
ifeq ($(CONFIG_ARM_VIRT_EXT),y)
OBJS += hyp-stub.o
endif
#
# Architecture dependencies
#
ifeq ($(CONFIG_ARCH_ACORN),y)
OBJS += ll_char_wr.o font.o
endif
ifeq ($(CONFIG_ARCH_SA1100),y)
OBJS += head-sa1100.o
endif
ifeq ($(CONFIG_CPU_XSCALE),y)
OBJS += head-xscale.o
endif
ifeq ($(CONFIG_PXA_SHARPSL_DETECT_MACH_ID),y)
OBJS += head-sharpsl.o
endif
ifeq ($(CONFIG_CPU_ENDIAN_BE32),y)
ifeq ($(CONFIG_CPU_CP15),y)
OBJS += big-endian.o
else
# The endian should be set by h/w design.
endif
endif
#
# We now have a PIC decompressor implementation. Decompressors running
# from RAM should not define ZTEXTADDR. Decompressors running directly
# from ROM or Flash must define ZTEXTADDR (preferably via the config)
# FIXME: Previous assignment to ztextaddr-y is lost here. See SHARK
ifeq ($(CONFIG_ZBOOT_ROM),y)
ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT)
ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS)
else
ZTEXTADDR := 0
ZBSSADDR := ALIGN(8)
endif
MALLOC_SIZE := 65536
AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET) -DMALLOC_SIZE=$(MALLOC_SIZE)
CPPFLAGS_vmlinux.lds := -DTEXT_START="$(ZTEXTADDR)" -DBSS_START="$(ZBSSADDR)"
CPPFLAGS_vmlinux.lds += -DTEXT_OFFSET="$(TEXT_OFFSET)"
CPPFLAGS_vmlinux.lds += -DMALLOC_SIZE="$(MALLOC_SIZE)"
compress-$(CONFIG_KERNEL_GZIP) = gzip
compress-$(CONFIG_KERNEL_LZO) = lzo_with_size
compress-$(CONFIG_KERNEL_LZMA) = lzma_with_size
compress-$(CONFIG_KERNEL_XZ) = xzkern_with_size
compress-$(CONFIG_KERNEL_LZ4) = lz4_with_size
libfdt_objs := fdt_rw.o fdt_ro.o fdt_wip.o fdt.o
ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y)
CFLAGS_REMOVE_atags_to_fdt.o += -Wframe-larger-than=${CONFIG_FRAME_WARN}
CFLAGS_atags_to_fdt.o += -Wframe-larger-than=1280
OBJS += $(libfdt_objs) atags_to_fdt.o
endif
ifeq ($(CONFIG_USE_OF),y)
OBJS += $(libfdt_objs) fdt_check_mem_start.o
endif
OBJS += lib1funcs.o ashldi3.o bswapsdi2.o
targets := vmlinux vmlinux.lds piggy_data piggy.o \
head.o $(OBJS)
KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin \
-I$(srctree)/scripts/dtc/libfdt -fno-stack-protector \
$(DISABLE_KSTACK_ERASE) \
-I$(obj)
ccflags-remove-$(CONFIG_FUNCTION_TRACER) += -pg
asflags-y := -DZIMAGE
# Supply kernel BSS size to the decompressor via a linker symbol.
KBSS_SZ = $(shell echo $$(($$($(NM) vmlinux | \
sed -n -e 's/^\([^ ]*\) [ABD] __bss_start$$/-0x\1/p' \
-e 's/^\([^ ]*\) [ABD] __bss_stop$$/+0x\1/p') )) )
LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
# Supply ZRELADDR to the decompressor via a linker symbol.
ifneq ($(CONFIG_AUTO_ZRELADDR),y)
LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR)
endif
ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
LDFLAGS_vmlinux += --be8
endif
# Report unresolved symbol references
LDFLAGS_vmlinux += --no-undefined
# Delete all temporary local symbols
LDFLAGS_vmlinux += -X
# Report orphan sections
ifdef CONFIG_LD_ORPHAN_WARN
LDFLAGS_vmlinux += --orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
endif
# Next argument is a linker script
LDFLAGS_vmlinux += -T
# We need to prevent any GOTOFF relocs being used with references
# to symbols in the .bss section since we cannot relocate them
# independently from the rest at run time. This can be achieved by
# ensuring that no private .bss symbols exist, as global symbols
# always have a GOT entry which is what we need.
# The .data section is already discarded by the linker script so no need
# to bother about it here.
check_for_bad_syms = \
bad_syms=$$($(NM) $@ | sed -n 's/^.\{8\} [bc] \(.*\)/\1/p') && \
[ -z "$$bad_syms" ] || \
( echo "following symbols must have non local/private scope:" >&2; \
echo "$$bad_syms" >&2; false )
check_for_multiple_zreladdr = \
if [ $(words $(ZRELADDR)) -gt 1 -a "$(CONFIG_AUTO_ZRELADDR)" = "" ]; then \
echo 'multiple zreladdrs: $(ZRELADDR)'; \
echo 'This needs CONFIG_AUTO_ZRELADDR to be set'; \
false; \
fi
efi-obj-$(CONFIG_EFI_STUB) := $(objtree)/drivers/firmware/efi/libstub/lib.a
$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \
$(addprefix $(obj)/, $(OBJS)) \
$(efi-obj-y) FORCE
@$(check_for_multiple_zreladdr)
$(call if_changed,ld)
@$(check_for_bad_syms)
$(obj)/piggy_data: $(obj)/../Image FORCE
$(call if_changed,$(compress-y))
$(obj)/piggy.o: $(obj)/piggy_data
CFLAGS_font.o := -DBOOTLOADER
@@ -0,0 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* For __aeabi_llsl */
#include "../../lib/ashldi3.S"
@@ -0,0 +1,218 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/libfdt_env.h>
#include <asm/setup.h>
#include <libfdt.h>
#include "misc.h"
#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND)
#define do_extend_cmdline 1
#else
#define do_extend_cmdline 0
#endif
#define NR_BANKS 16
static int node_offset(void *fdt, const char *node_path)
{
int offset = fdt_path_offset(fdt, node_path);
if (offset == -FDT_ERR_NOTFOUND)
/* Add the node to root if not found, dropping the leading '/' */
offset = fdt_add_subnode(fdt, 0, node_path + 1);
return offset;
}
static int setprop(void *fdt, const char *node_path, const char *property,
void *val_array, int size)
{
int offset = node_offset(fdt, node_path);
if (offset < 0)
return offset;
return fdt_setprop(fdt, offset, property, val_array, size);
}
static int setprop_string(void *fdt, const char *node_path,
const char *property, const char *string)
{
int offset = node_offset(fdt, node_path);
if (offset < 0)
return offset;
return fdt_setprop_string(fdt, offset, property, string);
}
static int setprop_cell(void *fdt, const char *node_path,
const char *property, uint32_t val)
{
int offset = node_offset(fdt, node_path);
if (offset < 0)
return offset;
return fdt_setprop_cell(fdt, offset, property, val);
}
static const void *getprop(const void *fdt, const char *node_path,
const char *property, int *len)
{
int offset = fdt_path_offset(fdt, node_path);
if (offset == -FDT_ERR_NOTFOUND)
return NULL;
return fdt_getprop(fdt, offset, property, len);
}
static uint32_t get_cell_size(const void *fdt)
{
int len;
uint32_t cell_size = 1;
const __be32 *size_len = getprop(fdt, "/", "#size-cells", &len);
if (size_len)
cell_size = fdt32_to_cpu(*size_len);
return cell_size;
}
static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
{
char cmdline[COMMAND_LINE_SIZE];
const char *fdt_bootargs;
char *ptr = cmdline;
int len = 0;
/* copy the fdt command line into the buffer */
fdt_bootargs = getprop(fdt, "/chosen", "bootargs", &len);
if (fdt_bootargs)
if (len < COMMAND_LINE_SIZE) {
memcpy(ptr, fdt_bootargs, len);
/* len is the length of the string
* including the NULL terminator */
ptr += len - 1;
}
/* and append the ATAG_CMDLINE */
if (fdt_cmdline) {
len = strlen(fdt_cmdline);
if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
*ptr++ = ' ';
memcpy(ptr, fdt_cmdline, len);
ptr += len;
}
}
*ptr = '\0';
setprop_string(fdt, "/chosen", "bootargs", cmdline);
}
static void hex_str(char *out, uint32_t value)
{
uint32_t digit;
int idx;
for (idx = 7; idx >= 0; idx--) {
digit = value >> 28;
value <<= 4;
digit &= 0xf;
if (digit < 10)
digit += '0';
else
digit += 'A'-10;
*out++ = digit;
}
*out = '\0';
}
/*
* Convert and fold provided ATAGs into the provided FDT.
*
* Return values:
* = 0 -> pretend success
* = 1 -> bad ATAG (may retry with another possible ATAG pointer)
* < 0 -> error from libfdt
*/
int atags_to_fdt(void *atag_list, void *fdt, int total_space)
{
struct tag *atag = atag_list;
/* In the case of 64 bits memory size, need to reserve 2 cells for
* address and size for each bank */
__be32 mem_reg_property[2 * 2 * NR_BANKS];
int memcount = 0;
int ret, memsize;
/* make sure we've got an aligned pointer */
if ((u32)atag_list & 0x3)
return 1;
/* if we get a DTB here we're done already */
if (*(__be32 *)atag_list == cpu_to_fdt32(FDT_MAGIC))
return 0;
/* validate the ATAG */
if (atag->hdr.tag != ATAG_CORE ||
(atag->hdr.size != tag_size(tag_core) &&
atag->hdr.size != 2))
return 1;
/* let's give it all the room it could need */
ret = fdt_open_into(fdt, fdt, total_space);
if (ret < 0)
return ret;
for_each_tag(atag, atag_list) {
if (atag->hdr.tag == ATAG_CMDLINE) {
/* Append the ATAGS command line to the device tree
* command line.
* NB: This means that if the same parameter is set in
* the device tree and in the tags, the one from the
* tags will be chosen.
*/
if (do_extend_cmdline)
merge_fdt_bootargs(fdt,
atag->u.cmdline.cmdline);
else
setprop_string(fdt, "/chosen", "bootargs",
atag->u.cmdline.cmdline);
} else if (atag->hdr.tag == ATAG_MEM) {
if (memcount >= sizeof(mem_reg_property)/4)
continue;
if (!atag->u.mem.size)
continue;
memsize = get_cell_size(fdt);
if (memsize == 2) {
/* if memsize is 2, that means that
* each data needs 2 cells of 32 bits,
* so the data are 64 bits */
__be64 *mem_reg_prop64 =
(__be64 *)mem_reg_property;
mem_reg_prop64[memcount++] =
cpu_to_fdt64(atag->u.mem.start);
mem_reg_prop64[memcount++] =
cpu_to_fdt64(atag->u.mem.size);
} else {
mem_reg_property[memcount++] =
cpu_to_fdt32(atag->u.mem.start);
mem_reg_property[memcount++] =
cpu_to_fdt32(atag->u.mem.size);
}
} else if (atag->hdr.tag == ATAG_INITRD2) {
uint32_t initrd_start, initrd_size;
initrd_start = atag->u.initrd.start;
initrd_size = atag->u.initrd.size;
setprop_cell(fdt, "/chosen", "linux,initrd-start",
initrd_start);
setprop_cell(fdt, "/chosen", "linux,initrd-end",
initrd_start + initrd_size);
} else if (atag->hdr.tag == ATAG_SERIAL) {
char serno[16+2];
hex_str(serno, atag->u.serialnr.high);
hex_str(serno+8, atag->u.serialnr.low);
setprop_string(fdt, "/", "serial-number", serno);
}
}
if (memcount) {
setprop(fdt, "/memory", "reg", mem_reg_property,
4 * memcount * memsize);
}
return fdt_pack(fdt);
}
@@ -0,0 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* linux/arch/arm/boot/compressed/big-endian.S
*
* Switch CPU into big endian mode.
* Author: Nicolas Pitre
*/
.section ".start", "ax"
mrc p15, 0, r0, c1, c0, 0 @ read control reg
orr r0, r0, #(1 << 7) @ enable big endian mode
mcr p15, 0, r0, c1, c0, 0 @ write control reg
@@ -0,0 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* For __bswapsi2, __bswapdi2 */
#include "../../lib/bswapsdi2.S"
@@ -0,0 +1,48 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/linkage.h>
#include <asm/assembler.h>
#ifndef CONFIG_DEBUG_SEMIHOSTING
#include CONFIG_DEBUG_LL_INCLUDE
ENTRY(putc)
addruart r1, r2, r3
#ifdef CONFIG_DEBUG_UART_FLOW_CONTROL
waituartcts r3, r1
#endif
waituarttxrdy r3, r1
senduart r0, r1
busyuart r3, r1
mov pc, lr
ENDPROC(putc)
#else
ENTRY(putc)
adr r1, 1f
ldmia r1, {r2, r3}
add r2, r2, r1
ldr r1, [r2, r3]
strb r0, [r1]
mov r0, #0x03 @ SYS_WRITEC
ARM( svc #0x123456 )
#ifdef CONFIG_CPU_V7M
THUMB( bkpt #0xab )
#else
THUMB( svc #0xab )
#endif
mov pc, lr
.align 2
1: .word _GLOBAL_OFFSET_TABLE_ - .
.word semi_writec_buf(GOT)
ENDPROC(putc)
.bss
.global semi_writec_buf
.type semi_writec_buf, %object
semi_writec_buf:
.space 4
.size semi_writec_buf, 4
#endif
@@ -0,0 +1,66 @@
// SPDX-License-Identifier: GPL-2.0
#define _LINUX_STRING_H_
#include <linux/compiler.h> /* for inline */
#include <linux/types.h> /* for size_t */
#include <linux/stddef.h> /* for NULL */
#include <linux/linkage.h>
#include <asm/string.h>
#include "misc.h"
#define STATIC static
#define STATIC_RW_DATA /* non-static please */
/* Diagnostic functions */
#ifdef DEBUG
# define Assert(cond,msg) {if(!(cond)) error(msg);}
# define Trace(x) fprintf x
# define Tracev(x) {if (verbose) fprintf x ;}
# define Tracevv(x) {if (verbose>1) fprintf x ;}
# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
#else
# define Assert(cond,msg)
# define Trace(x)
# define Tracev(x)
# define Tracevv(x)
# define Tracec(c,x)
# define Tracecv(c,x)
#endif
/* Not needed, but used in some headers pulled in by decompressors */
extern char * strstr(const char * s1, const char *s2);
extern size_t strlen(const char *s);
extern int strcmp(const char *cs, const char *ct);
extern int memcmp(const void *cs, const void *ct, size_t count);
extern char * strchrnul(const char *, int);
#ifdef CONFIG_KERNEL_GZIP
#include "../../../../lib/decompress_inflate.c"
#endif
#ifdef CONFIG_KERNEL_LZO
#include "../../../../lib/decompress_unlzo.c"
#endif
#ifdef CONFIG_KERNEL_LZMA
#include "../../../../lib/decompress_unlzma.c"
#endif
#ifdef CONFIG_KERNEL_XZ
/* Prevent KASAN override of string helpers in decompressor */
#undef memmove
#define memmove memmove
#undef memcpy
#define memcpy memcpy
#include "../../../../lib/decompress_unxz.c"
#endif
#ifdef CONFIG_KERNEL_LZ4
#include "../../../../lib/decompress_unlz4.c"
#endif
int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
{
return __decompress(input, len, NULL, NULL, output, 0, NULL, error);
}
@@ -0,0 +1,136 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2013-2017 Linaro Ltd
* Authors: Roy Franz <roy.franz@linaro.org>
* Ard Biesheuvel <ard.biesheuvel@linaro.org>
*/
#include <linux/pe.h>
#include <linux/sizes.h>
.macro __nop
AR_CLASS( mov r0, r0 )
M_CLASS( nop.w )
.endm
.macro __initial_nops
#ifdef CONFIG_EFI_STUB
@ This is a two-instruction NOP, which happens to bear the
@ PE/COFF signature "MZ" in the first two bytes, so the kernel
@ is accepted as an EFI binary. Booting via the UEFI stub
@ will not execute those instructions, but the ARM/Linux
@ boot protocol does, so we need some NOPs here.
.inst IMAGE_DOS_SIGNATURE | (0xe225 << 16) @ eor r5, r5, 0x4d000
eor r5, r5, 0x4d000 @ undo previous insn
#else
__nop
__nop
#endif
.endm
.macro __EFI_HEADER
#ifdef CONFIG_EFI_STUB
.set start_offset, __efi_start - start
.org start + 0x3c
@
@ The PE header can be anywhere in the file, but for
@ simplicity we keep it together with the MSDOS header
@ The offset to the PE/COFF header needs to be at offset
@ 0x3C in the MSDOS header.
@ The only 2 fields of the MSDOS header that are used are this
@ PE/COFF offset, and the "MZ" bytes at offset 0x0.
@
.long pe_header - start @ Offset to the PE header.
pe_header:
.long IMAGE_NT_SIGNATURE
coff_header:
.short IMAGE_FILE_MACHINE_THUMB @ Machine
.short section_count @ NumberOfSections
.long 0 @ TimeDateStamp
.long 0 @ PointerToSymbolTable
.long 0 @ NumberOfSymbols
.short section_table - optional_header @ SizeOfOptionalHeader
.short IMAGE_FILE_32BIT_MACHINE | \
IMAGE_FILE_DEBUG_STRIPPED | \
IMAGE_FILE_EXECUTABLE_IMAGE | \
IMAGE_FILE_LINE_NUMS_STRIPPED @ Characteristics
#define __pecoff_code_size (__pecoff_data_start - __efi_start)
optional_header:
.short IMAGE_NT_OPTIONAL_HDR32_MAGIC @ PE32 format
.byte 0x02 @ MajorLinkerVersion
.byte 0x14 @ MinorLinkerVersion
.long __pecoff_code_size @ SizeOfCode
.long __pecoff_data_size @ SizeOfInitializedData
.long 0 @ SizeOfUninitializedData
.long efi_pe_entry - start @ AddressOfEntryPoint
.long start_offset @ BaseOfCode
.long __pecoff_data_start - start @ BaseOfData
extra_header_fields:
.long 0 @ ImageBase
.long SZ_4K @ SectionAlignment
.long SZ_512 @ FileAlignment
.short 0 @ MajorOsVersion
.short 0 @ MinorOsVersion
.short LINUX_EFISTUB_MAJOR_VERSION @ MajorImageVersion
.short LINUX_EFISTUB_MINOR_VERSION @ MinorImageVersion
.short 0 @ MajorSubsystemVersion
.short 0 @ MinorSubsystemVersion
.long 0 @ Win32VersionValue
.long __pecoff_end - start @ SizeOfImage
.long start_offset @ SizeOfHeaders
.long 0 @ CheckSum
.short IMAGE_SUBSYSTEM_EFI_APPLICATION @ Subsystem
.short 0 @ DllCharacteristics
.long 0 @ SizeOfStackReserve
.long 0 @ SizeOfStackCommit
.long 0 @ SizeOfHeapReserve
.long 0 @ SizeOfHeapCommit
.long 0 @ LoaderFlags
.long (section_table - .) / 8 @ NumberOfRvaAndSizes
.quad 0 @ ExportTable
.quad 0 @ ImportTable
.quad 0 @ ResourceTable
.quad 0 @ ExceptionTable
.quad 0 @ CertificationTable
.quad 0 @ BaseRelocationTable
section_table:
.ascii ".text\0\0\0"
.long __pecoff_code_size @ VirtualSize
.long __efi_start @ VirtualAddress
.long __pecoff_code_size @ SizeOfRawData
.long __efi_start @ PointerToRawData
.long 0 @ PointerToRelocations
.long 0 @ PointerToLineNumbers
.short 0 @ NumberOfRelocations
.short 0 @ NumberOfLineNumbers
.long IMAGE_SCN_CNT_CODE | \
IMAGE_SCN_MEM_READ | \
IMAGE_SCN_MEM_EXECUTE @ Characteristics
.ascii ".data\0\0\0"
.long __pecoff_data_size @ VirtualSize
.long __pecoff_data_start - start @ VirtualAddress
.long __pecoff_data_rawsize @ SizeOfRawData
.long __pecoff_data_start - start @ PointerToRawData
.long 0 @ PointerToRelocations
.long 0 @ PointerToLineNumbers
.short 0 @ NumberOfRelocations
.short 0 @ NumberOfLineNumbers
.long IMAGE_SCN_CNT_INITIALIZED_DATA | \
IMAGE_SCN_MEM_READ | \
IMAGE_SCN_MEM_WRITE @ Characteristics
.set section_count, (. - section_table) / 40
.align 12
__efi_start:
#endif
.endm
@@ -0,0 +1,2 @@
// SPDX-License-Identifier: GPL-2.0-only
#include "../../../../lib/fdt.c"
@@ -0,0 +1,168 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/kernel.h>
#include <linux/libfdt.h>
#include <linux/sizes.h>
#include "misc.h"
static const void *get_prop(const void *fdt, const char *node_path,
const char *property, int minlen)
{
const void *prop;
int offset, len;
offset = fdt_path_offset(fdt, node_path);
if (offset < 0)
return NULL;
prop = fdt_getprop(fdt, offset, property, &len);
if (!prop || len < minlen)
return NULL;
return prop;
}
static uint32_t get_cells(const void *fdt, const char *name)
{
const fdt32_t *prop = get_prop(fdt, "/", name, sizeof(fdt32_t));
if (!prop) {
/* default */
return 1;
}
return fdt32_ld(prop);
}
static uint64_t get_val(const fdt32_t *cells, uint32_t ncells)
{
uint64_t r;
r = fdt32_ld(cells);
if (ncells > 1)
r = (r << 32) | fdt32_ld(cells + 1);
return r;
}
/*
* Check the start of physical memory
*
* Traditionally, the start address of physical memory is obtained by masking
* the program counter. However, this does require that this address is a
* multiple of 128 MiB, precluding booting Linux on platforms where this
* requirement is not fulfilled.
* Hence validate the calculated address against the memory information in the
* DTB, and, if out-of-range, replace it by the real start address.
* To preserve backwards compatibility (systems reserving a block of memory
* at the start of physical memory, kdump, ...), the traditional method is
* used if it yields a valid address, unless the "linux,usable-memory-range"
* property is present.
*
* Return value: start address of physical memory to use
*/
uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt)
{
uint32_t addr_cells, size_cells, usable_base, base;
uint32_t fdt_mem_start = 0xffffffff;
const fdt32_t *usable, *reg, *endp;
uint64_t size, usable_end, end;
const char *type;
int offset, len;
if (!fdt)
return mem_start;
if (fdt_magic(fdt) != FDT_MAGIC)
return mem_start;
/* There may be multiple cells on LPAE platforms */
addr_cells = get_cells(fdt, "#address-cells");
size_cells = get_cells(fdt, "#size-cells");
if (addr_cells > 2 || size_cells > 2)
return mem_start;
/*
* Usable memory in case of a crash dump kernel
* This property describes a limitation: memory within this range is
* only valid when also described through another mechanism
*/
usable = get_prop(fdt, "/chosen", "linux,usable-memory-range",
(addr_cells + size_cells) * sizeof(fdt32_t));
if (usable) {
size = get_val(usable + addr_cells, size_cells);
if (!size)
return mem_start;
if (addr_cells > 1 && fdt32_ld(usable)) {
/* Outside 32-bit address space */
return mem_start;
}
usable_base = fdt32_ld(usable + addr_cells - 1);
usable_end = usable_base + size;
}
/* Walk all memory nodes and regions */
for (offset = fdt_next_node(fdt, -1, NULL); offset >= 0;
offset = fdt_next_node(fdt, offset, NULL)) {
type = fdt_getprop(fdt, offset, "device_type", NULL);
if (!type || strcmp(type, "memory"))
continue;
reg = fdt_getprop(fdt, offset, "linux,usable-memory", &len);
if (!reg)
reg = fdt_getprop(fdt, offset, "reg", &len);
if (!reg)
continue;
for (endp = reg + (len / sizeof(fdt32_t));
endp - reg >= addr_cells + size_cells;
reg += addr_cells + size_cells) {
size = get_val(reg + addr_cells, size_cells);
if (!size)
continue;
if (addr_cells > 1 && fdt32_ld(reg)) {
/* Outside 32-bit address space, skipping */
continue;
}
base = fdt32_ld(reg + addr_cells - 1);
end = base + size;
if (usable) {
/*
* Clip to usable range, which takes precedence
* over mem_start
*/
if (base < usable_base)
base = usable_base;
if (end > usable_end)
end = usable_end;
if (end <= base)
continue;
} else if (mem_start >= base && mem_start < end) {
/* Calculated address is valid, use it */
return mem_start;
}
if (base < fdt_mem_start)
fdt_mem_start = base;
}
}
if (fdt_mem_start == 0xffffffff) {
/* No usable memory found, falling back to default */
return mem_start;
}
/*
* The calculated address is not usable, or was overridden by the
* "linux,usable-memory-range" property.
* Use the lowest usable physical memory address from the DTB instead,
* and make sure this is a multiple of 2 MiB for phys/virt patching.
*/
return round_up(fdt_mem_start, SZ_2M);
}
@@ -0,0 +1,2 @@
// SPDX-License-Identifier: GPL-2.0-only
#include "../../../../lib/fdt_ro.c"
@@ -0,0 +1,2 @@
// SPDX-License-Identifier: GPL-2.0-only
#include "../../../../lib/fdt_rw.c"
@@ -0,0 +1,2 @@
// SPDX-License-Identifier: GPL-2.0-only
#include "../../../../lib/fdt_wip.c"
@@ -0,0 +1,2 @@
// SPDX-License-Identifier: GPL-2.0-only
#include "../../../../lib/fonts/font_acorn_8x8.c"
@@ -0,0 +1,45 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* linux/arch/arm/boot/compressed/head-sa1100.S
*
* Copyright (C) 1999 Nicolas Pitre <nico@fluxnic.net>
*
* SA1100 specific tweaks. This is merged into head.S by the linker.
*
*/
#include <linux/linkage.h>
#include <asm/mach-types.h>
.section ".start", "ax"
.arch armv4
__SA1100_start:
@ Preserve r8/r7 i.e. kernel entry values
#ifdef CONFIG_SA1100_COLLIE
mov r7, #MACH_TYPE_COLLIE
#endif
mrc p15, 0, r0, c1, c0, 0 @ read control reg
ands r0, r0, #0x0d
beq 99f
@ Data cache might be active.
@ Be sure to flush kernel binary out of the cache,
@ whatever state it is, before it is turned off.
@ This is done by fetching through currently executed
@ memory to be sure we hit the same cache.
bic r2, pc, #0x1f
add r3, r2, #0x4000 @ 16 kb is quite enough...
1: ldr r0, [r2], #32
teq r2, r3
bne 1b
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches
@ disabling MMU and caches
mrc p15, 0, r0, c1, c0, 0 @ read control reg
bic r0, r0, #0x0d @ clear WB, DC, MMU
bic r0, r0, #0x1000 @ clear Icache
mcr p15, 0, r0, c1, c0, 0
99:
@@ -0,0 +1,151 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* linux/arch/arm/boot/compressed/head-sharpsl.S
*
* Copyright (C) 2004-2005 Richard Purdie <rpurdie@rpsys.net>
*
* Sharp's bootloader doesn't pass any kind of machine ID
* so we have to figure out the machine for ourselves...
*
* Support for Poodle, Corgi (SL-C700), Shepherd (SL-C750)
* Husky (SL-C760), Tosa (SL-C6000), Spitz (SL-C3000),
* Akita (SL-C1000) and Borzoi (SL-C3100).
*
*/
#include <linux/linkage.h>
#include <asm/mach-types.h>
#ifndef CONFIG_PXA_SHARPSL
#error What am I doing here...
#endif
.section ".start", "ax"
__SharpSL_start:
/* Check for TC6393 - if found we have a Tosa */
ldr r7, .TOSAID
mov r1, #0x10000000 @ Base address of TC6393 chip
mov r6, #0x03
ldrh r3, [r1, #8] @ Load TC6393XB Revison: This is 0x0003
cmp r6, r3
beq .SHARPEND @ Success -> tosa
/* Check for pxa270 - if found, branch */
mrc p15, 0, r4, c0, c0 @ Get Processor ID
and r4, r4, #0xffffff00
ldr r3, .PXA270ID
cmp r4, r3
beq .PXA270
/* Check for w100 - if not found we have a Poodle */
ldr r1, .W100ADDR @ Base address of w100 chip + regs offset
mov r6, #0x31 @ Load Magic Init value
str r6, [r1, #0x280] @ to SCRATCH_UMSK
mov r5, #0x3000
.W100LOOP:
subs r5, r5, #1
bne .W100LOOP
mov r6, #0x30 @ Load 2nd Magic Init value
str r6, [r1, #0x280] @ to SCRATCH_UMSK
ldr r6, [r1, #0] @ Load Chip ID
ldr r3, .W100ID
ldr r7, .POODLEID
cmp r6, r3
bne .SHARPEND @ We have no w100 - Poodle
/* Check for pxa250 - if found we have a Corgi */
ldr r7, .CORGIID
ldr r3, .PXA255ID
cmp r4, r3
blo .SHARPEND @ We have a PXA250 - Corgi
/* Check for 64MiB flash - if found we have a Shepherd */
bl get_flash_ids
ldr r7, .SHEPHERDID
cmp r3, #0x76 @ 64MiB flash
beq .SHARPEND @ We have Shepherd
/* Must be a Husky */
ldr r7, .HUSKYID @ Must be Husky
b .SHARPEND
.PXA270:
/* Check for 16MiB flash - if found we have Spitz */
bl get_flash_ids
ldr r7, .SPITZID
cmp r3, #0x73 @ 16MiB flash
beq .SHARPEND @ We have Spitz
/* Check for a second SCOOP chip - if found we have Borzoi */
ldr r1, .SCOOP2ADDR
ldr r7, .BORZOIID
mov r6, #0x0140
strh r6, [r1]
ldrh r6, [r1]
cmp r6, #0x0140
beq .SHARPEND @ We have Borzoi
/* Must be Akita */
ldr r7, .AKITAID
b .SHARPEND @ We have Borzoi
.PXA255ID:
.word 0x69052d00 @ PXA255 Processor ID
.PXA270ID:
.word 0x69054100 @ PXA270 Processor ID
.W100ID:
.word 0x57411002 @ w100 Chip ID
.W100ADDR:
.word 0x08010000 @ w100 Chip ID Reg Address
.SCOOP2ADDR:
.word 0x08800040
.POODLEID:
.word MACH_TYPE_POODLE
.CORGIID:
.word MACH_TYPE_CORGI
.SHEPHERDID:
.word MACH_TYPE_SHEPHERD
.HUSKYID:
.word MACH_TYPE_HUSKY
.TOSAID:
.word MACH_TYPE_TOSA
.SPITZID:
.word MACH_TYPE_SPITZ
.AKITAID:
.word MACH_TYPE_AKITA
.BORZOIID:
.word MACH_TYPE_BORZOI
/*
* Return: r2 - NAND Manufacturer ID
* r3 - NAND Chip ID
* Corrupts: r1
*/
get_flash_ids:
mov r1, #0x0c000000 @ Base address of NAND chip
ldrb r3, [r1, #24] @ Load FLASHCTL
bic r3, r3, #0x11 @ SET NCE
orr r3, r3, #0x0a @ SET CLR + FLWP
strb r3, [r1, #24] @ Save to FLASHCTL
mov r2, #0x90 @ Command "readid"
strb r2, [r1, #20] @ Save to FLASHIO
bic r3, r3, #2 @ CLR CLE
orr r3, r3, #4 @ SET ALE
strb r3, [r1, #24] @ Save to FLASHCTL
mov r2, #0 @ Address 0x00
strb r2, [r1, #20] @ Save to FLASHIO
bic r3, r3, #4 @ CLR ALE
strb r3, [r1, #24] @ Save to FLASHCTL
.fids1:
ldrb r3, [r1, #24] @ Load FLASHCTL
tst r3, #32 @ Is chip ready?
beq .fids1
ldrb r2, [r1, #20] @ NAND Manufacturer ID
ldrb r3, [r1, #20] @ NAND Chip ID
mov pc, lr
.SHARPEND:
@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* linux/arch/arm/boot/compressed/head-xscale.S
*
* XScale specific tweaks. This is merged into head.S by the linker.
*
*/
#include <linux/linkage.h>
.section ".start", "ax"
__XScale_start:
@ Preserve r8/r7 i.e. kernel entry values
@ Data cache might be active.
@ Be sure to flush kernel binary out of the cache,
@ whatever state it is, before it is turned off.
@ This is done by fetching through currently executed
@ memory to be sure we hit the same cache.
bic r2, pc, #0x1f
add r3, r2, #0x10000 @ 64 kb is quite enough...
1: ldr r0, [r2], #32
teq r2, r3
bne 1b
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches
@ disabling MMU and caches
mrc p15, 0, r0, c1, c0, 0 @ read control reg
bic r0, r0, #0x05 @ clear DC, MMU
bic r0, r0, #0x1000 @ clear Icache
mcr p15, 0, r0, c1, c0, 0
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,2 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include "../../kernel/hyp-stub.S"
@@ -0,0 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* For __aeabi_uidivmod */
#include "../../lib/lib1funcs.S"
@@ -0,0 +1,131 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* linux/arch/arm/lib/ll_char_wr.S
*
* Copyright (C) 1995, 1996 Russell King.
*
* Speedups & 1bpp code (C) 1996 Philip Blundell & Russell King.
*
* 10-04-96 RMK Various cleanups & reduced register usage.
* 08-04-98 RMK Shifts re-ordered
*/
@ Regs: [] = corruptible
@ {} = used
@ () = do not use
#include <linux/linkage.h>
#include <asm/assembler.h>
.text
LC0: .word LC0
.word bytes_per_char_h
.word video_size_row
.word acorndata_8x8
.word con_charconvtable
/*
* r0 = ptr
* r1 = char
* r2 = white
*/
ENTRY(ll_write_char)
stmfd sp!, {r4 - r7, lr}
@
@ Smashable regs: {r0 - r3}, [r4 - r7], (r8 - fp), [ip], (sp), [lr], (pc)
@
/*
* calculate offset into character table
*/
mov r1, r1, lsl #3
/*
* calculate offset required for each row.
*/
adr ip, LC0
ldmia ip, {r3, r4, r5, r6, lr}
sub ip, ip, r3
add r6, r6, ip
add lr, lr, ip
ldr r4, [r4, ip]
ldr r5, [r5, ip]
/*
* Go to resolution-dependent routine...
*/
cmp r4, #4
blt Lrow1bpp
add r0, r0, r5, lsl #3 @ Move to bottom of character
orr r1, r1, #7
ldrb r7, [r6, r1]
teq r4, #8
beq Lrow8bpplp
@
@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
@
Lrow4bpplp:
ldr r7, [lr, r7, lsl #2]
mul r7, r2, r7
sub r1, r1, #1 @ avoid using r7 directly after
str r7, [r0, -r5]!
ldrb r7, [r6, r1]
ldr r7, [lr, r7, lsl #2]
mul r7, r2, r7
tst r1, #7 @ avoid using r7 directly after
str r7, [r0, -r5]!
subne r1, r1, #1
ldrbne r7, [r6, r1]
bne Lrow4bpplp
ldmfd sp!, {r4 - r7, pc}
@
@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
@
Lrow8bpplp:
mov ip, r7, lsr #4
ldr ip, [lr, ip, lsl #2]
mul r4, r2, ip
and ip, r7, #15 @ avoid r4
ldr ip, [lr, ip, lsl #2] @ avoid r4
mul ip, r2, ip @ avoid r4
sub r1, r1, #1 @ avoid ip
sub r0, r0, r5 @ avoid ip
stmia r0, {r4, ip}
ldrb r7, [r6, r1]
mov ip, r7, lsr #4
ldr ip, [lr, ip, lsl #2]
mul r4, r2, ip
and ip, r7, #15 @ avoid r4
ldr ip, [lr, ip, lsl #2] @ avoid r4
mul ip, r2, ip @ avoid r4
tst r1, #7 @ avoid ip
sub r0, r0, r5 @ avoid ip
stmia r0, {r4, ip}
subne r1, r1, #1
ldrbne r7, [r6, r1]
bne Lrow8bpplp
ldmfd sp!, {r4 - r7, pc}
@
@ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc)
@
Lrow1bpp:
add r6, r6, r1
ldmia r6, {r4, r7}
strb r4, [r0], r5
mov r4, r4, lsr #8
strb r4, [r0], r5
mov r4, r4, lsr #8
strb r4, [r0], r5
mov r4, r4, lsr #8
strb r4, [r0], r5
strb r7, [r0], r5
mov r7, r7, lsr #8
strb r7, [r0], r5
mov r7, r7, lsr #8
strb r7, [r0], r5
mov r7, r7, lsr #8
strb r7, [r0], r5
ldmfd sp!, {r4 - r7, pc}
.bss
ENTRY(con_charconvtable)
.space 1024
@@ -0,0 +1,87 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
*/
/*
* These machine IDs are no longer used by the kernel since EP93xx was converted
* to DT booting, but they are still passed in by bootloaders, so we use our own
* local definitions of the relevant macros.
*/
#define machine_is_bk3() (__machine_arch_type == 1880)
#define machine_is_edb9301() (__machine_arch_type == 462)
#define machine_is_edb9302a() (__machine_arch_type == 1127)
#define machine_is_edb9302() (__machine_arch_type == 538)
#define machine_is_edb9307a() (__machine_arch_type == 1128)
#define machine_is_edb9307() (__machine_arch_type == 607)
#define machine_is_edb9312() (__machine_arch_type == 451)
#define machine_is_edb9315a() (__machine_arch_type == 772)
#define machine_is_edb9315() (__machine_arch_type == 463)
#define machine_is_ts72xx() (__machine_arch_type == 673)
#define machine_is_vision_ep9307() (__machine_arch_type == 1578)
static inline unsigned int __raw_readl(unsigned int ptr)
{
return *((volatile unsigned int *)ptr);
}
static inline void __raw_writeb(unsigned char value, unsigned int ptr)
{
*((volatile unsigned char *)ptr) = value;
}
static inline void __raw_writel(unsigned int value, unsigned int ptr)
{
*((volatile unsigned int *)ptr) = value;
}
/*
* Some bootloaders don't turn off DMA from the ethernet MAC before
* jumping to linux, which means that we might end up with bits of RX
* status and packet data scribbled over the uncompressed kernel image.
* Work around this by resetting the ethernet MAC before we uncompress.
*/
#define PHYS_ETH_SELF_CTL 0x80010020
#define ETH_SELF_CTL_RESET 0x00000001
static inline void ep93xx_ethernet_reset(void)
{
unsigned int v;
/* Reset the ethernet MAC. */
v = __raw_readl(PHYS_ETH_SELF_CTL);
__raw_writel(v | ETH_SELF_CTL_RESET, PHYS_ETH_SELF_CTL);
/* Wait for reset to finish. */
while (__raw_readl(PHYS_ETH_SELF_CTL) & ETH_SELF_CTL_RESET)
;
}
#define TS72XX_WDT_CONTROL_PHYS_BASE 0x23800000
#define TS72XX_WDT_FEED_PHYS_BASE 0x23c00000
#define TS72XX_WDT_FEED_VAL 0x05
static inline void __maybe_unused ts72xx_watchdog_disable(void)
{
__raw_writeb(TS72XX_WDT_FEED_VAL, TS72XX_WDT_FEED_PHYS_BASE);
__raw_writeb(0, TS72XX_WDT_CONTROL_PHYS_BASE);
}
static inline void ep93xx_decomp_setup(void)
{
if (machine_is_ts72xx())
ts72xx_watchdog_disable();
if (machine_is_edb9301() ||
machine_is_edb9302() ||
machine_is_edb9302a() ||
machine_is_edb9307() ||
machine_is_edb9307a() ||
machine_is_edb9312() ||
machine_is_edb9315() ||
machine_is_edb9315a() ||
machine_is_ts72xx() ||
machine_is_bk3() ||
machine_is_vision_ep9307())
ep93xx_ethernet_reset();
}
+160
View File
@@ -0,0 +1,160 @@
// SPDX-License-Identifier: GPL-2.0
/*
* misc.c
*
* This is a collection of several routines from gzip-1.0.3
* adapted for Linux.
*
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
*
* Modified for ARM Linux by Russell King
*
* Nicolas Pitre <nico@visuaide.com> 1999/04/14 :
* For this code to run directly from Flash, all constant variables must
* be marked with 'const' and all other variables initialized at run-time
* only. This way all non constant variables will end up in the bss segment,
* which should point to addresses in RAM and cleared to 0 on start.
* This allows for a much quicker boot time.
*/
unsigned int __machine_arch_type;
#include <linux/compiler.h> /* for inline */
#include <linux/types.h>
#include <linux/linkage.h>
#include "misc.h"
#ifdef CONFIG_ARCH_EP93XX
#include "misc-ep93xx.h"
#endif
static void putstr(const char *ptr);
#include CONFIG_UNCOMPRESS_INCLUDE
#ifdef CONFIG_DEBUG_ICEDCC
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
static void icedcc_putc(int ch)
{
int status, i = 0x4000000;
do {
if (--i < 0)
return;
asm volatile ("mrc p14, 0, %0, c0, c1, 0" : "=r" (status));
} while (status & (1 << 29));
asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
}
#elif defined(CONFIG_CPU_XSCALE)
static void icedcc_putc(int ch)
{
int status, i = 0x4000000;
do {
if (--i < 0)
return;
asm volatile ("mrc p14, 0, %0, c14, c0, 0" : "=r" (status));
} while (status & (1 << 28));
asm("mcr p14, 0, %0, c8, c0, 0" : : "r" (ch));
}
#else
static void icedcc_putc(int ch)
{
int status, i = 0x4000000;
do {
if (--i < 0)
return;
asm volatile ("mrc p14, 0, %0, c0, c0, 0" : "=r" (status));
} while (status & 2);
asm("mcr p14, 0, %0, c1, c0, 0" : : "r" (ch));
}
#endif
#define putc(ch) icedcc_putc(ch)
#endif
static void putstr(const char *ptr)
{
char c;
while ((c = *ptr++) != '\0') {
if (c == '\n')
putc('\r');
putc(c);
}
flush();
}
/*
* gzip declarations
*/
unsigned char *output_data;
unsigned long free_mem_ptr;
unsigned long free_mem_end_ptr;
#ifndef arch_error
#define arch_error(x)
#endif
void error(char *x)
{
arch_error(x);
putstr("\n\n");
putstr(x);
putstr("\n\n -- System halted");
while(1); /* Halt */
}
asmlinkage void __div0(void)
{
error("Attempting division by 0!");
}
void
decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
unsigned long free_mem_ptr_end_p,
int arch_id)
{
int ret;
output_data = (unsigned char *)output_start;
free_mem_ptr = free_mem_ptr_p;
free_mem_end_ptr = free_mem_ptr_end_p;
__machine_arch_type = arch_id;
#ifdef CONFIG_ARCH_EP93XX
ep93xx_decomp_setup();
#endif
arch_decomp_setup();
putstr("Uncompressing Linux...");
ret = do_decompress(input_data, input_data_end - input_data,
output_data, error);
if (ret)
error("decompressor returned an error");
else
putstr(" done, booting the kernel.\n");
}
void __fortify_panic(const u8 reason, size_t avail, size_t size)
{
error("detected buffer overflow");
}
@@ -0,0 +1,21 @@
#ifndef MISC_H
#define MISC_H
#include <linux/compiler.h>
void error(char *x) __noreturn;
extern unsigned long free_mem_ptr;
extern unsigned long free_mem_end_ptr;
void __div0(void);
void
decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
unsigned long free_mem_ptr_end_p, int arch_id);
void __fortify_panic(const u8 reason, size_t avail, size_t size);
int atags_to_fdt(void *atag_list, void *fdt, int total_space);
uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt);
int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
extern char input_data[];
extern char input_data_end[];
#endif
@@ -0,0 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
.section .piggydata, "a"
.globl input_data
input_data:
.incbin "arch/arm/boot/compressed/piggy_data"
.globl input_data_end
input_data_end:
@@ -0,0 +1,162 @@
// SPDX-License-Identifier: GPL-2.0
/*
* arch/arm/boot/compressed/string.c
*
* Small subset of simple string routines
*/
#define __NO_FORTIFY
#include <linux/string.h>
/*
* The decompressor is built without KASan but uses the same redirects as the
* rest of the kernel when CONFIG_KASAN is enabled, defining e.g. memcpy()
* to __memcpy() but since we are not linking with the main kernel string
* library in the decompressor, that will lead to link failures.
*
* Undefine KASan's versions, define the wrapped functions and alias them to
* the right names so that when e.g. __memcpy() appear in the code, it will
* still be linked to this local version of memcpy().
*/
#ifdef CONFIG_KASAN
#undef memcpy
#undef memmove
#undef memset
void *__memcpy(void *__dest, __const void *__src, size_t __n) __alias(memcpy);
void *__memmove(void *__dest, __const void *__src, size_t count) __alias(memmove);
void *__memset(void *s, int c, size_t count) __alias(memset);
#endif
void *memcpy(void *__dest, __const void *__src, size_t __n)
{
int i = 0;
unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
for (i = __n >> 3; i > 0; i--) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (__n & 1 << 2) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (__n & 1 << 1) {
*d++ = *s++;
*d++ = *s++;
}
if (__n & 1)
*d++ = *s++;
return __dest;
}
void *memmove(void *__dest, __const void *__src, size_t count)
{
unsigned char *d = __dest;
const unsigned char *s = __src;
if (__dest == __src)
return __dest;
if (__dest < __src)
return memcpy(__dest, __src, count);
while (count--)
d[count] = s[count];
return __dest;
}
size_t strlen(const char *s)
{
const char *sc = s;
while (*sc != '\0')
sc++;
return sc - s;
}
size_t strnlen(const char *s, size_t count)
{
const char *sc;
for (sc = s; count-- && *sc != '\0'; ++sc)
/* nothing */;
return sc - s;
}
int memcmp(const void *cs, const void *ct, size_t count)
{
const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count;
int res = 0;
while (su1 < end) {
res = *su1++ - *su2++;
if (res)
break;
}
return res;
}
int strcmp(const char *cs, const char *ct)
{
unsigned char c1, c2;
int res = 0;
do {
c1 = *cs++;
c2 = *ct++;
res = c1 - c2;
if (res)
break;
} while (c1);
return res;
}
void *memchr(const void *s, int c, size_t count)
{
const unsigned char *p = s;
while (count--)
if ((unsigned char)c == *p++)
return (void *)(p - 1);
return NULL;
}
char *strchr(const char *s, int c)
{
while (*s != (char)c)
if (*s++ == '\0')
return NULL;
return (char *)s;
}
char *strrchr(const char *s, int c)
{
const char *last = NULL;
do {
if (*s == (char)c)
last = s;
} while (*s++);
return (char *)last;
}
#undef memset
void *memset(void *s, int c, size_t count)
{
char *xs = s;
while (count--)
*xs++ = c;
return s;
}
@@ -0,0 +1,144 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2000 Russell King
*/
#include <asm/vmlinux.lds.h>
#ifdef CONFIG_CPU_ENDIAN_BE8
#define ZIMAGE_MAGIC(x) ( (((x) >> 24) & 0x000000ff) | \
(((x) >> 8) & 0x0000ff00) | \
(((x) << 8) & 0x00ff0000) | \
(((x) << 24) & 0xff000000) )
#else
#define ZIMAGE_MAGIC(x) (x)
#endif
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
/DISCARD/ : {
COMMON_DISCARDS
*(.ARM.exidx*)
*(.ARM.extab*)
*(.modinfo)
*(.note.*)
*(.rel.*)
*(.printk_index)
/*
* Discard any r/w data - this produces a link error if we have any,
* which is required for PIC decompression. Local data generates
* GOTOFF relocations, which prevents it being relocated independently
* of the text/got segments.
*/
*(.data)
}
. = TEXT_START;
_text = .;
.text : {
_start = .;
*(.start)
*(.text)
*(.text.*)
ARM_STUBS_TEXT
}
.table : ALIGN(4) {
_table_start = .;
LONG(ZIMAGE_MAGIC(6))
LONG(ZIMAGE_MAGIC(0x5a534c4b))
LONG(ZIMAGE_MAGIC(__piggy_size_addr - _start))
LONG(ZIMAGE_MAGIC(_kernel_bss_size))
LONG(ZIMAGE_MAGIC(TEXT_OFFSET))
LONG(ZIMAGE_MAGIC(MALLOC_SIZE))
LONG(0)
_table_end = .;
}
.rodata : {
*(.rodata)
*(.rodata.*)
*(.data.rel.ro)
*(.data.rel.ro.*)
}
.piggydata : {
*(.piggydata)
__piggy_size_addr = . - 4;
}
. = ALIGN(4);
_etext = .;
.got.plt : { *(.got.plt) }
#ifndef CONFIG_EFI_STUB
_got_start = .;
.got : { *(.got) }
_got_end = .;
#endif
/* ensure the zImage file size is always a multiple of 64 bits */
/* (without a dummy byte, ld just ignores the empty section) */
.pad : { BYTE(0); . = ALIGN(8); }
#ifdef CONFIG_EFI_STUB
.data : ALIGN(4096) {
__pecoff_data_start = .;
_got_start = .;
*(.got)
_got_end = .;
/*
* The EFI stub always executes from RAM, and runs strictly before the
* decompressor, so we can make an exception for its r/w data, and keep it
*/
*(.data.efistub .bss.efistub)
__pecoff_data_end = .;
/*
* PE/COFF mandates a file size which is a multiple of 512 bytes if the
* section size equals or exceeds 4 KB
*/
. = ALIGN(512);
}
__pecoff_data_rawsize = . - ADDR(.data);
#endif
_edata = .;
/*
* The image_end section appears after any additional loadable sections
* that the linker may decide to insert in the binary image. Having
* this symbol allows further debug in the near future.
*/
.image_end (NOLOAD) : {
/*
* EFI requires that the image is aligned to 512 bytes, and appended
* DTB requires that we know where the end of the image is. Ensure
* that both are satisfied by ensuring that there are no additional
* sections emitted into the decompressor image.
*/
_edata_real = .;
}
_magic_sig = ZIMAGE_MAGIC(0x016f2818);
_magic_start = ZIMAGE_MAGIC(_start);
_magic_end = ZIMAGE_MAGIC(_edata);
_magic_table = ZIMAGE_MAGIC(_table_start - _start);
. = BSS_START;
__bss_start = .;
.bss : { *(.bss .bss.*) }
_end = .;
. = ALIGN(8); /* the stack must be 64-bit aligned */
.stack : { *(.stack) }
PROVIDE(__pecoff_data_size = ALIGN(512) - ADDR(.data));
PROVIDE(__pecoff_end = ALIGN(512));
STABS_DEBUG
DWARF_DEBUG
ARM_DETAILS
ARM_ASSERTS
}
ASSERT(_edata_real == _edata, "error: zImage file size is incorrect");