diff options
Diffstat (limited to 'utils')
-rw-r--r-- | utils/hwpatcher/hwpatcher.c | 85 | ||||
-rw-r--r-- | utils/hwpatcher/lib.lua | 32 |
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 | |||
50 | lua_State *g_lua; | 52 | lua_State *g_lua; |
51 | bool g_exit = false; | 53 | bool 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 | ||
64 | enum crc_type_t | ||
65 | { | ||
66 | CRC_RKW | ||
67 | }; | ||
68 | |||
69 | struct 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 | |||
62 | struct bin_file_t | 76 | struct 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 | ||
866 | unsigned 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 | |||
901 | struct crc_type_desc_t crc_types[] = | ||
902 | { | ||
903 | {CRC_RKW, "RKW", crc_rkw} | ||
904 | }; | ||
905 | |||
906 | int 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 */ |
853 | static bool compute_md5sum_buf(void *buf, size_t sz, uint8_t file_md5sum[16]) | 927 | static 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 | ||
10 | In the hwp table: | 10 | In 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 | |||
24 | The list of CRCs available is available the hwp.CRC table: | ||
25 | - RKW | ||
21 | 26 | ||
22 | Data read/written from/to a firmware must must be an array of bytes. | 27 | Data read/written from/to a firmware must must be an array of bytes. |
23 | The address must be a table of the following fields: | 28 | The 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 |
29 | We provide the following functions to help dealing with addresses: | 34 | We 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 |
107 | end | 112 | end |
113 | |||
114 | -- compute the CRC of a firmware part | ||
115 | function hwp.crc(crc_type, fw, addr, len) | ||
116 | return hwp.crc_buf(crc_type, hwp.read(fw, addr, len)) | ||
117 | end | ||