AARCH64: Allow for embedding an initramfs

This actually breaks the armv7 port. It has to be revisited in the
future, since it not only is not compilable right now, but also
cannot boot linux properly. TODO

Also introduce a new C-based __memcpy_optimized that does not
cause an exception on some devices when copying the initramfs.
This issue has to be debugged further.

Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
This commit is contained in:
Ivaylo Ivanov 2024-10-12 19:39:11 +03:00
parent 2de1d3c549
commit 9c60b66f71
10 changed files with 71 additions and 4 deletions

1
.gitignore vendored
View File

@ -18,3 +18,4 @@ boot.img
blob/Image
blob/dtb
drivers/*.a
blob/ramdisk

View File

@ -36,6 +36,13 @@ menu "Building options"
default blob/dtb
help
Path to the device tree, which is going to get embedded to uniLoader
config RAMDISK_PATH
string "Path to ramdisk image"
depends on EMBED_LINUX
default blob/ramdisk
help
Path to the ramdisk, which is going to get embedded to uniLoader
endmenu
source "lib/Kconfig"

View File

@ -103,6 +103,7 @@ export srctree objtree VPATH
CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
KERNEL_PATH ?= $(CONFIG_KERNEL_PATH:"%"=%)
DT_PATH ?= $(CONFIG_DT_PATH:"%"=%)
RAMDISK_PATH ?= $(CONFIG_RAMDISK_PATH:"%"=%)
TEXT_BASE ?= $(CONFIG_TEXT_BASE:"%"=%)
KCONFIG_CONFIG ?= .config
@ -371,8 +372,8 @@ uniLoader-all := $(uniLoader-objs) $(uniLoader-libs)
quiet_cmd_uniLoader = LD $@.o
cmd_uniLoader = $(LD) $(main-y) $(arch-libs-y) $(uniLoader-libs) -o $@.o --script=arch/$(ARCH)/linker.lds
arch/$(ARCH)/linker.lds: arch/$(ARCH)/linker.lds.S $(KERNEL_PATH)
$(CPP) $< -DTEXT_BASE=$(TEXT_BASE) -DKERNEL_PATH=$(KERNEL_PATH) -DDTB_PATH=$(DT_PATH) -P -o $@
arch/$(ARCH)/linker.lds: arch/$(ARCH)/linker.lds.S $(KERNEL_PATH) $(RAMDISK_PATH)
$(CPP) $< -DTEXT_BASE=$(TEXT_BASE) -DKERNEL_PATH=$(KERNEL_PATH) -DDTB_PATH=$(DT_PATH) -DRAMDISK_PATH=$(RAMDISK_PATH) -P -o $@
uniLoader: $(uniLoader-all)
$(call if_changed,uniLoader)

View File

@ -9,6 +9,7 @@ TARGET(binary)
INPUT(KERNEL_PATH)
INPUT(DTB_PATH)
INPUT(RAMDISK_PATH)
SECTIONS
{
@ -41,5 +42,11 @@ SECTIONS
KERNEL_PATH
}
.ramdisk ALIGN(4096) : {
ramdisk = .;
RAMDISK_PATH
}
kernel_size = SIZEOF(.kernel);
ramdisk_size = SIZEOF(.ramdisk);
}

View File

@ -18,6 +18,8 @@ ENTRY(_start)
add x0, x0, #:lo12:dtb /* Add offset within the page */
adrp x1, kernel /* Load page of kernel */
add x1, x1, #:lo12:kernel /* Add offset within the page */
adrp x2, ramdisk /* Load page of kernel */
add x2, x2, #:lo12:ramdisk /* Add offset within the page */
bl main
END(_start)

0
blob/ramdisk Normal file
View File

View File

@ -97,6 +97,10 @@ menu "Device Specific Addresses"
default 0x090000000 if SAMSUNG_J5LTE
default 0x090000000 if SAMSUNG_GTA4XL
config RAMDISK_ENTRY
hex "Ramdisk Entry Address"
default 0x082000000 if SAMSUNG_DREAMLTE
config FRAMEBUFFER_BASE
hex "Framebuffer Base Address (for SimpleFB)"
depends on SIMPLE_FB

View File

@ -9,6 +9,7 @@
#define MAIN_H_
extern unsigned long kernel_size;
extern unsigned long ramdisk_size;
extern void load_kernel(void* dtb, void* x1, void* x2, void* x3, void* kernel);
extern void soc_init(void);

View File

@ -9,7 +9,7 @@
#include "stddef.h"
#define LBLOCKSIZE (sizeof(long))
#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
// C-driven unoptimized functions
@ -30,6 +30,49 @@ void writel (unsigned int value, void* address);
// C-driven optimized functions
void *memset (void *m, int c, size_t n);
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
#define UNALIGNED_CPY(X, Y) (((long)X & (sizeof (long) - 1)) | \
((long)Y & (sizeof (long) - 1)))
/* How many bytes are copied each iteration of the 4X unrolled loop. */
#define BIGBLOCKSIZE (sizeof(long) << 2)
static void *__optimized_memcpy (void *dst0, const void *src0, size_t len0)
{
char *dst = dst0;
const char *src = src0;
long *aligned_dst;
const long *aligned_src;
/* If the size is small, or either SRC or DST is unaligned,
then punt into the byte copy loop. This should be rare. */
if (!(((len0) < BIGBLOCKSIZE)) && !UNALIGNED_CPY (src, dst)) {
aligned_dst = (long*)dst;
aligned_src = (long*)src;
/* Copy 4X long words at a time if possible. */
while (len0 >= BIGBLOCKSIZE) {
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
len0 -= BIGBLOCKSIZE;
}
/* Copy one long word at a time if possible. */
while (len0 >= LBLOCKSIZE) {
*aligned_dst++ = *aligned_src++;
len0 -= LBLOCKSIZE;
}
/* Pick up any residual with a byte copier. */
dst = (char*)aligned_dst;
src = (char*)aligned_src;
}
while (len0--)
*dst++ = *src++;
return dst0;
}
// Assembly-driven functions
#ifdef __aarch64__
void *memcpy (void *__restrict, const void *__restrict, size_t);

View File

@ -23,7 +23,7 @@ struct board_data board = {
}
};
void main(void* dt, void* kernel)
void main(void* dt, void* kernel, void* ramdisk)
{
/* Initialize SoC and Board specific peripherals/quirks */
init_board_funcs(&board);
@ -46,6 +46,7 @@ void main(void* dt, void* kernel)
printk(-1, "Booting linux...\n");
memcpy((void*)CONFIG_PAYLOAD_ENTRY, kernel, (unsigned long) &kernel_size);
__optimized_memcpy((void*)CONFIG_RAMDISK_ENTRY, ramdisk, (unsigned long) &ramdisk_size);
load_kernel(dt, 0, 0, 0, (void*)CONFIG_PAYLOAD_ENTRY);
/* We shouldn't get there */