mirror of
https://github.com/meizu-m86/kexec-tools-arm64
synced 2025-11-04 05:46:10 +08:00
Revert "arm64: add support for appended dtb (Squashed)"
This reverts commit bb982d67c1.
This commit is contained in:
@@ -328,190 +328,14 @@ static int read_sys_dtb(struct dtb *dtb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DTB_PAD_SIZE 1024
|
||||
#define INVALID_SOC_REV_ID 0xFFFFFFFF
|
||||
|
||||
struct msm_id
|
||||
{
|
||||
uint32_t platform_id;
|
||||
uint32_t hardware_id;
|
||||
uint32_t soc_rev;
|
||||
};
|
||||
|
||||
static uint32_t dtb_compatible(void *dtb, struct msm_id *devid)
|
||||
{
|
||||
int root_offset;
|
||||
const void *prop;
|
||||
struct msm_id msm_id;
|
||||
int len;
|
||||
|
||||
root_offset = fdt_path_offset(dtb, "/");
|
||||
if (root_offset < 0)
|
||||
return 0;
|
||||
|
||||
prop = fdt_getprop(dtb, root_offset, "qcom,msm-id", &len);
|
||||
if (!prop || len <= 0) {
|
||||
printf("DTB: qcom,msm-id entry not found\n");
|
||||
return 0;
|
||||
} else if (len < (int)sizeof(struct msm_id)) {
|
||||
printf("DTB: qcom,msm-id entry size mismatch (%d != %d)\n",
|
||||
len, sizeof(struct msm_id));
|
||||
return 0;
|
||||
}
|
||||
msm_id.platform_id = fdt32_to_cpu(((const struct msm_id *)prop)->platform_id);
|
||||
msm_id.hardware_id = fdt32_to_cpu(((const struct msm_id *)prop)->hardware_id);
|
||||
msm_id.soc_rev = fdt32_to_cpu(((const struct msm_id *)prop)->soc_rev);
|
||||
|
||||
if (msm_id.platform_id != devid->platform_id ||
|
||||
msm_id.hardware_id != devid->hardware_id) {
|
||||
return INVALID_SOC_REV_ID;
|
||||
}
|
||||
|
||||
return msm_id.soc_rev;
|
||||
}
|
||||
|
||||
static int get_appended_dtb(const char *kernel, off_t kernel_len, struct dtb *dtb_struct)
|
||||
{
|
||||
char *kernel_end = (char*)kernel + kernel_len;
|
||||
char *dtb;
|
||||
FILE *f;
|
||||
struct msm_id devid;
|
||||
char *bestmatch_tag = NULL;
|
||||
uint32_t bestmatch_tag_size;
|
||||
uint32_t bestmatch_soc_rev_id = INVALID_SOC_REV_ID;
|
||||
|
||||
f = fopen("/proc/device-tree/qcom,msm-id", "r");
|
||||
if(!f)
|
||||
{
|
||||
fprintf(stderr, "DTB: Couldn't open /proc/device-tree/qcom,msm-id!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fread(&devid, sizeof(struct msm_id), 1, f);
|
||||
fclose(f);
|
||||
|
||||
devid.platform_id = fdt32_to_cpu(devid.platform_id);
|
||||
devid.hardware_id = fdt32_to_cpu(devid.hardware_id);
|
||||
devid.soc_rev = fdt32_to_cpu(devid.soc_rev);
|
||||
|
||||
printf("DTB: platform %u hw %u soc 0x%x\n", devid.platform_id, devid.hardware_id, devid.soc_rev);
|
||||
|
||||
// scan the compressed kernel buf for dtb
|
||||
dtb = kernel;
|
||||
while(dtb + sizeof(struct fdt_header) < kernel_end)
|
||||
{
|
||||
|
||||
int ret = fdt_check_header(dtb);
|
||||
if (ret != 0) {
|
||||
dtb++;
|
||||
continue;
|
||||
} else {
|
||||
printf("DTB: found dtb header at %zu\n", dtb);
|
||||
}
|
||||
|
||||
uint32_t dtb_soc_rev_id;
|
||||
uint32_t dtb_size;
|
||||
|
||||
// stop if we go over kernel_end
|
||||
if (dtb + fdt_totalsize(dtb) > kernel_end) {
|
||||
printf("DTB: went over kernel_end, BREAK!\n");
|
||||
break;
|
||||
}
|
||||
dtb_size = fdt_totalsize(dtb);
|
||||
dtb_soc_rev_id = dtb_compatible(dtb, &devid);
|
||||
if (dtb_soc_rev_id == devid.soc_rev) {
|
||||
dtb_struct->buf = xmalloc(dtb_size);
|
||||
memcpy(dtb_struct->buf, dtb, dtb_size);
|
||||
dtb_struct->size = dtb_size;
|
||||
printf("DTB: match 0x%x, my id 0x%x, len %u\n", dtb_soc_rev_id, devid.soc_rev, dtb_size);
|
||||
return 1;
|
||||
} else if ((dtb_soc_rev_id != INVALID_SOC_REV_ID) &&
|
||||
(dtb_soc_rev_id < devid.soc_rev)) {
|
||||
/* if current bestmatch is less than new dtb_soc_rev_id then update
|
||||
bestmatch_tag */
|
||||
if((bestmatch_soc_rev_id == INVALID_SOC_REV_ID) ||
|
||||
(bestmatch_soc_rev_id < dtb_soc_rev_id)) {
|
||||
bestmatch_tag = dtb;
|
||||
bestmatch_tag_size = dtb_size;
|
||||
bestmatch_soc_rev_id = dtb_soc_rev_id;
|
||||
}
|
||||
}
|
||||
|
||||
/* goto the next device tree if any */
|
||||
dtb += dtb_size;
|
||||
}
|
||||
if(bestmatch_tag) {
|
||||
printf("DTB: bestmatch 0x%x, my id 0x%x\n", bestmatch_soc_rev_id, devid.soc_rev);
|
||||
dtb_struct->buf = xmalloc(bestmatch_tag_size);
|
||||
memcpy(dtb_struct->buf, bestmatch_tag, bestmatch_tag_size);
|
||||
dtb_struct->size = bestmatch_tag_size;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dtb_add_memory_reg(void *dtb_buf, int off)
|
||||
{
|
||||
FILE *f;
|
||||
uint32_t reg;
|
||||
int res;
|
||||
|
||||
f = fopen("/proc/device-tree/memory/reg", "r");
|
||||
if(!f)
|
||||
{
|
||||
fprintf(stderr, "DTB: Failed to open /proc/device-tree/memory/reg!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fdt_delprop(dtb_buf, off, "reg");
|
||||
|
||||
while(fread(®, sizeof(reg), 1, f) == 1)
|
||||
fdt_appendprop(dtb_buf, off, "reg", ®, sizeof(reg));
|
||||
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int read_appended_dtb(const char *kernel_buf, off_t kernel_size, struct dtb *dtb) {
|
||||
|
||||
if(get_appended_dtb(kernel_buf, kernel_size, dtb))
|
||||
{
|
||||
int ret, off;
|
||||
|
||||
printf("DTB: Using DTB appended to zImage\n");
|
||||
dtb->size = fdt_totalsize(dtb->buf) + DTB_PAD_SIZE;
|
||||
dtb->buf = xrealloc(dtb->buf, dtb->size);
|
||||
ret = fdt_open_into(dtb->buf, dtb->buf, dtb->size);
|
||||
if(ret)
|
||||
die("DTB: fdt_open_into failed");
|
||||
ret = fdt_path_offset(dtb->buf, "/memory");
|
||||
if (ret >= 0)
|
||||
dtb_add_memory_reg(dtb->buf, ret);
|
||||
else
|
||||
fprintf(stderr, "DTB: Could not find memory node.\n");
|
||||
// this shouldn't be used, but we set it for completeness
|
||||
dtb->path = "appended";
|
||||
return ret;
|
||||
} else {
|
||||
printf("DTB: appended DTB not detected\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* read_1st_dtb - Read the 1st stage kernel's dtb.
|
||||
*/
|
||||
|
||||
static int read_1st_dtb(struct dtb *dtb, const char *kernel_buf, off_t kernel_size)
|
||||
static int read_1st_dtb(struct dtb *dtb)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = read_appended_dtb(kernel_buf, kernel_size, dtb);
|
||||
|
||||
if (!result)
|
||||
goto on_success;
|
||||
|
||||
result = read_sys_dtb(dtb);
|
||||
|
||||
if (!result)
|
||||
@@ -557,8 +381,7 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line)
|
||||
*/
|
||||
|
||||
int arm64_load_other_segments(struct kexec_info *info,
|
||||
uint64_t kernel_entry, const char *kernel_buf,
|
||||
off_t kernel_size)
|
||||
uint64_t kernel_entry)
|
||||
{
|
||||
int result;
|
||||
uint64_t dtb_base;
|
||||
@@ -584,11 +407,9 @@ int arm64_load_other_segments(struct kexec_info *info,
|
||||
if (arm64_opts.dtb) {
|
||||
dtb.name = "dtb_2";
|
||||
dtb.buf = slurp_file(arm64_opts.dtb, &dtb.size);
|
||||
// skip header if loading dtb.img
|
||||
dtb.buf += 2048;
|
||||
} else {
|
||||
dtb.name = "dtb_1";
|
||||
result = read_1st_dtb(&dtb, kernel_buf, kernel_size);
|
||||
result = read_1st_dtb(&dtb);
|
||||
|
||||
if (result) {
|
||||
fprintf(stderr,
|
||||
@@ -774,8 +595,7 @@ static int get_memory_ranges_iomem(struct memory_range *array,
|
||||
* get_memory_ranges_dt - Try to get the memory ranges from the 1st stage dtb.
|
||||
*/
|
||||
|
||||
static int get_memory_ranges_dt(struct memory_range *array, unsigned int *count,
|
||||
char *kernel_buf, off_t kernel_size)
|
||||
static int get_memory_ranges_dt(struct memory_range *array, unsigned int *count)
|
||||
{
|
||||
struct region {uint64_t base; uint64_t size;};
|
||||
struct dtb dtb = {.name = "range_dtb"};
|
||||
@@ -784,7 +604,7 @@ static int get_memory_ranges_dt(struct memory_range *array, unsigned int *count,
|
||||
|
||||
*count = 0;
|
||||
|
||||
result = read_1st_dtb(&dtb, kernel_buf, kernel_size);
|
||||
result = read_1st_dtb(&dtb);
|
||||
|
||||
if (result) {
|
||||
goto on_error;
|
||||
@@ -876,7 +696,7 @@ on_exit:
|
||||
*/
|
||||
|
||||
int get_memory_ranges(struct memory_range **range, int *ranges,
|
||||
unsigned long kexec_flags, char *kernel_buf, off_t kernel_size)
|
||||
unsigned long kexec_flags)
|
||||
{
|
||||
static struct memory_range array[KEXEC_SEGMENT_MAX];
|
||||
unsigned int count;
|
||||
@@ -885,7 +705,7 @@ int get_memory_ranges(struct memory_range **range, int *ranges,
|
||||
result = get_memory_ranges_iomem(array, &count);
|
||||
|
||||
if (result)
|
||||
result = get_memory_ranges_dt(array, &count, kernel_buf, kernel_size);
|
||||
result = get_memory_ranges_dt(array, &count);
|
||||
|
||||
*range = result ? NULL : array;
|
||||
*ranges = result ? 0 : count;
|
||||
|
||||
@@ -23,14 +23,12 @@
|
||||
|
||||
int elf_arm64_probe(const char *kernel_buf, off_t kernel_size);
|
||||
int elf_arm64_load(int argc, char **argv, const char *kernel_buf,
|
||||
off_t kernel_size, const char *kernel_compressed_buf,
|
||||
off_t kernel_compressed_size, struct kexec_info *info);
|
||||
off_t kernel_size, struct kexec_info *info);
|
||||
void elf_arm64_usage(void);
|
||||
|
||||
int image_arm64_probe(const char *kernel_buf, off_t kernel_size);
|
||||
int image_arm64_load(int argc, char **argv, const char *kernel_buf,
|
||||
off_t kernel_size, const char *kernel_compressed_buf,
|
||||
off_t kernel_compressed_size, struct kexec_info *info);
|
||||
off_t kernel_size, struct kexec_info *info);
|
||||
void image_arm64_usage(void);
|
||||
|
||||
off_t initrd_base;
|
||||
@@ -67,7 +65,6 @@ static inline void set_phys_offset(uint64_t v)
|
||||
|
||||
int arm64_process_image_header(const struct arm64_image_header *h);
|
||||
int arm64_load_other_segments(struct kexec_info *info,
|
||||
uint64_t kernel_entry, const char *kernel_buf,
|
||||
off_t kernel_size);
|
||||
uint64_t kernel_entry);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -37,8 +37,7 @@ on_exit:
|
||||
}
|
||||
|
||||
int elf_arm64_load(int argc, char **argv, const char *kernel_buf,
|
||||
off_t kernel_size, const char *kernel_compressed_buf,
|
||||
off_t kernel_compressed_size, struct kexec_info *info)
|
||||
off_t kernel_size, struct kexec_info *info)
|
||||
{
|
||||
struct mem_ehdr ehdr;
|
||||
int result;
|
||||
@@ -109,7 +108,7 @@ int elf_arm64_load(int argc, char **argv, const char *kernel_buf,
|
||||
}
|
||||
|
||||
result = arm64_load_other_segments(info,
|
||||
virt_to_phys(ehdr.e_entry), kernel_buf, kernel_size);
|
||||
virt_to_phys(ehdr.e_entry));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,7 @@ int image_arm64_probe(const char *kernel_buf, off_t kernel_size)
|
||||
}
|
||||
|
||||
int image_arm64_load(int argc, char **argv, const char *kernel_buf,
|
||||
off_t kernel_size, const char *kernel_compressed_buf,
|
||||
off_t kernel_compressed_size, struct kexec_info *info)
|
||||
off_t kernel_size, struct kexec_info *info)
|
||||
{
|
||||
const struct arm64_image_header *h;
|
||||
unsigned long image_base;
|
||||
@@ -50,8 +49,7 @@ int image_arm64_load(int argc, char **argv, const char *kernel_buf,
|
||||
add_segment_phys_virt(info, kernel_buf, kernel_size, image_base,
|
||||
arm64_mem.image_size, 0);
|
||||
|
||||
return arm64_load_other_segments(info, image_base,
|
||||
kernel_compressed_buf, kernel_compressed_size);
|
||||
return arm64_load_other_segments(info, image_base);
|
||||
}
|
||||
|
||||
void image_arm64_usage(void)
|
||||
|
||||
@@ -693,8 +693,6 @@ static int my_load(const char *type, int fileind, int argc, char **argv,
|
||||
char *kernel;
|
||||
char *kernel_buf;
|
||||
off_t kernel_size;
|
||||
char *kernel_compressed_buf;
|
||||
off_t kernel_compressed_size;
|
||||
int i = 0;
|
||||
int result;
|
||||
struct kexec_info info;
|
||||
@@ -713,16 +711,12 @@ static int my_load(const char *type, int fileind, int argc, char **argv,
|
||||
kernel = argv[fileind];
|
||||
/* slurp in the input kernel */
|
||||
kernel_buf = slurp_decompress_file(kernel, &kernel_size);
|
||||
// make sure to always slurp in the compressed input kernel
|
||||
// this is used to check for appended dtb
|
||||
kernel_compressed_buf = slurp_file(kernel, &kernel_compressed_size);
|
||||
|
||||
dbgprintf("kernel: %p kernel_size: %#llx\n",
|
||||
kernel_buf, (unsigned long long)kernel_size);
|
||||
|
||||
if (get_memory_ranges(&info.memory_range, &info.memory_ranges,
|
||||
info.kexec_flags, kernel_compressed_buf, kernel_compressed_size) < 0 ||
|
||||
info.memory_ranges == 0) {
|
||||
info.kexec_flags) < 0 || info.memory_ranges == 0) {
|
||||
fprintf(stderr, "Could not get memory layout\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -766,8 +760,7 @@ static int my_load(const char *type, int fileind, int argc, char **argv,
|
||||
}
|
||||
info.kexec_flags |= native_arch;
|
||||
|
||||
result = file_type[i].load(argc, argv, kernel_buf, kernel_size,
|
||||
kernel_compressed_buf, kernel_compressed_size, &info);
|
||||
result = file_type[i].load(argc, argv, kernel_buf, kernel_size, &info);
|
||||
if (result < 0) {
|
||||
switch (result) {
|
||||
case ENOCRASHKERNEL:
|
||||
@@ -1138,9 +1131,7 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
|
||||
struct kexec_info info;
|
||||
int ret = 0;
|
||||
char *kernel_buf;
|
||||
char *kernel_compressed_buf;
|
||||
off_t kernel_size;
|
||||
off_t kernel_compressed_size;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.segment = NULL;
|
||||
@@ -1174,9 +1165,6 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
|
||||
|
||||
/* slurp in the input kernel */
|
||||
kernel_buf = slurp_decompress_file(kernel, &kernel_size);
|
||||
// make sure to always slurp in the compressed input kernel
|
||||
// this is used to check for appended dtb
|
||||
kernel_compressed_buf = slurp_decompress_file(kernel, &kernel_compressed_size);
|
||||
|
||||
for (i = 0; i < file_types; i++) {
|
||||
if (file_type[i].probe(kernel_buf, kernel_size) >= 0)
|
||||
@@ -1189,8 +1177,7 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = file_type[i].load(argc, argv, kernel_buf, kernel_size,
|
||||
kernel_compressed_buf, kernel_compressed_size, &info);
|
||||
ret = file_type[i].load(argc, argv, kernel_buf, kernel_size, &info);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot load %s\n", kernel);
|
||||
return ret;
|
||||
|
||||
@@ -182,8 +182,7 @@ long kernel_version(void);
|
||||
|
||||
void usage(void);
|
||||
int get_memory_ranges(struct memory_range **range, int *ranges,
|
||||
unsigned long kexec_flags, char *kernel_buf,
|
||||
off_t kernel_size);
|
||||
unsigned long kexec_flags);
|
||||
int valid_memory_range(struct kexec_info *info,
|
||||
unsigned long sstart, unsigned long send);
|
||||
void print_segments(FILE *file, struct kexec_info *info);
|
||||
@@ -195,8 +194,7 @@ unsigned long locate_hole(struct kexec_info *info,
|
||||
|
||||
typedef int (probe_t)(const char *kernel_buf, off_t kernel_size);
|
||||
typedef int (load_t )(int argc, char **argv,
|
||||
const char *kernel_buf, off_t kernel_size,
|
||||
const char *kernel_compressed_buf, off_t kernel_compressed_size,
|
||||
const char *kernel_buf, off_t kernel_size,
|
||||
struct kexec_info *info);
|
||||
typedef void (usage_t)(void);
|
||||
struct file_type {
|
||||
|
||||
@@ -289,33 +289,6 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
|
||||
const void *val, int len)
|
||||
{
|
||||
struct fdt_property *prop;
|
||||
int err, oldlen, newlen;
|
||||
|
||||
FDT_RW_CHECK_HEADER(fdt);
|
||||
|
||||
prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
|
||||
if (prop) {
|
||||
newlen = len + oldlen;
|
||||
err = _fdt_splice_struct(fdt, prop->data,
|
||||
FDT_TAGALIGN(oldlen),
|
||||
FDT_TAGALIGN(newlen));
|
||||
if (err)
|
||||
return err;
|
||||
prop->len = cpu_to_fdt32(newlen);
|
||||
memcpy(prop->data + oldlen, val, len);
|
||||
} else {
|
||||
err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
|
||||
if (err)
|
||||
return err;
|
||||
memcpy(prop->data, val, len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdt_delprop(void *fdt, int nodeoffset, const char *name)
|
||||
{
|
||||
struct fdt_property *prop;
|
||||
|
||||
@@ -974,36 +974,6 @@ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
|
||||
#define fdt_setprop_string(fdt, nodeoffset, name, str) \
|
||||
fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
|
||||
|
||||
/**
|
||||
* fdt_appendprop - append to or create a property
|
||||
* @fdt: pointer to the device tree blob
|
||||
* @nodeoffset: offset of the node whose property to change
|
||||
* @name: name of the property to append to
|
||||
* @val: pointer to data to append to the property value
|
||||
* @len: length of the data to append to the property value
|
||||
*
|
||||
* fdt_appendprop() appends the value to the named property in the
|
||||
* given node, creating the property if it does not already exist.
|
||||
*
|
||||
* This function may insert data into the blob, and will therefore
|
||||
* change the offsets of some existing nodes.
|
||||
*
|
||||
* returns:
|
||||
* 0, on success
|
||||
* -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
|
||||
* contain the new property value
|
||||
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
|
||||
* -FDT_ERR_BADLAYOUT,
|
||||
* -FDT_ERR_BADMAGIC,
|
||||
* -FDT_ERR_BADVERSION,
|
||||
* -FDT_ERR_BADSTATE,
|
||||
* -FDT_ERR_BADSTRUCTURE,
|
||||
* -FDT_ERR_BADLAYOUT,
|
||||
* -FDT_ERR_TRUNCATED, standard meanings
|
||||
*/
|
||||
int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
|
||||
const void *val, int len);
|
||||
|
||||
/**
|
||||
* fdt_delprop - delete a property
|
||||
* @fdt: pointer to the device tree blob
|
||||
|
||||
Reference in New Issue
Block a user