diff options
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c')
-rw-r--r-- | firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c b/firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c new file mode 100644 index 0000000000..c794da4000 --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c | |||
@@ -0,0 +1,195 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2021 Aidan MacDonald | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "installer.h" | ||
23 | #include "nand-x1000.h" | ||
24 | #include "core_alloc.h" | ||
25 | #include "file.h" | ||
26 | |||
27 | #define INSTALL_SUCCESS 0 | ||
28 | #define ERR_FLASH_OPEN_FAILED (-1) | ||
29 | #define ERR_FLASH_ENABLE_WP_FAILED (-2) | ||
30 | #define ERR_FLASH_DISABLE_WP_FAILED (-3) | ||
31 | #define ERR_FLASH_ERASE_FAILED (-4) | ||
32 | #define ERR_FLASH_WRITE_FAILED (-5) | ||
33 | #define ERR_FLASH_READ_FAILED (-6) | ||
34 | #define ERR_OUT_OF_MEMORY (-7) | ||
35 | #define ERR_CANNOT_READ_FILE (-8) | ||
36 | #define ERR_CANNOT_WRITE_FILE (-9) | ||
37 | #define ERR_WRONG_SIZE (-10) | ||
38 | |||
39 | #define BOOT_IMAGE_SIZE (128 * 1024) | ||
40 | |||
41 | static int install_from_buffer(const void* buf) | ||
42 | { | ||
43 | if(nand_open()) | ||
44 | return ERR_FLASH_OPEN_FAILED; | ||
45 | |||
46 | int status = INSTALL_SUCCESS; | ||
47 | |||
48 | if(nand_enable_writes(true)) { | ||
49 | status = ERR_FLASH_DISABLE_WP_FAILED; | ||
50 | goto _exit; | ||
51 | } | ||
52 | |||
53 | if(nand_erase_block(0)) { | ||
54 | status = ERR_FLASH_ERASE_FAILED; | ||
55 | goto _exit; | ||
56 | } | ||
57 | |||
58 | if(nand_write_bytes(0, BOOT_IMAGE_SIZE, buf)) { | ||
59 | status = ERR_FLASH_WRITE_FAILED; | ||
60 | goto _exit; | ||
61 | } | ||
62 | |||
63 | if(nand_enable_writes(false)) { | ||
64 | status = ERR_FLASH_ENABLE_WP_FAILED; | ||
65 | goto _exit; | ||
66 | } | ||
67 | |||
68 | _exit: | ||
69 | nand_close(); | ||
70 | return status; | ||
71 | } | ||
72 | |||
73 | static int dump_to_buffer(void* buf) | ||
74 | { | ||
75 | if(nand_open()) | ||
76 | return ERR_FLASH_OPEN_FAILED; | ||
77 | |||
78 | int status = INSTALL_SUCCESS; | ||
79 | |||
80 | if(nand_read_bytes(0, BOOT_IMAGE_SIZE, buf)) { | ||
81 | status = ERR_FLASH_READ_FAILED; | ||
82 | goto _exit; | ||
83 | } | ||
84 | |||
85 | _exit: | ||
86 | nand_close(); | ||
87 | return status; | ||
88 | } | ||
89 | |||
90 | int install_bootloader(const char* path) | ||
91 | { | ||
92 | /* Allocate memory to hold image */ | ||
93 | int handle = core_alloc("boot_image", BOOT_IMAGE_SIZE); | ||
94 | if(handle < 0) | ||
95 | return ERR_OUT_OF_MEMORY; | ||
96 | |||
97 | int status = INSTALL_SUCCESS; | ||
98 | void* buffer = core_get_data(handle); | ||
99 | |||
100 | /* Open the boot image */ | ||
101 | int fd = open(path, O_RDONLY); | ||
102 | if(fd < 0) { | ||
103 | status = ERR_CANNOT_READ_FILE; | ||
104 | goto _exit; | ||
105 | } | ||
106 | |||
107 | /* Check file size */ | ||
108 | off_t fsize = filesize(fd); | ||
109 | if(fsize != BOOT_IMAGE_SIZE) { | ||
110 | status = ERR_WRONG_SIZE; | ||
111 | goto _exit; | ||
112 | } | ||
113 | |||
114 | /* Read the file into the buffer */ | ||
115 | ssize_t cnt = read(fd, buffer, BOOT_IMAGE_SIZE); | ||
116 | if(cnt != BOOT_IMAGE_SIZE) { | ||
117 | status = ERR_CANNOT_READ_FILE; | ||
118 | goto _exit; | ||
119 | } | ||
120 | |||
121 | /* Perform the installation */ | ||
122 | status = install_from_buffer(buffer); | ||
123 | |||
124 | _exit: | ||
125 | if(fd >= 0) | ||
126 | close(fd); | ||
127 | core_free(handle); | ||
128 | return status; | ||
129 | } | ||
130 | |||
131 | /* Dump the current bootloader to a file */ | ||
132 | int dump_bootloader(const char* path) | ||
133 | { | ||
134 | /* Allocate memory to hold image */ | ||
135 | int handle = core_alloc("boot_image", BOOT_IMAGE_SIZE); | ||
136 | if(handle < 0) | ||
137 | return -1; | ||
138 | |||
139 | /* Read data from flash */ | ||
140 | int fd = -1; | ||
141 | void* buffer = core_get_data(handle); | ||
142 | int status = dump_to_buffer(buffer); | ||
143 | if(status) | ||
144 | goto _exit; | ||
145 | |||
146 | /* Open file */ | ||
147 | fd = open(path, O_CREAT|O_TRUNC|O_WRONLY); | ||
148 | if(fd < 0) { | ||
149 | status = ERR_CANNOT_WRITE_FILE; | ||
150 | goto _exit; | ||
151 | } | ||
152 | |||
153 | /* Write data to file */ | ||
154 | ssize_t cnt = write(fd, buffer, BOOT_IMAGE_SIZE); | ||
155 | if(cnt != BOOT_IMAGE_SIZE) { | ||
156 | status = ERR_CANNOT_WRITE_FILE; | ||
157 | goto _exit; | ||
158 | } | ||
159 | |||
160 | _exit: | ||
161 | if(fd >= 0) | ||
162 | close(fd); | ||
163 | core_free(handle); | ||
164 | return status; | ||
165 | } | ||
166 | |||
167 | const char* installer_strerror(int rc) | ||
168 | { | ||
169 | switch(rc) { | ||
170 | case INSTALL_SUCCESS: | ||
171 | return "Success"; | ||
172 | case ERR_FLASH_OPEN_FAILED: | ||
173 | return "Can't open flash device"; | ||
174 | case ERR_FLASH_ENABLE_WP_FAILED: | ||
175 | return "Couldn't re-enable write protect"; | ||
176 | case ERR_FLASH_DISABLE_WP_FAILED: | ||
177 | return "Can't disable write protect"; | ||
178 | case ERR_FLASH_ERASE_FAILED: | ||
179 | return "Flash erase failed"; | ||
180 | case ERR_FLASH_WRITE_FAILED: | ||
181 | return "Flash write error"; | ||
182 | case ERR_FLASH_READ_FAILED: | ||
183 | return "Flash read error"; | ||
184 | case ERR_OUT_OF_MEMORY: | ||
185 | return "Out of memory"; | ||
186 | case ERR_CANNOT_READ_FILE: | ||
187 | return "Error reading file"; | ||
188 | case ERR_CANNOT_WRITE_FILE: | ||
189 | return "Error writing file"; | ||
190 | case ERR_WRONG_SIZE: | ||
191 | return "Wrong file size"; | ||
192 | default: | ||
193 | return "Unknown error"; | ||
194 | } | ||
195 | } | ||