1 /* control utility for the Calypso bootloader */
3 /* (C) 2010 by Ingo Albrecht <prom@berlin.ccc.de>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include <arpa/inet.h>
32 #include <sys/socket.h>
35 #include <osmocore/msgb.h>
36 #include <osmocore/select.h>
38 #include <loader/protocol.h>
42 #define DEFAULT_SOCKET "/tmp/osmocom_loader"
44 static struct bsc_fd connection;
50 static int usage(const char *name)
52 printf("\nUsage: %s [ -v | -h ] [ -m {c123,c155} ] [ -l /tmp/osmocom_loader ] COMMAND\n", name);
56 static int version(const char *name)
58 //printf("\n%s version %s\n", name, VERSION);
62 static void hexdump(const uint8_t *data, unsigned int len)
64 const uint8_t *bufptr = data;
67 for (n=0; n < len; n++, bufptr++)
68 printf("%02x ", *bufptr);
73 loader_send_request(struct msgb *msg) {
75 u_int16_t len = htons(msg->len);
77 printf("Sending %d bytes ", msg->len);
78 hexdump(msg->data, msg->len);
80 rc = write(connection.fd, &len, sizeof(len));
81 if(rc != sizeof(len)) {
82 fprintf(stderr, "Error writing.\n");
86 rc = write(connection.fd, msg->data, msg->len);
88 fprintf(stderr, "Error writing.\n");
94 loader_handle_reply(struct msgb *msg) {
95 uint8_t cmd = msgb_get_u8(msg);
102 printf("Received pong.\n");
106 printf("Reset confirmed.\n");
109 case LOADER_POWEROFF:
110 printf("Poweroff confirmed.\n");
113 case LOADER_ENTER_ROM_LOADER:
114 printf("Jump to ROM loader confirmed.\n");
117 case LOADER_ENTER_FLASH_LOADER:
118 printf("Jump to flash loader confirmed.\n");
121 case LOADER_MEM_READ:
122 length = msgb_get_u8(msg);
123 address = msgb_get_u32(msg);
124 printf("Received memory dump of %d bytes at 0x%x:\n", length, address);
125 hexdump(msgb_get(msg, length), length);
128 case LOADER_MEM_WRITE:
129 length = msgb_get_u8(msg);
130 address = msgb_get_u32(msg);
131 printf("Confirmed memory write of %d bytes at 0x%x.\n", length, address);
135 printf("Received unknown reply for command %d:\n");
136 hexdump(msg->data, msg->len);
143 loader_read_cb(struct bsc_fd *fd, unsigned int flags) {
148 msg = msgb_alloc(MSGB_MAX, "loader");
150 fprintf(stderr, "Failed to allocate msg.\n");
154 rc = read(fd->fd, &len, sizeof(len));
155 if (rc < sizeof(len)) {
156 fprintf(stderr, "Short read. Error.\n");
160 if (ntohs(len) > MSGB_MAX) {
161 fprintf(stderr, "Length is too big: %u\n", ntohs(len));
166 /* blocking read for the poor... we can starve in here... */
167 msg->l2h = msgb_put(msg, ntohs(len));
168 rc = read(fd->fd, msg->l2h, msgb_l2len(msg));
169 if (rc != msgb_l2len(msg)) {
170 fprintf(stderr, "Can not read data: rc: %d errno: %d\n", rc, errno);
175 loader_handle_reply(msg);
183 loader_connect(const char *socket_path) {
185 struct sockaddr_un local;
186 struct bsc_fd *conn = &connection;
188 local.sun_family = AF_UNIX;
189 strncpy(local.sun_path, socket_path, sizeof(local.sun_path));
190 local.sun_path[sizeof(local.sun_path) - 1] = '\0';
192 conn->fd = socket(AF_UNIX, SOCK_STREAM, 0);
194 fprintf(stderr, "Failed to create unix domain socket.\n");
198 rc = connect(conn->fd, (struct sockaddr *) &local,
199 sizeof(local.sun_family) + strlen(local.sun_path));
201 fprintf(stderr, "Failed to connect to '%s'.\n", local.sun_path);
205 conn->when = BSC_FD_READ;
206 conn->cb = loader_read_cb;
209 if (bsc_register_fd(conn) != 0) {
210 fprintf(stderr, "Failed to register fd.\n");
216 loader_send_simple(uint8_t command) {
217 struct msgb *msg = msgb_alloc(MSGB_MAX, "loader");
218 msgb_put_u8(msg, command);
219 loader_send_request(msg);
224 loader_send_memread(uint8_t length, uint32_t address) {
225 struct msgb *msg = msgb_alloc(MSGB_MAX, "loader");
226 msgb_put_u8(msg, LOADER_MEM_READ);
227 msgb_put_u8(msg, 128);
228 msgb_put_u32(msg, 0x00810000);
229 loader_send_request(msg);
234 loader_send_memwrite(uint8_t length, uint32_t address, void *data) {
235 struct msgb *msg = msgb_alloc(MSGB_MAX, "loader");
236 msgb_put_u8(msg, LOADER_MEM_WRITE);
237 msgb_put_u8(msg, length);
238 msgb_put_u32(msg, address);
239 memcpy(msgb_put(msg, 128), data, length);
240 loader_send_request(msg);
245 loader_command(char *name, int cmdc, char **cmdv) {
254 memset(buf, 23, sizeof(buf));
256 printf("Command %s\n", cmd);
258 if(!strcmp(cmd, "ping")) {
259 loader_send_simple(LOADER_PING);
260 } else if(!strcmp(cmd, "memread")) {
261 loader_send_memread(128, 0x810000);
262 } else if(!strcmp(cmd, "memwrite")) {
263 loader_send_memwrite(128, 0x810000, buf);
264 } else if(!strcmp(cmd, "off")) {
265 loader_send_simple(LOADER_POWEROFF);
266 } else if(!strcmp(cmd, "reset")) {
267 loader_send_simple(LOADER_RESET);
268 } else if(!strcmp(cmd, "romload")) {
269 loader_send_simple(LOADER_ENTER_ROM_LOADER);
270 } else if(!strcmp(cmd, "flashload")) {
271 loader_send_simple(LOADER_ENTER_FLASH_LOADER);
273 printf("Unknown command '%s'\n", cmd);
279 main(int argc, char **argv) {
281 char *loader_un_path = "/tmp/osmocom_loader";
283 while((opt = getopt(argc, argv, "hl:m:v")) != -1) {
286 loader_un_path = optarg;
289 puts("model selection not implemented");
304 loader_connect(loader_un_path);
306 loader_command(argv[0], argc - optind, argv + optind);
308 while(!osmoload.quit) {