📄 e100boot.c
字号:
/*!****************************************************************************!*! FILE NAME : e100boot.c*!*! DESCRIPTION: Network boot loader for Axis ETRAX100 chip.*!*! ---------------------------------------------------------------------------*! HISTORY*!*! DATE NAME CHANGES*! ---- ---- -------*! Dec 26 2001 Andrey Filippov Added control sum generation (requires CBL changes)*! Dec 21 2001 Andrey Filippov Added single file output (--tofile)*! ??? ? ???? Ronny Ranerup Initial version*! Jul 3 2000 Johan Adolfsson Added this header and added Log tag*! $Log: e100boot.c,v $*! Revision 1.17 2001/02/19 13:53:05 larsv*! Added "--pause" option from ASIC's version (needed to initialize SDRAM).*! Increased size of command buffer.*!*! Revision 1.16 2001/01/08 10:55:03 tobiasa*! Made it portable to *BSD.*!*! Revision 1.15 2000/12/18 16:55:55 jonashg*! Corrected help output of sbl (which depends on how it was invoked).*! Added --help option to sbl.*!*! Revision 1.14 2000/11/09 10:18:21 johana*! If EPERM, write message that the program must be executed as root.*!*! Revision 1.13 2000/09/18 14:24:14 pkj*! Do not dump core if no --file option is given.*!*! Revision 1.12 2000/09/12 13:18:06 orjanf*! Applied patch by Ronny Ranerup to fix boot loading with padded packets.*!*! Revision 1.11 2000/07/03 17:10:30 johana*! Makefile.in*!*! ---------------------------------------------------------------------------*! (C) Copyright 1999, 2000, Axis Communications AB, LUND, SWEDEN*!***************************************************************************//* * tools/e100boot/sbl/e100boot.c * $Id: e100boot.c,v 1.17 2001/02/19 13:53:05 larsv Exp $ *//************************** Version **************************************/char version[] = "Time-stamp: $Id: e100boot.c,v 1.17 2001/02/19 13:53:05 larsv Exp $";/************************** Include files ********************************/#include <conf.h>#include <pcap.h>#include <svinto_boot.h>#include <sys/ioctl.h>#include "boot_images.h"#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)#include <sys/types.h>#include <sys/sysctl.h>#include <sys/param.h>#include <sys/socket.h>#include <sys/time.h>#include <netdb.h>#include <net/if_dl.h>#include <net/if_types.h>#include <net/route.h>#include <net/bpf.h>#include <netinet/in.h>#include <netinet/in_var.h>#include <arpa/inet.h>#endif/************************** Constants and macros *************************/#define MEMTEST 0#if MEMTESTunsigned long malloc_tot = 0;unsigned long malloc_cnt = 0;unsigned long free_cnt = 0;unsigned long free_tot = 0;void ugly_check(int line);void *tst_malloc(size_t s, int line){ void *m = malloc(s); malloc_cnt++; ugly_check(line); malloc_tot += s; printf("malloc #%4i: %-8i 0x%08X on line: %5i tot %-8lu \n", malloc_cnt, s, m, line, malloc_tot); return m;}void *tst_calloc(size_t n, size_t s, int line){ void *m = calloc(n, s); malloc_cnt++; ugly_check(line); malloc_tot += s; printf("calloc #%4i: %-8i 0x%08X on line: %5i tot %-8lu \n", malloc_cnt, s, m, line, malloc_tot); return m;}void tst_free(void *m, int line){ ugly_check(line); free(m); free_cnt++; printf("free #%4i: 0x%08X on line: %5i\n", free_cnt,m, line);}#define malloc(s) tst_malloc(s, __LINE__)#define calloc(n, s) tst_calloc(n, s, __LINE__)#define free(m) tst_free(m, __LINE__)#endif #define UDEC 0#define CHAR 1#define ASCII 2#define HEX 3#define CRC_LEN 4#define DATA_SIZE 1460#define SIZE_OF_FIRST_HEADER (sizeof(struct packet_header_T)-8)#define PACKET_SIZE (DATA_SIZE + sizeof(struct packet_header_T))#define SIZE_OF_BOOT_CMDS (0x200-CRC_LEN)#define SNAP1 0xaaaa0300#define SNAP2 0x408c8856#define SERVER_TAG 0xffffffff#define CLIENT_TAG 0xfffffffe#define BOOT_ADDRESS 0x380000f4/************************** Type definitions *****************************//************************** Global variables *****************************/int doing_flash = FALSE; /* Just a flag to see if we should warn that it might take some time. */udword highest_ack_received;udword last_ack_received = -1;int new_ack = FALSE;int got_new_packet = FALSE;int toFiles = FALSE;char ofilename[256]; //AndreyFILE *singlefd=NULL; //Added by Andrey for writing a single fileint nACK=0; //Added by Andrey for counting accepted packetsint nREJ=0; //Added by Andrey for counting rejected packetsint one_id_only = TRUE;int all_ids = TRUE;udword id;struct boot_files_T { char *fileName; udword *size_p; /* Pointer to size in boot_cmds. */ udword size; /* size of file */ udword size_sent; /* Number of bytes sent so far */ struct boot_files_T *next; FILE *fd;};struct packet_buf { udword size; struct packet_buf *next; udword seq; char *data; struct boot_files_T *boot_file;};struct packet_buf *first_packet = NULL;struct packet_buf *last_packet = NULL;struct packet_buf first_rec_packet;struct packet_buf *last_rec_packet = &first_rec_packet;struct packet_buf *boot_cmds_packet;int create_boot_loader = TRUE;/* We use the INTERNAL boot image as default */char boot_loader_file[256] = "INTERNAL";struct boot_files_T *first_boot_file = NULL;struct boot_files_T *last_boot_file = NULL;unsigned int boot_cmds[512/sizeof(unsigned int)];int boot_cmds_cnt = 0;struct sockaddr sock_addr;int sock_fd;int svboot = FALSE;#ifdef __linux__char device[100] = "eth0";#elsechar device[6];#endifint both_addresses = FALSE;int p_packet_bpl = 8;int printPacketType = CHAR;pcap_t *pd;pcap_handler handler;char host1[100];char host2[100];const struct pcap_pkthdr *hdrG;int db1 = 0;int db2 = 0;int db3 = 0;int db4 = 0;int quiet = 0;int promisc = 0;int pPacket = 0;unsigned char buf[100000];unsigned char dst_addr_of_device[] = { 0x01, 0x40, 0x8c, 0x00, 0x01, 0x00 };unsigned char src_addr_of_device[] = { 0x02, 0x40, 0x8c, 0x00, 0x01, 0x00 };unsigned char eth_addr_local[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };struct packet_header_T send_packet;struct packet_header_T *receive_packet;int seq_nr = 0;#if 0#define D() ugly_check(__LINE__)void ugly_check(int line){ static int last_ok = 0; if (last_boot_file->size != *last_boot_file->size_p) { printf("**** size mismatch detected: line %i (prev: %i\n", line, last_ok); } else { last_ok = line; }}#else#define D()#endif/************************** Function prototypes **************************/void FinishBootCmds();int timeout(struct timeval *tvThen, int ms);struct packet_buf* packet_with_seq(int seq);int highest_seq_received();FILE *Fopen(char *name, char *mode);void CreateBootLoader();void DecodeSvintoBoot(const unsigned char *p);void GetLocalEthAddr();int GetNumberOption(int *argNr, int argCount, char *argVect[], unsigned int *ret, char *option, int base);int GetStringOption (int *argNr, int argCount, char *argVect[], char *ret, char *option);void GetNextPacket();void Handler(unsigned char *buf, const struct pcap_pkthdr *hdr, const unsigned char *p);int InitSendSocket(char *device_name);void ParseArgs (int argc, char *argv[]);void PrintHelp();void PrintPacket(const unsigned char *p, int size, int type);void SendToDevice(unsigned char *data, int data_len);void SigHandler(int sig);int main(int argc, char *argv[]);struct packet_buf* ack_on_seq(int seq);void CreateBootCmds();struct timeval timeval_subtract(struct timeval *x, struct timeval *y);struct packet_buf* create_packet(udword seq);struct packet_buf* free_packet(struct packet_buf *p);struct packet_buf* create_packet(udword seq);struct packet_buf* allocate_packet(struct packet_buf *p);struct boot_files_T* allocate_boot_file(struct boot_files_T *bf);struct packet_buf* CreateNewBootPacket();/*****************************************************************************#*# FUNCTION NAME: main*#*# PARAMETERS: Command line arguments.*#*#---------------------------------------------------------------------------*# HISTORY*#*# DATE NAME CHANGES*# ---- ---- -------*# 961022 ronny Initial version*#*#***************************************************************************/intmain(int argc, char *argv[]){ struct packet_buf *p; char *dev; char errBuf[1000]; struct timeval tv; gettimeofday(&tv, NULL); /* signal(SIGINT, SigHandler);*/ srand(time(NULL)); ParseArgs(argc, argv); D(); GetLocalEthAddr(); D(); first_rec_packet.data = malloc(PACKET_SIZE); if ((dev = pcap_lookupdev(errBuf)) == NULL) { printf("Error %s\n", errBuf); if (errno == EPERM) { printf("Make sure this program is executed as root user or is setuid as root\n"); } exit(1); } if ((pd = pcap_open_live(device, 100, promisc, 10, errBuf)) == NULL) { printf("Error %s\n", errBuf); if (errno == EPERM) { printf("Make sure the program (%s) is executed as root user,\n" "or is setuid as root by doing (as root using su or sudo): \n" " \"chown root.root %s; chmod 6755 %s\"\n" "in the directory it was installed, or simply doing\n" " \"make install\"\n" "in tools/e100boot/ directory (as root).\n", argv[0], argv[0], argv[0]); } exit(1); } handler = (pcap_handler) Handler; InitSendSocket(device); CreateBootLoader(); CreateBootCmds(); FinishBootCmds(); /* ? */ printf("Starting boot...\n"); if (doing_flash) { printf("We're doing a flash write, this may take up to a few minutes...\n"); } p = create_packet(0); if (singlefd) { // added by Andrey udword seq = 0; while(p) { if ((p = create_packet(seq++))) { D(); SendToDevice(p->data, p->size); } } fclose(singlefd); printf ("Created file %s to be loaded by other eboot loader\n",ofilename); exit(0); } if (toFiles) { udword seq = 0; while(p) { if ((p = create_packet(seq++))) { D(); SendToDevice(p->data, p->size); } } exit(0); } SendToDevice(p->data, p->size); do { if (got_new_packet) { got_new_packet = FALSE; if (new_ack) {// printf("* got ACK %d.\n", last_ack_received);// printf("* ACK wanted %d.\n", first_packet->seq); if (last_ack_received == first_packet->seq) { // printf("* got ACK %d for first_packet.\n", last_ack_received); if (!(p = create_packet(first_packet->seq+1))) { break; } first_packet = free_packet(first_packet); } } } if (new_ack || timeout(&tv, 1000)) { SendToDevice(p->data, p->size); new_ack = FALSE; gettimeofday(&tv, NULL); } GetNextPacket(); } while(1); printf("Packets accepted - %d\nPackets rejected - %d\n",nACK,nREJ); //Added by Andrey for counting packets printf("Done.\n"); return 0;} /* main */struct packet_buf* free_packet(struct packet_buf *p) { struct packet_buf *next_p; next_p = p->next; free(p->data); free(p); return(next_p);}/*****************************************************************************#*# FUNCTION NAME: create_packet*#*# PARAMETERS: Sequence number of desired packet.*#*# DESCRIPTION: *#*#---------------------------------------------------------------------------*# HISTORY*#*# DATE NAME CHANGES*# ---- ---- -------*# 2000 06 28 ronny Initial version*#*#***************************************************************************/struct packet_buf*create_packet(udword seq){ struct packet_buf *p = first_packet; /* Should check last first? */ while (p) { if (p->seq == seq) { return(p); } p = p->next; } return(CreateNewBootPacket());}/*****************************************************************************#*# FUNCTION NAME: GetNextPacket*#*# PARAMETERS: *#*# DESCRIPTION: *#*#---------------------------------------------------------------------------*# HISTORY*#*# DATE NAME CHANGES*# ---- ---- -------*# 961022 ronny Initial version*#*#***************************************************************************/voidGetNextPacket(){ int ret; if (db1) printf("> GetNextPacket\n"); do { /* got_new_packet = FALSE;*/ if ((ret = pcap_dispatch(pd, 1, handler, buf)) == -1) { pcap_perror(pd, "Error in pcap_dispatch"); exit(1); } } while(!got_new_packet); if (db1) printf("< GetNextPacket\n");}/*****************************************************************************#*# FUNCTION NAME: Handler*#*# PARAMETERS: *#*# DESCRIPTION: *#*#---------------------------------------------------------------------------*# HISTORY*#*# DATE NAME CHANGES*# ---- ---- -------*# 961022 ronny Initial version*#*#***************************************************************************/voidHandler(unsigned char *buf, const struct pcap_pkthdr *hdr, const unsigned char *p){ const unsigned char *src = &p[6]; const unsigned char *dst = &p[0]; struct packet_header_T *h = (struct packet_header_T*)p; D(); if (db2) printf("> Handler\n"); got_new_packet = TRUE; if ((!memcmp(src, eth_addr_local, 6) && !memcmp(dst, dst_addr_of_device, 6)) || (!memcmp(src, src_addr_of_device, 6) && !memcmp(dst, eth_addr_local, 6))) { if (db1) printf("#RX######################################################\n"); if (db1) printf("Length: %u(0x%x)\n", (udword)hdr->len, (udword)hdr->len); if (pPacket) PrintPacket(p, hdr->caplen, printPacketType); if (db1) DecodeSvintoBoot(p); if ((ntohl(h->type) == ACK)) { if (all_ids || (ntohl(h->id) == id)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -