diff options
author | Ingo Albrecht <prom@berlin.ccc.de> | 2010-03-07 13:55:28 +0100 |
---|---|---|
committer | Ingo Albrecht <prom@berlin.ccc.de> | 2010-07-20 14:41:19 +0200 |
commit | f499d89dafe001c6eb16ae59dec3862cbbce77bd (patch) | |
tree | e2d40fa051f85668d1ba668df479097b349f4359 /src/host/osmocon | |
parent | 91fa8c59418c220fdd178d6308cdb133657780f3 (diff) |
osmoload: memdump command
Diffstat (limited to 'src/host/osmocon')
-rw-r--r-- | src/host/osmocon/osmoload.c | 240 |
1 files changed, 203 insertions, 37 deletions
diff --git a/src/host/osmocon/osmoload.c b/src/host/osmocon/osmoload.c index d302d955..cf0cb4c6 100644 --- a/src/host/osmocon/osmoload.c +++ b/src/host/osmocon/osmoload.c @@ -43,13 +43,40 @@ static struct bsc_fd connection; +enum { + OPERATION_QUERY, + OPERATION_MEMDUMP, + OPERATION_MEMLOAD, +}; + static struct { + unsigned char print_requests; + unsigned char print_replies; + unsigned char quit; + int operation; + uint8_t command; + + FILE *binfile; + + uint32_t req_length; + uint32_t req_address; + + uint32_t cur_length; + uint32_t cur_address; } osmoload; static int usage(const char *name) { - printf("\nUsage: %s [ -v | -h ] [ -m {c123,c155} ] [ -l /tmp/osmocom_loader ] COMMAND\n", name); + printf("\nUsage: %s [ -v | -h ] [ -d tr ] [ -m {c123,c155} ] [ -l /tmp/osmocom_loader ] COMMAND\n", name); + puts(" memread <hex-length> <hex-address>"); + puts(" memdump <hex-length> <hex-address> <file>"); + puts(" flashloader"); + puts(" romloader"); + puts(" ping"); + puts(" reset"); + puts(" off"); + exit(2); } @@ -74,8 +101,10 @@ loader_send_request(struct msgb *msg) { int rc; u_int16_t len = htons(msg->len); - printf("Sending %d bytes ", msg->len); - hexdump(msg->data, msg->len); + if(osmoload.print_requests) { + printf("Sending %d bytes:\n", msg->len); + hexdump(msg->data, msg->len); + } rc = write(connection.fd, &len, sizeof(len)); if(rc != sizeof(len)) { @@ -90,53 +119,91 @@ loader_send_request(struct msgb *msg) { } } +static void loader_do_memdump(); + static void loader_handle_reply(struct msgb *msg) { + int rc; + + if(osmoload.print_replies) { + printf("Received %d bytes:\n", msg->len); + hexdump(msg->data, msg->len); + } + uint8_t cmd = msgb_get_u8(msg); uint8_t length; uint32_t address; + void *data; + switch(cmd) { case LOADER_PING: - printf("Received pong.\n"); - osmoload.quit = 1; - break; case LOADER_RESET: - printf("Reset confirmed.\n"); - osmoload.quit = 1; - break; case LOADER_POWEROFF: - printf("Poweroff confirmed.\n"); - osmoload.quit = 1; - break; case LOADER_ENTER_ROM_LOADER: - printf("Jump to ROM loader confirmed.\n"); - osmoload.quit = 1; - break; case LOADER_ENTER_FLASH_LOADER: - printf("Jump to flash loader confirmed.\n"); - osmoload.quit = 1; break; case LOADER_MEM_READ: length = msgb_get_u8(msg); address = msgb_get_u32(msg); - printf("Received memory dump of %d bytes at 0x%x:\n", length, address); - hexdump(msgb_get(msg, length), length); - osmoload.quit = 1; + data = msgb_get(msg, length); break; case LOADER_MEM_WRITE: length = msgb_get_u8(msg); address = msgb_get_u32(msg); - printf("Confirmed memory write of %d bytes at 0x%x.\n", length, address); - osmoload.quit = 1; break; default: - printf("Received unknown reply for command %d:\n"); + printf("Received unknown reply %d:\n", cmd); hexdump(msg->data, msg->len); osmoload.quit = 1; break; } + + switch(osmoload.operation) { + case OPERATION_QUERY: + switch(cmd) { + case LOADER_PING: + printf("Received pong.\n"); + break; + case LOADER_RESET: + printf("Reset confirmed.\n"); + break; + case LOADER_POWEROFF: + printf("Poweroff confirmed.\n"); + break; + case LOADER_ENTER_ROM_LOADER: + printf("Jump to ROM loader confirmed.\n"); + break; + case LOADER_ENTER_FLASH_LOADER: + printf("Jump to flash loader confirmed.\n"); + break; + case LOADER_MEM_READ: + printf("Received memory dump of %d bytes at 0x%x:\n", length, address); + hexdump(data, length); + break; + case LOADER_MEM_WRITE: + printf("Confirmed memory write of %d bytes at 0x%x.\n", length, address); + break; + default: + break; + } + if(osmoload.command == cmd) { + osmoload.quit = 1; + } + break; + case OPERATION_MEMDUMP: + if(cmd == LOADER_MEM_READ) { + rc = fwrite(data, 1, length, osmoload.binfile); + if(ferror(osmoload.binfile)) { + printf("Error writing to dump file: %s\n", strerror(errno)); + } + loader_do_memdump(); + } + break; + default: + break; + } } static int @@ -213,21 +280,27 @@ loader_connect(const char *socket_path) { } static void -loader_send_simple(uint8_t command) { +loader_send_query(uint8_t command) { struct msgb *msg = msgb_alloc(MSGB_MAX, "loader"); msgb_put_u8(msg, command); loader_send_request(msg); msgb_free(msg); + + osmoload.operation = OPERATION_QUERY; + osmoload.command = command; } static void loader_send_memread(uint8_t length, uint32_t address) { struct msgb *msg = msgb_alloc(MSGB_MAX, "loader"); msgb_put_u8(msg, LOADER_MEM_READ); - msgb_put_u8(msg, 128); - msgb_put_u32(msg, 0x00810000); + msgb_put_u8(msg, length); + msgb_put_u32(msg, address); loader_send_request(msg); msgb_free(msg); + + osmoload.operation = OPERATION_QUERY; + osmoload.command = LOADER_MEM_READ; } static void @@ -236,9 +309,54 @@ loader_send_memwrite(uint8_t length, uint32_t address, void *data) { msgb_put_u8(msg, LOADER_MEM_WRITE); msgb_put_u8(msg, length); msgb_put_u32(msg, address); - memcpy(msgb_put(msg, 128), data, length); + memcpy(msgb_put(msg, length), data, length); loader_send_request(msg); msgb_free(msg); + + osmoload.operation = OPERATION_QUERY; + osmoload.command = LOADER_MEM_WRITE; +} + +static void +loader_do_memdump() { + uint32_t rembytes = osmoload.req_length - osmoload.cur_length; + + if(!rembytes) { + osmoload.quit = 1; + return; + } + +#define MEM_READ_MAX (MSGB_MAX - 16) + + uint8_t reqbytes = (rembytes < MEM_READ_MAX) ? rembytes : MEM_READ_MAX; + + struct msgb *msg = msgb_alloc(MSGB_MAX, "loader"); + + msgb_put_u8(msg, LOADER_MEM_READ); + msgb_put_u8(msg, reqbytes); + msgb_put_u32(msg, osmoload.cur_address); + loader_send_request(msg); + msgb_free(msg); + + osmoload.cur_address += reqbytes; + osmoload.cur_length += reqbytes; +} + +static void +loader_start_memdump(uint32_t length, uint32_t address, char *file) { + osmoload.operation = OPERATION_MEMDUMP; + osmoload.binfile = fopen(file, "wb"); + if(!osmoload.binfile) { + printf("Could not open %s: %s\n", file, strerror(errno)); + exit(1); + } + osmoload.req_length = length; + osmoload.req_address = address; + + osmoload.cur_length = 0; + osmoload.cur_address = address; + + loader_do_memdump(); } static void @@ -247,41 +365,85 @@ loader_command(char *name, int cmdc, char **cmdv) { usage(name); } - struct msgb *msg; char *cmd = cmdv[0]; char buf[256]; memset(buf, 23, sizeof(buf)); - printf("Command %s\n", cmd); - if(!strcmp(cmd, "ping")) { - loader_send_simple(LOADER_PING); + loader_send_query(LOADER_PING); } else if(!strcmp(cmd, "memread")) { - loader_send_memread(128, 0x810000); + uint8_t length; + uint32_t address; + + if(cmdc < 3) { + usage(name); + } + + length = strtoul(cmdv[1], NULL, 16); + address = strtoul(cmdv[2], NULL, 16); + + loader_send_memread(length, address); + } else if(!strcmp(cmd, "memdump")) { + uint32_t length; + uint32_t address; + + if(cmdc < 4) { + usage(name); + } + + length = strtoul(cmdv[1], NULL, 16); + address = strtoul(cmdv[2], NULL, 16); + + loader_start_memdump(length, address, cmdv[3]); } else if(!strcmp(cmd, "memwrite")) { loader_send_memwrite(128, 0x810000, buf); } else if(!strcmp(cmd, "off")) { - loader_send_simple(LOADER_POWEROFF); + loader_send_query(LOADER_POWEROFF); } else if(!strcmp(cmd, "reset")) { - loader_send_simple(LOADER_RESET); + loader_send_query(LOADER_RESET); } else if(!strcmp(cmd, "romload")) { - loader_send_simple(LOADER_ENTER_ROM_LOADER); + loader_send_query(LOADER_ENTER_ROM_LOADER); } else if(!strcmp(cmd, "flashload")) { - loader_send_simple(LOADER_ENTER_FLASH_LOADER); + loader_send_query(LOADER_ENTER_FLASH_LOADER); + } else if(!strcmp(cmd, "help")) { + usage(name); } else { printf("Unknown command '%s'\n", cmd); usage(name); } } +void +setdebug(const char *name, char c) { + switch(c) { + case 't': + osmoload.print_requests = 1; + break; + case 'r': + osmoload.print_replies = 1; + break; + default: + usage(name); + break; + } +} + int main(int argc, char **argv) { int opt; char *loader_un_path = "/tmp/osmocom_loader"; + const char *debugopt; - while((opt = getopt(argc, argv, "hl:m:v")) != -1) { + while((opt = getopt(argc, argv, "d:hl:m:v")) != -1) { switch(opt) { + case 'd': + debugopt = optarg; + while(*debugopt) { + setdebug(argv[0], *debugopt); + debugopt++; + } + break; case 'l': loader_un_path = optarg; break; @@ -309,5 +471,9 @@ main(int argc, char **argv) { bsc_select_main(0); } + if(osmoload.binfile) { + fclose(osmoload.binfile); + } + return 0; } |