forked from M-Labs/zynq-rs
Compare commits
3 Commits
6cfb6fd1fc
...
6e4e0548a2
| Author | SHA1 | Date | |
|---|---|---|---|
| 6e4e0548a2 | |||
| 2965ebfdce | |||
| bd466202d4 |
18
flake.lock
generated
18
flake.lock
generated
@@ -30,11 +30,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1768908532,
|
||||
"narHash": "sha256-HIdLXEFaUVE8FiaCPJbCfBMsnF+mVtDub8Jwj2BD+mk=",
|
||||
"lastModified": 1769799857,
|
||||
"narHash": "sha256-88IFXZ7Sa1vxbz5pty0Io5qEaMQMMUPMonLa3Ls/ss4=",
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"rev": "8d97452673640eb7fabe428e8b6a425bc355008b",
|
||||
"rev": "9d4ed44d8b8cecdceb1d6fd76e74123d90ae6339",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -45,11 +45,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1769018530,
|
||||
"narHash": "sha256-MJ27Cy2NtBEV5tsK+YraYr2g851f3Fl1LpNHDzDX15c=",
|
||||
"lastModified": 1771008912,
|
||||
"narHash": "sha256-gf2AmWVTs8lEq7z/3ZAsgnZDhWIckkb+ZnAo5RzSxJg=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "88d3861acdd3d2f0e361767018218e51810df8a1",
|
||||
"rev": "a82ccc39b39b621151d6732718e3e250109076fa",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -90,11 +90,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769136478,
|
||||
"narHash": "sha256-8UNd5lmGf8phCr/aKxagJ4kNsF0pCHLish2G4ZKCFFY=",
|
||||
"lastModified": 1771038269,
|
||||
"narHash": "sha256-TygYZ7JhnJbRoWOk7d5HaA/GhEVCvtRruN7TqaN9s/c=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "470ee44393bb19887056b557ea2c03fc5230bd5a",
|
||||
"rev": "d7a86c8a4df49002446737603a3e0d7ef91a9637",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -59,8 +59,9 @@
|
||||
};
|
||||
|
||||
propagatedBuildInputs = [pkgs.libelf pkgs.pcre];
|
||||
patchPhase = ''
|
||||
substituteInPlace Makefile --replace "git rev-parse --short HEAD" "echo nix"
|
||||
patches = [ ./mkbootimage-elf-use-ph.diff ];
|
||||
postPatch = ''
|
||||
substituteInPlace Makefile --replace-fail "git rev-parse --short HEAD" "echo nix"
|
||||
'';
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
|
||||
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