summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2014-08-13 12:46:45 +0200
committerMarcin Bukat <marcin.bukat@gmail.com>2014-08-26 07:21:19 +0200
commit69df56504e7dfc8ba7e283901aadde6ebdada5b1 (patch)
tree2852978cbb169c810fd81f98266d1e9d971a6ca8
parentbfbec3a3a7de448902b2b3244f5b4f942ef09570 (diff)
downloadrockbox-69df56504e7dfc8ba7e283901aadde6ebdada5b1.tar.gz
rockbox-69df56504e7dfc8ba7e283901aadde6ebdada5b1.zip
hwpatcher: add framework for CRC computation
Change-Id: Ib78f0fe58db5cec86f043d3e9e1ca14e69297ba0 Reviewed-on: http://gerrit.rockbox.org/911 Reviewed-by: Marcin Bukat <marcin.bukat@gmail.com>
-rw-r--r--utils/hwpatcher/hwpatcher.c85
-rw-r--r--utils/hwpatcher/lib.lua32
2 files changed, 106 insertions, 11 deletions
diff --git a/utils/hwpatcher/hwpatcher.c b/utils/hwpatcher/hwpatcher.c
index 60e142bbc1..7153a220c9 100644
--- a/utils/hwpatcher/hwpatcher.c
+++ b/utils/hwpatcher/hwpatcher.c
@@ -47,6 +47,8 @@
47#include "misc.h" 47#include "misc.h"
48#include "md5.h" 48#include "md5.h"
49 49
50#define ARRAYLEN(arr) (sizeof(arr) / sizeof(arr[0]))
51
50lua_State *g_lua; 52lua_State *g_lua;
51bool g_exit = false; 53bool g_exit = false;
52 54
@@ -59,6 +61,18 @@ enum fw_type_t
59 FW_UNK, FW_ELF, FW_SB1, FW_SB2, FW_BIN, FW_EDOC 61 FW_UNK, FW_ELF, FW_SB1, FW_SB2, FW_BIN, FW_EDOC
60}; 62};
61 63
64enum crc_type_t
65{
66 CRC_RKW
67};
68
69struct crc_type_desc_t
70{
71 enum crc_type_t type;
72 const char *lua_name;
73 unsigned (*fn)(uint8_t *buf, size_t len);
74};
75
62struct bin_file_t 76struct bin_file_t
63{ 77{
64 size_t size; 78 size_t size;
@@ -849,6 +863,66 @@ int my_lua_section_info(lua_State *state)
849 return 1; 863 return 1;
850} 864}
851 865
866unsigned crc_rkw(uint8_t *buf, size_t len)
867{
868 /* polynomial 0x04c10db7 */
869 static const uint32_t crc32_lookup[16] =
870 { /* lookup table for 4 bits at a time is affordable */
871 0x00000000, 0x04C10DB7, 0x09821B6E, 0x0D4316D9,
872 0x130436DC, 0x17C53B6B, 0x1A862DB2, 0x1E472005,
873 0x26086DB8, 0x22C9600F, 0x2F8A76D6, 0x2B4B7B61,
874 0x350C5B64, 0x31CD56D3, 0x3C8E400A, 0x384F4DBD
875 };
876
877 uint32_t crc32 = 0;
878 unsigned char byte;
879 uint32_t t;
880
881 while (len--)
882 {
883 byte = *buf++; /* get one byte of data */
884
885 /* upper nibble of our data */
886 t = crc32 >> 28; /* extract the 4 most significant bits */
887 t ^= byte >> 4; /* XOR in 4 bits of data into the extracted bits */
888 crc32 <<= 4; /* shift the CRC register left 4 bits */
889 crc32 ^= crc32_lookup[t]; /* do the table lookup and XOR the result */
890
891 /* lower nibble of our data */
892 t = crc32 >> 28; /* extract the 4 most significant bits */
893 t ^= byte & 0x0F; /* XOR in 4 bits of data into the extracted bits */
894 crc32 <<= 4; /* shift the CRC register left 4 bits */
895 crc32 ^= crc32_lookup[t]; /* do the table lookup and XOR the result */
896 }
897
898 return crc32;
899}
900
901struct crc_type_desc_t crc_types[] =
902{
903 {CRC_RKW, "RKW", crc_rkw}
904};
905
906int my_lua_crc_buf(lua_State *state)
907{
908 int n = lua_gettop(state);
909 if(n != 2)
910 return luaL_error(state, "crc_buf takes two arguments: a crc type and a buffer");
911 unsigned type = lua_tounsigned(state, 1);
912 size_t len;
913 void *buf = my_lua_get_buffer(state, 2, &len);
914 for(int i = 0; i < ARRAYLEN(crc_types); i++)
915 if(crc_types[i].type == type)
916 {
917 lua_pushunsigned(state, crc_types[i].fn(buf, len));
918 free(buf);
919 return 1;
920 }
921 free(buf);
922 luaL_error(state, "crc_buf: unknown crc type");
923 return 0;
924}
925
852/* compute MD5 sum of a buffer */ 926/* compute MD5 sum of a buffer */
853static bool compute_md5sum_buf(void *buf, size_t sz, uint8_t file_md5sum[16]) 927static bool compute_md5sum_buf(void *buf, size_t sz, uint8_t file_md5sum[16])
854{ 928{
@@ -945,6 +1019,17 @@ static bool init_lua_hwp(void)
945 lua_pushcfunction(g_lua, my_lua_md5sum); 1019 lua_pushcfunction(g_lua, my_lua_md5sum);
946 lua_setfield(g_lua, -2, "md5sum"); 1020 lua_setfield(g_lua, -2, "md5sum");
947 1021
1022 lua_newtable(g_lua);
1023 for(int i = 0; i < ARRAYLEN(crc_types); i++)
1024 {
1025 lua_pushunsigned(g_lua, crc_types[i].type);
1026 lua_setfield(g_lua, -2, crc_types[i].lua_name);
1027 }
1028 lua_setfield(g_lua, -2, "CRC");
1029
1030 lua_pushcfunction(g_lua, my_lua_crc_buf);
1031 lua_setfield(g_lua, -2, "crc_buf");
1032
948 return true; 1033 return true;
949} 1034}
950 1035
diff --git a/utils/hwpatcher/lib.lua b/utils/hwpatcher/lib.lua
index 7a3e4a4115..4c0d6ff7ab 100644
--- a/utils/hwpatcher/lib.lua
+++ b/utils/hwpatcher/lib.lua
@@ -8,16 +8,21 @@ At global level:
8- exit() Same as quit() 8- exit() Same as quit()
9 9
10In the hwp table: 10In the hwp table:
11- load_file(filename) Load a firmware and guess type 11- load_file(filename) Load a firmware and guess type
12- load_elf_file(filename) Load a firmware as ELF 12- load_elf_file(filename) Load a firmware as ELF
13- load_sb_file(filename) Load a firmware as SB 13- load_sb_file(filename) Load a firmware as SB
14- load_sb1_file(filename) Load a firmware as SB1 14- load_sb1_file(filename) Load a firmware as SB1
15- load_bin_file(filename) Load a firmware as binary 15- load_bin_file(filename) Load a firmware as binary
16- save_file(obj, filename) Save a firmware to a file 16- save_file(fw, filename) Save a firmware to a file
17- read(obj, addr, len) Read data from a firmware 17- read(fw, addr, len) Read data from a firmware
18- write(obj, addr, data) Write data to a firmware 18- write(fw, addr, data) Write data to a firmware
19- section_info(obj, sec) Return information about a section in a table (or nil) 19- section_info(fw, sec) Return information about a section in a table (or nil)
20- md5sum(filename) Compute the MD5 sum of a file 20- md5sum(filename) Compute the MD5 sum of a file
21- crc_buf(crc_type, buf) Compute the CRC of a byte buffer and return a byte buffer
22- crc(crc_type, fw, addr, len) Compute the CRC of a firmware part
23
24The list of CRCs available is available the hwp.CRC table:
25- RKW
21 26
22Data read/written from/to a firmware must must be an array of bytes. 27Data read/written from/to a firmware must must be an array of bytes.
23The address must be a table of the following fields: 28The address must be a table of the following fields:
@@ -27,7 +32,7 @@ Data section information is a table with the following fields:
27- address: first address if the section 32- address: first address if the section
28- size: size of the section 33- size: size of the section
29We provide the following functions to help dealing with addresses: 34We provide the following functions to help dealing with addresses:
30- make_addr 35- make_addr(addr, section) Build a firmware address from a raw address and a section
31 36
32]]-- 37]]--
33 38
@@ -105,3 +110,8 @@ function hwp.md5str(md5)
105 end 110 end
106 return s 111 return s
107end 112end
113
114-- compute the CRC of a firmware part
115function hwp.crc(crc_type, fw, addr, len)
116 return hwp.crc_buf(crc_type, hwp.read(fw, addr, len))
117end