Skip to content

Support for fit image #185

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion Config.in.kernel
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,18 @@ config OF_ADDRESS
default "0x61000000" if SAMA7G5
default "0x21000000"


endmenu

config IMG_FIT
depends on LOAD_LINUX && (NANDFLASH || DATAFLASH)
select OF_LIBFDT
bool "Support loading a FIT image"
help
A FIT image is a container. It usualy contains the kernel, one or more DTB,
and optionnaly a initramfs. It also specifies where each of those images must
be loaded in memory.
The FIT image is loaded in memory at the address defined by IMG_ADDRESS. Care must
taken to select this address so that it does not overlap with the adresses specified
in the FIT.

endmenu
95 changes: 67 additions & 28 deletions driver/load_kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,22 @@

#include "debug.h"

#ifdef CONFIG_MMU
#include "mmu.h"
#endif

#ifdef CONFIG_CACHES
#include "l1cache.h"
#endif

static char cmdline_buf[256];
static char *bootargs;

#ifdef CONFIG_OF_LIBFDT

static int setup_dt_blob(void *blob)
static int setup_dt_blob(void *blob, struct image_info *image)
{
char *bootargs_start = NULL;
int ret;
#if !defined(CONFIG_LOAD_OPTEE)
unsigned int mem_bank = AT91C_BASE_DDRCS;
Expand Down Expand Up @@ -63,11 +72,13 @@ static int setup_dt_blob(void *blob)
if (*p == '\0')
return -1;

ret = fixup_chosen_node(blob, p);
if (ret)
return ret;
bootargs_start = p;
}

ret = fixup_chosen_node(blob, bootargs_start, image);
if (ret)
return ret;

/*
* When using OP-TEE the memory node should match the configuration of the DDR
* that has been secured. Since this can't easily be inferred from
Expand Down Expand Up @@ -362,6 +373,7 @@ int load_kernel(struct image_info *image)
unsigned int mach_type;
int ret;
unsigned int mem_size;
const char *mem_size_str = NULL;

#if defined(CONFIG_SDRAM)
mem_size = get_sdram_size();
Expand All @@ -373,60 +385,80 @@ int load_kernel(struct image_info *image)

void (*kernel_entry)(int zero, int arch, unsigned int params);

bootargs = board_override_cmd_line();
if (sizeof(cmdline_buf) < 10 + strlen(bootargs)){
dbg_very_loud("\nKERNEL: buffer for bootargs is too small\n\n");
return -1;
}
switch(mem_size){
case 0x800000:
memcpy(cmdline_buf, "mem=8M ", 7);
memcpy(&cmdline_buf[7], bootargs, strlen(bootargs));
mem_size_str = "mem=8M";
break;
case 0x1000000:
memcpy(cmdline_buf, "mem=16M ", 8);
memcpy(&cmdline_buf[8], bootargs, strlen(bootargs));
mem_size_str = "mem=16M";
break;
case 0x2000000:
memcpy(cmdline_buf, "mem=32M ", 8);
memcpy(&cmdline_buf[8], bootargs, strlen(bootargs));
mem_size_str = "mem=32M";
break;
case 0x4000000:
memcpy(cmdline_buf, "mem=64M ", 8);
memcpy(&cmdline_buf[8], bootargs, strlen(bootargs));
mem_size_str = "mem=64M";
break;
case 0x8000000:
memcpy(cmdline_buf, "mem=128M ", 9);
memcpy(&cmdline_buf[9], bootargs, strlen(bootargs));
mem_size_str = "mem=128M";
break;
case 0x10000000:
memcpy(cmdline_buf, "mem=256M ", 9);
memcpy(&cmdline_buf[9], bootargs, strlen(bootargs));
mem_size_str = "mem=256M";
break;
case 0x20000000:
memcpy(cmdline_buf, "mem=512M ", 9);
memcpy(&cmdline_buf[9], bootargs, strlen(bootargs));
mem_size_str = "mem=512M";
break;
default:
dbg_very_loud("\nKERNEL: bootargs incorrect due to the memory size is not a multiple of MB\n\n");
break;
}
bootargs = cmdline_buf;

ret = load_kernel_image(image);
if (ret)
return ret;

#ifdef CONFIG_OVERRIDE_CMDLINE_FROM_EXT_FILE
bootargs = board_override_cmd_line_ext(image->cmdline_args);
#endif
#if defined(CONFIG_SECURE)
ret = secure_check(image->dest);
if (ret)
return ret;
image->dest += sizeof(at91_secure_header_t);
#endif

#ifdef CONFIG_IMG_FIT
if (!check_dt_blob_valid(image->dest))
deploy_fit_image(image->dest, image, NULL);
#endif

int total_bootargs_sz;
const char *base_bootargs;

base_bootargs = board_override_cmd_line();
if (strlen(base_bootargs) == 0) {
/* look for bootargs in the DT */
base_bootargs = bootargs_from_dt(image->of_dest);
if (base_bootargs)
dbg_loud("Using bootargs from the device-tree\n");
}

total_bootargs_sz = (mem_size_str ? strlen(mem_size_str) + 1 /* for the separator ' ' */ : 0) +
(base_bootargs ? strlen(base_bootargs) : 0) + 1 /* for the terminal '\0' */;

if (sizeof(cmdline_buf) < total_bootargs_sz ){
dbg_info("\nKERNEL: buffer for bootargs is too small\n\n");
return -1;
}

if (mem_size_str)
strcpy(cmdline_buf, mem_size_str);
if (strlen(base_bootargs)) {
strcat(cmdline_buf, " ");
strcat(cmdline_buf, base_bootargs);
}
bootargs = cmdline_buf;

#ifdef CONFIG_OVERRIDE_CMDLINE_FROM_EXT_FILE
bootargs = board_override_cmd_line_ext(image->cmdline_args);
#endif

#ifdef CONFIG_SCLK
slowclk_switch_osc32();
#endif
Expand All @@ -441,7 +473,7 @@ int load_kernel(struct image_info *image)
kernel_entry = (void (*)(int, int, unsigned int))entry_point;

#ifdef CONFIG_OF_LIBFDT
ret = setup_dt_blob((char *)image->of_dest);
ret = setup_dt_blob((char *)image->of_dest, image);
if (ret)
return ret;

Expand All @@ -454,6 +486,13 @@ int load_kernel(struct image_info *image)
r2 = (unsigned int)(AT91C_BASE_DDRCS + 0x100);
#endif

#ifdef CONFIG_CACHES
dcache_disable();
#endif
#ifdef CONFIG_MMU
mmu_disable();
#endif

dbg_info("\nKERNEL: Starting linux kernel ..., machid: %x\n\n",
mach_type);
#if defined(CONFIG_ENTER_NWD)
Expand Down
18 changes: 17 additions & 1 deletion driver/nandflash.c
Original file line number Diff line number Diff line change
Expand Up @@ -1362,6 +1362,9 @@ static int update_image_length(struct nand_info *nand,

int load_nandflash(struct image_info *image)
{
#if defined(CONFIG_LOAD_LINUX) || defined(CONFIG_LOAD_ANDROID)
int length;
#endif
struct nand_info nand;
int ret;

Expand All @@ -1384,8 +1387,21 @@ int load_nandflash(struct image_info *image)
dbg_info("NAND: Using Software ECC\n");
#endif

#ifdef CONFIG_IMG_FIT
length = update_image_length(&nand,
image->offset, image->dest, DT_BLOB);
if (length > 0) {
image->length = length;

dbg_info("NAND: FIT image: Loading %x bytes from %x to %x\n",
image->length, image->offset, image->dest);

return nand_loadimage(&nand, image->offset, image->length, image->dest);
}
#endif

#if defined(CONFIG_LOAD_LINUX) || defined(CONFIG_LOAD_ANDROID)
int length = update_image_length(&nand,
length = update_image_length(&nand,
image->offset, image->dest, KERNEL_IMAGE);
if (length == -1)
return -1;
Expand Down
21 changes: 21 additions & 0 deletions driver/spi_flash/spi_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,27 @@ int spi_flash_loadimage(struct spi_flash *flash, struct image_info *image)
return 0;
#else /* CONFIG_QSPI_XIP */

#ifdef CONFIG_IMG_FIT
length = update_image_length(flash,
image->offset, image->dest, DT_BLOB);
if (length > 0) {
image->length = length;

dbg_info("SF: Copy FIT %x bytes from %x to %x\n",
image->length, image->offset, image->dest);

ret = spi_flash_read(flash,
image->offset,
image->length,
image->dest);
if (ret) {
dbg_info("** SF: Serial flash read error**\n");
ret = -1;
goto err_exit;
}
}
#endif

#if defined(CONFIG_LOAD_LINUX) || defined(CONFIG_LOAD_ANDROID)
length = update_image_length(flash,
image->offset,
Expand Down
2 changes: 2 additions & 0 deletions include/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ struct image_info
unsigned int of_offset;
unsigned int of_length;
#endif
void *initrd_dest;
unsigned int initrd_length;
#ifdef CONFIG_SDCARD
char *of_filename;
#endif
Expand Down
4 changes: 3 additions & 1 deletion include/fdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
#ifndef __FDT_H__
#define __FDT_H__

extern const char *bootargs_from_dt(void *blob);
extern int deploy_fit_image(void *blob, struct image_info *image, const char *configuration_name);
extern unsigned int of_get_dt_total_size(void *blob);
extern int check_dt_blob_valid(void *blob);
extern int fixup_chosen_node(void *blob, char *bootargs);
extern int fixup_chosen_node(void *blob, char *bootargs, struct image_info *image);
extern int fixup_memory_node(void *blob,
unsigned int *mem_bank,
unsigned int *mem_bank2,
Expand Down
Loading