diff options
Diffstat (limited to 'firmware/common')
-rw-r--r-- | firmware/common/rb-loader.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/firmware/common/rb-loader.c b/firmware/common/rb-loader.c index 10807f9c96..82b636d451 100644 --- a/firmware/common/rb-loader.c +++ b/firmware/common/rb-loader.c | |||
@@ -25,6 +25,54 @@ | |||
25 | #include "rb-loader.h" | 25 | #include "rb-loader.h" |
26 | #include "loader_strerror.h" | 26 | #include "loader_strerror.h" |
27 | 27 | ||
28 | #if defined(HAVE_BOOTDATA) | ||
29 | #include "bootdata.h" | ||
30 | #include "crc32.h" | ||
31 | |||
32 | /* Write boot data into location marked by magic header | ||
33 | * buffer is already loaded with the firmware image | ||
34 | * we just need to find the location and write | ||
35 | * data into the payload along with the crc | ||
36 | * for later verification and use. | ||
37 | * Returns payload len on success, | ||
38 | * On error returns EKEY_NOT_FOUND | ||
39 | */ | ||
40 | static int write_bootdata(unsigned char* buf, int len, unsigned int boot_volume) | ||
41 | { | ||
42 | struct boot_data_t bl_boot_data; | ||
43 | struct boot_data_t *fw_boot_data = NULL; | ||
44 | int search_len = MIN(len, BOOT_DATA_SEARCH_SIZE) - sizeof(struct boot_data_t); | ||
45 | int payload_len = EKEY_NOT_FOUND; | ||
46 | |||
47 | /* search for boot data header prior to search_len */ | ||
48 | for(int i = 0;i < search_len;i++) | ||
49 | { | ||
50 | fw_boot_data = (struct boot_data_t*) &buf[i]; | ||
51 | if (fw_boot_data->magic[0] != BOOT_DATA_MAGIC0 || | ||
52 | fw_boot_data->magic[1] != BOOT_DATA_MAGIC1) | ||
53 | continue; | ||
54 | /* 0 fill bootloader struct then add our data */ | ||
55 | memset(&bl_boot_data.payload, 0, BOOT_DATA_PAYLOAD_SIZE); | ||
56 | bl_boot_data.boot_volume = boot_volume; | ||
57 | /* 0 fill payload region in firmware */ | ||
58 | memset(fw_boot_data->payload, 0, fw_boot_data->length); | ||
59 | /* determine maximum bytes we can write to firmware | ||
60 | BOOT_DATA_PAYLOAD_SIZE is the size the bootloader expects */ | ||
61 | payload_len = MIN(BOOT_DATA_PAYLOAD_SIZE, fw_boot_data->length); | ||
62 | /* write payload size back to firmware struct */ | ||
63 | fw_boot_data->length = payload_len; | ||
64 | /* copy data to firmware bootdata struct */ | ||
65 | memcpy(fw_boot_data->payload, &bl_boot_data.payload, payload_len); | ||
66 | /* calculate and write the crc for the payload */ | ||
67 | fw_boot_data->crc = crc_32(fw_boot_data->payload, | ||
68 | payload_len, | ||
69 | 0xffffffff); | ||
70 | break; | ||
71 | |||
72 | } | ||
73 | return payload_len; | ||
74 | } | ||
75 | #endif /* HAVE_BOOTDATA */ | ||
28 | /* Load firmware image in a format created by add method of tools/scramble | 76 | /* Load firmware image in a format created by add method of tools/scramble |
29 | * on success we return size loaded image | 77 | * on success we return size loaded image |
30 | * on error we return negative value which can be deciphered by means | 78 | * on error we return negative value which can be deciphered by means |
@@ -105,11 +153,14 @@ int load_firmware(unsigned char* buf, const char* firmware, int buffer_size) | |||
105 | ret = EBAD_CHKSUM; | 153 | ret = EBAD_CHKSUM; |
106 | goto end; | 154 | goto end; |
107 | } | 155 | } |
108 | 156 | #ifdef HAVE_BOOTDATA | |
157 | /* 0 is the default boot volume */ | ||
158 | write_bootdata(buf, ret, 0); | ||
159 | #endif | ||
109 | ret = len; | 160 | ret = len; |
110 | 161 | ||
162 | |||
111 | end: | 163 | end: |
112 | close(fd); | 164 | close(fd); |
113 | return ret; | 165 | return ret; |
114 | } | 166 | } |
115 | |||