forked from M-Labs/zynq-rs
mkbootimage: add elf_use_ph patch by mwojcik
This commit is contained in:
@@ -59,7 +59,8 @@
|
||||
};
|
||||
|
||||
propagatedBuildInputs = [pkgs.libelf pkgs.pcre];
|
||||
patchPhase = ''
|
||||
patches = [ ./mkbootimage-elf-use-ph.diff ];
|
||||
postPatch = ''
|
||||
substituteInPlace Makefile --replace "git rev-parse --short HEAD" "echo nix"
|
||||
'';
|
||||
installPhase = ''
|
||||
|
||||
219
mkbootimage-elf-use-ph.diff
Normal file
219
mkbootimage-elf-use-ph.diff
Normal file
@@ -0,0 +1,219 @@
|
||||
diff --git a/src/bif.c b/src/bif.c
|
||||
index f3e0615..e2caec9 100644
|
||||
--- a/src/bif.c
|
||||
+++ b/src/bif.c
|
||||
@@ -332,8 +332,9 @@ static error bif_parse_file(lexer_t *lex, bif_cfg_t *cfg, bif_node_t *node) {
|
||||
node->load = 0;
|
||||
node->offset = 0;
|
||||
node->bootloader = 0;
|
||||
+ node->elf_use_ph = 0;
|
||||
node->fsbl_config = 0;
|
||||
- node->pmufw_image = 0;
|
||||
+ node->pmufw_image = 0;
|
||||
node->exception_level = BOOTROM_PART_ATTR_EXC_LVL_EL0;
|
||||
node->partition_owner = BOOTROM_PART_ATTR_OWNER_FSBL;
|
||||
node->destination_cpu = BOOTROM_PART_ATTR_DEST_CPU_NONE;
|
||||
@@ -462,6 +463,11 @@ error bif_node_set_attr(
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
+ if (strcmp(attr_name, "elf_use_ph") == 0) {
|
||||
+ node->elf_use_ph = 0xFF;
|
||||
+ return SUCCESS;
|
||||
+ }
|
||||
+
|
||||
if (strcmp(attr_name, "partition_owner") == 0) {
|
||||
if (!value) {
|
||||
perrorf(lex, "the \"%s\" attribute requires an argument\n", attr_name);
|
||||
diff --git a/src/bif.h b/src/bif.h
|
||||
index f76b13e..cf73670 100644
|
||||
--- a/src/bif.h
|
||||
+++ b/src/bif.h
|
||||
@@ -40,6 +40,7 @@ typedef struct bif_node_t {
|
||||
uint32_t load;
|
||||
uint32_t offset;
|
||||
uint32_t partition_owner;
|
||||
+ uint8_t elf_use_ph; /* boolean */
|
||||
|
||||
/* supported zynqmp attributes */
|
||||
uint8_t fsbl_config; /* boolean */
|
||||
diff --git a/src/bootrom.c b/src/bootrom.c
|
||||
index 4b6ee25..af90570 100644
|
||||
--- a/src/bootrom.c
|
||||
+++ b/src/bootrom.c
|
||||
@@ -187,7 +187,8 @@ error append_file_to_image(uint32_t *addr,
|
||||
img_size,
|
||||
&elf_nbits,
|
||||
&elf_load,
|
||||
- &elf_entry);
|
||||
+ &elf_entry,
|
||||
+ node.elf_use_ph);
|
||||
if (err) {
|
||||
errorf("ELF file reading failed\n");
|
||||
|
||||
@@ -372,7 +373,8 @@ error create_boot_image(uint32_t *img_ptr,
|
||||
&pmufw_img_size,
|
||||
&pmufw_img_nbits,
|
||||
&pmufw_img_load,
|
||||
- &pmufw_img_entry);
|
||||
+ &pmufw_img_entry,
|
||||
+ bif_cfg->nodes[i].elf_use_ph);
|
||||
if (err) {
|
||||
errorf("failed to parse ELF file: %s\n", bif_cfg->nodes[i].fname);
|
||||
return ERROR_BOOTROM_ELF;
|
||||
diff --git a/src/file/elf.c b/src/file/elf.c
|
||||
index 410fed6..4fd7ded 100644
|
||||
--- a/src/file/elf.c
|
||||
+++ b/src/file/elf.c
|
||||
@@ -34,11 +34,75 @@
|
||||
#include <gelf.h>
|
||||
#include <unistd.h>
|
||||
|
||||
+static error elf_create_image_from_ph(Elf *elf, uint32_t start_addr, uint8_t *out_buf) {
|
||||
+ size_t n_phdrs;
|
||||
+
|
||||
+ if(elf_getphdrnum(elf, &n_phdrs) != 0) {
|
||||
+ printf("elf_getphdrnum failed\n");
|
||||
+ return ERROR_BOOTROM_ELF;
|
||||
+ }
|
||||
+ size_t file_size;
|
||||
+ uint8_t *raw_data = elf_rawfile(elf, &file_size);
|
||||
+ if (raw_data == NULL) {
|
||||
+ return ERROR_BOOTROM_ELF;
|
||||
+ }
|
||||
+ for (size_t i = 0; i < n_phdrs; ++i) {
|
||||
+ GElf_Phdr phdr;
|
||||
+ if (gelf_getphdr(elf, i, &phdr) == NULL) {
|
||||
+ printf("gelf_getphdr returned no address\n");
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (phdr.p_type == PT_LOAD) {
|
||||
+ // loadable, get the data
|
||||
+ if (phdr.p_offset + phdr.p_filesz > file_size) {
|
||||
+ // somehow offset is further than the whole file size
|
||||
+ return ERROR_BOOTROM_ELF;
|
||||
+ }
|
||||
+ if (phdr.p_filesz > 0) {
|
||||
+ uint8_t *segment_data = raw_data + phdr.p_offset;
|
||||
+ size_t segment_size = phdr.p_filesz;
|
||||
+
|
||||
+ memcpy(out_buf + phdr.p_paddr - start_addr,
|
||||
+ segment_data,
|
||||
+ segment_size);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return SUCCESS;
|
||||
+}
|
||||
+
|
||||
static bool elf_is_loadable_section(const GElf_Shdr *elf_shdr) {
|
||||
return elf_shdr->sh_type != SHT_NOBITS && (elf_shdr->sh_flags & SHF_ALLOC) &&
|
||||
elf_shdr->sh_size != 0;
|
||||
}
|
||||
|
||||
+static error elf_get_startaddr_endaddr_from_ph(Elf *elf, uint32_t *start_addr, uint32_t *end_addr) {
|
||||
+ size_t n_phdrs;
|
||||
+ *start_addr = -1;
|
||||
+ *end_addr = 0;
|
||||
+
|
||||
+ if (elf_getphdrnum(elf, &n_phdrs) != 0) {
|
||||
+ return ERROR_BOOTROM_ELF;
|
||||
+ }
|
||||
+
|
||||
+ for (size_t i = 0; i < n_phdrs; ++i) {
|
||||
+ GElf_Phdr phdr;
|
||||
+ if (gelf_getphdr(elf, i, &phdr) == NULL) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (phdr.p_type == PT_LOAD) {
|
||||
+ if (*start_addr > phdr.p_paddr) {
|
||||
+ *start_addr = phdr.p_paddr;
|
||||
+ }
|
||||
+
|
||||
+ if (phdr.p_paddr + phdr.p_filesz > *end_addr) {
|
||||
+ *end_addr = phdr.p_paddr + phdr.p_filesz;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return SUCCESS;
|
||||
+}
|
||||
+
|
||||
static error elf_get_startaddr_endaddr(Elf *elf, uint32_t *start_addr, uint32_t *end_addr) {
|
||||
Elf_Scn *elf_scn = NULL;
|
||||
GElf_Shdr elf_shdr;
|
||||
@@ -95,7 +159,8 @@ error elf_append(void *addr,
|
||||
uint32_t *img_size,
|
||||
uint8_t *elf_nbits,
|
||||
uint32_t *elf_load,
|
||||
- uint32_t *elf_entry) {
|
||||
+ uint32_t *elf_entry,
|
||||
+ uint8_t elf_use_ph) {
|
||||
error err;
|
||||
int fd_elf;
|
||||
Elf *elf;
|
||||
@@ -124,10 +189,18 @@ error elf_append(void *addr,
|
||||
return ERROR_BOOTROM_ELF;
|
||||
}
|
||||
|
||||
- if ((err = elf_get_startaddr_endaddr(elf, &start_addr, &end_addr))) {
|
||||
- elf_end(elf);
|
||||
- close(fd_elf);
|
||||
- return err;
|
||||
+ if (elf_use_ph) {
|
||||
+ if ((err = elf_get_startaddr_endaddr_from_ph(elf, &start_addr, &end_addr))) {
|
||||
+ elf_end(elf);
|
||||
+ close(fd_elf);
|
||||
+ return err;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if ((err = elf_get_startaddr_endaddr(elf, &start_addr, &end_addr))) {
|
||||
+ elf_end(elf);
|
||||
+ close(fd_elf);
|
||||
+ return err;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (end_addr - start_addr > img_max_size) {
|
||||
@@ -138,10 +211,18 @@ error elf_append(void *addr,
|
||||
|
||||
memset(addr, 0, end_addr - start_addr);
|
||||
|
||||
- if ((err = elf_create_image(elf, start_addr, addr))) {
|
||||
- elf_end(elf);
|
||||
- close(fd_elf);
|
||||
- return err;
|
||||
+ if (elf_use_ph) {
|
||||
+ if ((err = elf_create_image_from_ph(elf, start_addr, addr))) {
|
||||
+ elf_end(elf);
|
||||
+ close(fd_elf);
|
||||
+ return err;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if ((err = elf_create_image(elf, start_addr, addr))) {
|
||||
+ elf_end(elf);
|
||||
+ close(fd_elf);
|
||||
+ return err;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (gelf_getehdr(elf, &elf_ehdr) != &elf_ehdr) {
|
||||
@@ -159,4 +240,4 @@ error elf_append(void *addr,
|
||||
close(fd_elf);
|
||||
|
||||
return SUCCESS;
|
||||
-}
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/file/elf.h b/src/file/elf.h
|
||||
index 062616e..88d27ff 100644
|
||||
--- a/src/file/elf.h
|
||||
+++ b/src/file/elf.h
|
||||
@@ -9,6 +9,7 @@ error elf_append(void *addr,
|
||||
uint32_t *img_size,
|
||||
uint8_t *elf_nbits,
|
||||
uint32_t *elf_load,
|
||||
- uint32_t *elf_entry);
|
||||
+ uint32_t *elf_entry,
|
||||
+ uint8_t elf_use_ph);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user