mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-11 07:34:31 +00:00
bootstage: Correct relocation algorithm
At present bootstage relocation assumes that it is possible to point back to memory available before relocation, so it does not relocate the strings. However this is not the case on some platforms, such as x86 which uses the cache as RAM and loses access to this when the cache is enabled. Move the relocation step to before U-Boot relocates, expand the allocated region to include space for the strings and relocate the strings at the same time as the bootstage records. This ensures that bootstage data can remain accessible from TPL through SPL to U-Boot before/after relocation. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
65b2d96f4c
commit
ac9cd4805c
3 changed files with 23 additions and 4 deletions
|
@ -696,6 +696,7 @@ static int reloc_bootstage(void)
|
|||
gd->bootstage, gd->new_bootstage, size);
|
||||
memcpy(gd->new_bootstage, gd->bootstage, size);
|
||||
gd->bootstage = gd->new_bootstage;
|
||||
bootstage_relocate();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -670,7 +670,6 @@ static init_fnc_t init_sequence_r[] = {
|
|||
#ifdef CONFIG_SYS_NONCACHED_MEMORY
|
||||
initr_noncached,
|
||||
#endif
|
||||
bootstage_relocate,
|
||||
#ifdef CONFIG_OF_LIVE
|
||||
initr_of_live,
|
||||
#endif
|
||||
|
|
|
@ -53,14 +53,23 @@ int bootstage_relocate(void)
|
|||
{
|
||||
struct bootstage_data *data = gd->bootstage;
|
||||
int i;
|
||||
char *ptr;
|
||||
|
||||
/* Figure out where to relocate the strings to */
|
||||
ptr = (char *)(data + 1);
|
||||
|
||||
/*
|
||||
* Duplicate all strings. They may point to an old location in the
|
||||
* program .text section that can eventually get trashed.
|
||||
*/
|
||||
debug("Relocating %d records\n", data->rec_count);
|
||||
for (i = 0; i < data->rec_count; i++)
|
||||
data->record[i].name = strdup(data->record[i].name);
|
||||
for (i = 0; i < data->rec_count; i++) {
|
||||
const char *from = data->record[i].name;
|
||||
|
||||
strcpy(ptr, from);
|
||||
data->record[i].name = ptr;
|
||||
ptr += strlen(ptr) + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -490,7 +499,17 @@ int bootstage_unstash(const void *base, int size)
|
|||
|
||||
int bootstage_get_size(void)
|
||||
{
|
||||
return sizeof(struct bootstage_data);
|
||||
struct bootstage_data *data = gd->bootstage;
|
||||
struct bootstage_record *rec;
|
||||
int size;
|
||||
int i;
|
||||
|
||||
size = sizeof(struct bootstage_data);
|
||||
for (rec = data->record, i = 0; i < data->rec_count;
|
||||
i++, rec++)
|
||||
size += strlen(rec->name) + 1;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int bootstage_init(bool first)
|
||||
|
|
Loading…
Reference in a new issue