mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-07 06:48:44 +00:00
Support writing the IHEX symbol table
This commit is contained in:
parent
499f2bf995
commit
c68757ce4d
@ -31,6 +31,7 @@ void dfu_firmware_add_symbol (DfuFirmware *firmware,
|
|||||||
guint32 symbol_addr);
|
guint32 symbol_addr);
|
||||||
guint32 dfu_firmware_lookup_symbol (DfuFirmware *firmware,
|
guint32 dfu_firmware_lookup_symbol (DfuFirmware *firmware,
|
||||||
const gchar *symbol_name);
|
const gchar *symbol_name);
|
||||||
|
GPtrArray *dfu_firmware_get_symbols (DfuFirmware *firmware);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -853,3 +853,25 @@ dfu_firmware_lookup_symbol (DfuFirmware *firmware, const gchar *symbol_name)
|
|||||||
return GPOINTER_TO_UINT (g_hash_table_lookup (priv->symtab,
|
return GPOINTER_TO_UINT (g_hash_table_lookup (priv->symtab,
|
||||||
symbol_name));
|
symbol_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dfu_firmware_get_symbols:
|
||||||
|
* @firmware: a #DfuFirmware
|
||||||
|
*
|
||||||
|
* Gets all the symbols currently defined.
|
||||||
|
*
|
||||||
|
* Return value: (element-type utf8) (transfer container): symbol names
|
||||||
|
*
|
||||||
|
* Since: 0.7.4
|
||||||
|
**/
|
||||||
|
GPtrArray *
|
||||||
|
dfu_firmware_get_symbols (DfuFirmware *firmware)
|
||||||
|
{
|
||||||
|
DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
|
||||||
|
GPtrArray *array = g_ptr_array_new_with_free_func (g_free);
|
||||||
|
GList *l;
|
||||||
|
g_autoptr(GList) keys = g_hash_table_get_keys (priv->symtab);
|
||||||
|
for (l = keys; l != NULL; l = l->next)
|
||||||
|
g_ptr_array_add (array, g_strdup (l->data));
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
@ -314,16 +314,15 @@ dfu_firmware_from_ihex (DfuFirmware *firmware,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static void
|
||||||
dfu_firmware_to_ihex_element (DfuElement *element, GString *str, GError **error)
|
dfu_firmware_to_ihex_bytes (GString *str, guint8 record_type,
|
||||||
|
guint32 address, GBytes *contents)
|
||||||
{
|
{
|
||||||
GBytes *contents;
|
|
||||||
const guint8 *data;
|
const guint8 *data;
|
||||||
const guint chunk_size = 16;
|
const guint chunk_size = 16;
|
||||||
gsize len;
|
gsize len;
|
||||||
|
|
||||||
/* get number of chunks */
|
/* get number of chunks */
|
||||||
contents = dfu_element_get_contents (element);
|
|
||||||
data = g_bytes_get_data (contents, &len);
|
data = g_bytes_get_data (contents, &len);
|
||||||
for (gsize i = 0; i < len; i += chunk_size) {
|
for (gsize i = 0; i < len; i += chunk_size) {
|
||||||
guint8 checksum = 0;
|
guint8 checksum = 0;
|
||||||
@ -332,8 +331,8 @@ dfu_firmware_to_ihex_element (DfuElement *element, GString *str, GError **error)
|
|||||||
gsize chunk_len = MIN (len - i, 16);
|
gsize chunk_len = MIN (len - i, 16);
|
||||||
g_string_append_printf (str, ":%02X%04X%02X",
|
g_string_append_printf (str, ":%02X%04X%02X",
|
||||||
(guint) chunk_len,
|
(guint) chunk_len,
|
||||||
(guint) (dfu_element_get_address (element) + i),
|
(guint) (address + i),
|
||||||
(guint) DFU_INHX32_RECORD_TYPE_DATA);
|
(guint) record_type);
|
||||||
for (gsize j = 0; j < chunk_len; j++)
|
for (gsize j = 0; j < chunk_len; j++)
|
||||||
g_string_append_printf (str, "%02X", data[i+j]);
|
g_string_append_printf (str, "%02X", data[i+j]);
|
||||||
|
|
||||||
@ -342,6 +341,15 @@ dfu_firmware_to_ihex_element (DfuElement *element, GString *str, GError **error)
|
|||||||
checksum += (guint8) str->str[str->len - (j + 1)];
|
checksum += (guint8) str->str[str->len - (j + 1)];
|
||||||
g_string_append_printf (str, "%02X\n", checksum);
|
g_string_append_printf (str, "%02X\n", checksum);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
dfu_firmware_to_ihex_element (DfuElement *element, GString *str, GError **error)
|
||||||
|
{
|
||||||
|
GBytes *contents = dfu_element_get_contents (element);
|
||||||
|
dfu_firmware_to_ihex_bytes (str, DFU_INHX32_RECORD_TYPE_DATA,
|
||||||
|
dfu_element_get_address (element),
|
||||||
|
contents);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,6 +371,7 @@ dfu_firmware_to_ihex (DfuFirmware *firmware, GError **error)
|
|||||||
GPtrArray *elements;
|
GPtrArray *elements;
|
||||||
guint i;
|
guint i;
|
||||||
guint j;
|
guint j;
|
||||||
|
g_autoptr(GPtrArray) symbols = NULL;
|
||||||
g_autoptr(GString) str = NULL;
|
g_autoptr(GString) str = NULL;
|
||||||
|
|
||||||
/* write all the element data */
|
/* write all the element data */
|
||||||
@ -383,5 +392,16 @@ dfu_firmware_to_ihex (DfuFirmware *firmware, GError **error)
|
|||||||
/* add EOF */
|
/* add EOF */
|
||||||
g_string_append_printf (str, ":000000%02XFF\n",
|
g_string_append_printf (str, ":000000%02XFF\n",
|
||||||
(guint) DFU_INHX32_RECORD_TYPE_EOF);
|
(guint) DFU_INHX32_RECORD_TYPE_EOF);
|
||||||
|
|
||||||
|
/* add any symbol table */
|
||||||
|
symbols = dfu_firmware_get_symbols (firmware);
|
||||||
|
for (i = 0; i < symbols->len; i++) {
|
||||||
|
const gchar *name = g_ptr_array_index (symbols, i);
|
||||||
|
guint32 addr = dfu_firmware_lookup_symbol (firmware, name);
|
||||||
|
g_autoptr(GBytes) contents = g_bytes_new_static (name, strlen (name));
|
||||||
|
dfu_firmware_to_ihex_bytes (str, DFU_INHX32_RECORD_TYPE_SYMTAB,
|
||||||
|
addr, contents);
|
||||||
|
}
|
||||||
|
|
||||||
return g_bytes_new (str->str, str->len);
|
return g_bytes_new (str->str, str->len);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user