Skip to content

Commit

Permalink
AARCH64: Allow for embedding an initramfs
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
ivoszbg committed Oct 12, 2024
1 parent 2de1d3c commit 9c60b66
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ boot.img
blob/Image
blob/dtb
drivers/*.a
blob/ramdisk
7 changes: 7 additions & 0 deletions Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions arch/aarch64/linker.lds.S
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ TARGET(binary)

INPUT(KERNEL_PATH)
INPUT(DTB_PATH)
INPUT(RAMDISK_PATH)

SECTIONS
{
Expand Down Expand Up @@ -41,5 +42,11 @@ SECTIONS
KERNEL_PATH
}

.ramdisk ALIGN(4096) : {
ramdisk = .;
RAMDISK_PATH
}

kernel_size = SIZEOF(.kernel);
ramdisk_size = SIZEOF(.ramdisk);
}
2 changes: 2 additions & 0 deletions arch/aarch64/start.S
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Empty file added blob/ramdisk
Empty file.
4 changes: 4 additions & 0 deletions board/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions include/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
45 changes: 44 additions & 1 deletion lib/unic/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);

This comment has been minimized.

Copy link
@ivoszbg

ivoszbg Oct 12, 2024

Author Owner

Idea for the future - could avoid memcpy'ing the ramdisk entirely, since when we get libfdt added, we could dynamically find the address of the ramdisk and pass it via bootargs

load_kernel(dt, 0, 0, 0, (void*)CONFIG_PAYLOAD_ENTRY);

/* We shouldn't get there */
Expand Down

0 comments on commit 9c60b66

Please sign in to comment.