Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 2 commits
  • 6 files changed
  • 0 comments
  • 1 contributor
11  software/include/hw/flash.h
... ...
@@ -1,6 +1,6 @@
1 1
 /*
2 2
  * Milkymist SoC (Software)
3  
- * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
  3
+ * Copyright (C) 2007, 2008, 2009, 2010, 2012 Sebastien Bourdeauducq
4 4
  *
5 5
  * This program is free software: you can redistribute it and/or modify
6 6
  * it under the terms of the GNU General Public License as published by
@@ -22,13 +22,12 @@
22 22
 
23 23
 #define FLASH_OFFSET_RESCUE_BITSTREAM	(0x000A0000) /* 1536k */
24 24
 #define FLASH_OFFSET_RESCUE_BIOS	(0x00220000) /* 128k */
25  
-#define FLASH_OFFSET_MAC_ADDRESS	(0x002200E0) /* within rescue BIOS */
26  
-#define FLASH_OFFSET_RESCUE_SPLASH	(0x00240000) /* 640k */
27  
-#define FLASH_OFFSET_RESCUE_APP		(0x002E0000) /* 4096k */
  25
+#define FLASH_OFFSET_RESCUE_APP		(0x00240000) /* 4736k */
28 26
 
29 27
 #define FLASH_OFFSET_REGULAR_BITSTREAM	(0x006E0000) /* 1536k */
30 28
 #define FLASH_OFFSET_REGULAR_BIOS	(0x00860000) /* 128k */
31  
-#define FLASH_OFFSET_REGULAR_SPLASH	(0x00880000) /* 640k */
32  
-#define FLASH_OFFSET_REGULAR_APP	(0x00920000) /* remaining space (23424k) */
  29
+#define FLASH_OFFSET_REGULAR_APP	(0x00880000) /* remaining space (24064k) */
  30
+
  31
+#define FLASH_OFFSET_MAC_ADDRESS	(0x002200E0) /* within rescue BIOS */
33 32
 
34 33
 #endif /* __HW_FLASH_H */
16  tools/Makefile
... ...
@@ -0,0 +1,16 @@
  1
+TARGETS=bin2hex mkmmimg flterm
  2
+CC=clang
  3
+
  4
+all: $(TARGETS)
  5
+
  6
+%: %.c
  7
+	$(CC) -O2 -Wall -I. -s -o $@ $<
  8
+
  9
+install: mkmmimg flterm
  10
+	cp mkmmimg /usr/bin
  11
+	cp flterm /usr/bin
  12
+
  13
+.PHONY: clean install
  14
+
  15
+clean:
  16
+	rm -f $(TARGETS)
83  tools/bin2hex.c
... ...
@@ -0,0 +1,83 @@
  1
+/*
  2
+ * Milkymist SoC
  3
+ * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
  4
+ *
  5
+ * This program is free software: you can redistribute it and/or modify
  6
+ * it under the terms of the GNU General Public License as published by
  7
+ * the Free Software Foundation, version 3 of the License.
  8
+ *
  9
+ * This program is distributed in the hope that it will be useful,
  10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12
+ * GNU General Public License for more details.
  13
+ *
  14
+ * You should have received a copy of the GNU General Public License
  15
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16
+ */
  17
+ 
  18
+/* WARNING: This tool is little endian in 16-bit mode 
  19
+ * and big endian in 32-bit mode. 
  20
+ */
  21
+
  22
+#include <stdlib.h>
  23
+#include <string.h>
  24
+#include <stdio.h>
  25
+
  26
+int main(int argc, char *argv[])
  27
+{
  28
+	int i;
  29
+	int pad;
  30
+	FILE *fdi, *fdo;
  31
+	unsigned char w[4];
  32
+	int mode16;
  33
+	
  34
+	if((argc != 4) && (argc != 5)) {
  35
+		fprintf(stderr, "Usage: bin2hex <infile> <outfile> <size> [16]\n");
  36
+		return 1;
  37
+	}
  38
+	pad = atoi(argv[3]);
  39
+	if(pad <= 0) {
  40
+		fprintf(stderr, "Incorrect size\n");
  41
+		return 1;
  42
+	}
  43
+	fdi = fopen(argv[1], "rb");
  44
+	if(!fdi) {
  45
+		perror("Unable to open input file");
  46
+		return 1;
  47
+	}
  48
+	fdo = fopen(argv[2], "w");
  49
+	if(!fdo) {
  50
+		perror("Unable to open output file");
  51
+		fclose(fdi);
  52
+		return 1;
  53
+	}
  54
+	mode16 = (argc == 5) && (strcmp(argv[4], "16") == 0);
  55
+	if(mode16) {
  56
+		while(1) {
  57
+			if(fread(w, 2, 1, fdi) <= 0) break;
  58
+			fprintf(fdo, "%02hhx%02hhx\n", w[1], w[0]);
  59
+			pad--;
  60
+		}
  61
+	} else {
  62
+		while(1) {
  63
+			if(fread(w, 4, 1, fdi) <= 0) break;
  64
+			fprintf(fdo, "%02hhx%02hhx%02hhx%02hhx\n", w[0], w[1], w[2], w[3]);
  65
+			pad--;
  66
+		}
  67
+	}
  68
+	fclose(fdi);
  69
+	if(pad<0)
  70
+		fprintf(stderr, "Warning: Input binary is larger than specified size\n");
  71
+	if(mode16) {
  72
+		for(i=0;i<pad;i++)
  73
+			fprintf(fdo, "0000\n");
  74
+	} else {
  75
+		for(i=0;i<pad;i++)
  76
+			fprintf(fdo, "00000000\n");
  77
+	}
  78
+	if(fclose(fdo) != 0) {
  79
+		perror("Unable to close output file");
  80
+		return 1;
  81
+	}
  82
+	return 0;
  83
+}
735  tools/flterm.c
... ...
@@ -0,0 +1,735 @@
  1
+/*
  2
+ * Milkymist SoC
  3
+ * Copyright (C) 2007, 2008, 2009, 2010, 2011 Sebastien Bourdeauducq
  4
+ * Copyright (C) 2011 Michael Walle
  5
+ * Copyright (C) 2004 MontaVista Software, Inc
  6
+ *
  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, version 3 of the License.
  10
+ *
  11
+ * This program is distributed in the hope that it will be useful,
  12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14
+ * GNU General Public License for more details.
  15
+ *
  16
+ * You should have received a copy of the GNU General Public License
  17
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18
+ */
  19
+
  20
+#define _GNU_SOURCE
  21
+
  22
+#include <sys/types.h>
  23
+#include <sys/stat.h>
  24
+#include <sys/ioctl.h>
  25
+#include <sys/time.h>
  26
+#include <string.h>
  27
+#include <ctype.h>
  28
+#include <termios.h>
  29
+#include <fcntl.h>
  30
+#include <unistd.h>
  31
+#include <stdio.h>
  32
+#include <stdlib.h>
  33
+#include <poll.h>
  34
+#include <fcntl.h>
  35
+#include <getopt.h>
  36
+#include <sfl.h>
  37
+
  38
+#define DEFAULT_KERNELADR	(0x40000000)
  39
+#define DEFAULT_CMDLINEADR	(0x41000000)
  40
+#define DEFAULT_INITRDADR	(0x41002000)
  41
+
  42
+#define GDBBUFLEN 1000
  43
+
  44
+unsigned int crc16_table[256] = {
  45
+	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
  46
+	0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
  47
+	0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
  48
+	0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
  49
+	0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
  50
+	0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
  51
+	0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
  52
+	0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
  53
+	0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
  54
+	0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
  55
+	0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
  56
+	0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
  57
+	0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
  58
+	0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
  59
+	0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
  60
+	0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
  61
+	0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
  62
+	0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
  63
+	0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
  64
+	0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
  65
+	0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
  66
+	0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
  67
+	0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
  68
+	0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
  69
+	0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
  70
+	0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
  71
+	0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
  72
+	0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
  73
+	0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
  74
+	0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
  75
+	0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
  76
+	0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
  77
+};
  78
+
  79
+static int debug = 0;
  80
+
  81
+static unsigned short crc16(const void *_buffer, int len)
  82
+{
  83
+	const unsigned char *buffer = (const unsigned char *)_buffer;
  84
+	unsigned short crc;
  85
+	
  86
+	crc = 0;
  87
+	while(len-- > 0)
  88
+	    crc = crc16_table[((crc >> 8) ^ (*buffer++)) & 0xFF] ^ (crc << 8);
  89
+	
  90
+	return crc;
  91
+}
  92
+
  93
+static int write_exact(int fd, const char *data, unsigned int length)
  94
+{
  95
+	int r;
  96
+	
  97
+	while(length > 0) {
  98
+		r = write(fd, data, length);
  99
+		if(r <= 0) return 0;
  100
+		length -= r;
  101
+		data += r;
  102
+	}
  103
+	return 1;
  104
+}
  105
+
  106
+/* length, cmd and payload must be filled in */
  107
+static int send_frame(int serialfd, struct sfl_frame *frame)
  108
+{
  109
+	unsigned short int crc;
  110
+	int retry;
  111
+	char reply;
  112
+	
  113
+	crc = crc16(&frame->cmd, frame->length+1);
  114
+	frame->crc[0] = (crc & 0xff00) >> 8;
  115
+	frame->crc[1] = (crc & 0x00ff);
  116
+	
  117
+	retry = 0;
  118
+	do {
  119
+		if(!write_exact(serialfd, (char *)frame, frame->length+4)) {
  120
+			perror("[FLTERM] Unable to write to serial port.");
  121
+			return 0;
  122
+		}
  123
+		/* Get the reply from the device */
  124
+		read(serialfd, &reply, 1); /* TODO: timeout */
  125
+		switch(reply) {
  126
+			case SFL_ACK_SUCCESS:
  127
+				retry = 0;
  128
+				break;
  129
+			case SFL_ACK_CRCERROR:
  130
+				retry = 1;
  131
+				break;
  132
+			default:
  133
+				fprintf(stderr, "[FLTERM] Got unknown reply '%c' from the device, aborting.\n", reply);
  134
+				return 0;
  135
+		}
  136
+	} while(retry);
  137
+	return 1;
  138
+}
  139
+
  140
+static int upload_fd(int serialfd, const char *name, int firmwarefd, unsigned int load_address)
  141
+{
  142
+	struct sfl_frame frame;
  143
+	int readbytes;
  144
+	int length;
  145
+	int position;
  146
+	unsigned int current_address;
  147
+	struct timeval t0;
  148
+	struct timeval t1;
  149
+	int millisecs;
  150
+	
  151
+	length = lseek(firmwarefd, 0, SEEK_END);
  152
+	lseek(firmwarefd, 0, SEEK_SET);
  153
+	
  154
+	printf("[FLTERM] Uploading %s (%d bytes)...\n", name, length);
  155
+	
  156
+	gettimeofday(&t0, NULL);
  157
+	
  158
+	current_address = load_address;
  159
+	position = 0;
  160
+	while(1) {
  161
+		printf("%d%%\r", 100*position/length);
  162
+		fflush(stdout);
  163
+	
  164
+		readbytes = read(firmwarefd, &frame.payload[4], sizeof(frame.payload) - 4);
  165
+		if(readbytes < 0) {
  166
+			perror("[FLTERM] Unable to read image.");
  167
+			return -1;
  168
+		}
  169
+		if(readbytes == 0) break;
  170
+		
  171
+		frame.length = readbytes+4;
  172
+		frame.cmd = SFL_CMD_LOAD;
  173
+		frame.payload[0] = (current_address & 0xff000000) >> 24;
  174
+		frame.payload[1] = (current_address & 0x00ff0000) >> 16;
  175
+		frame.payload[2] = (current_address & 0x0000ff00) >> 8;
  176
+		frame.payload[3] = (current_address & 0x000000ff);
  177
+		
  178
+		if(!send_frame(serialfd, &frame)) return -1;
  179
+		
  180
+		current_address += readbytes;
  181
+		position += readbytes;
  182
+	}
  183
+	
  184
+	gettimeofday(&t1, NULL);
  185
+	
  186
+	millisecs = (t1.tv_sec - t0.tv_sec)*1000 + (t1.tv_usec - t0.tv_usec)/1000;
  187
+	
  188
+	printf("[FLTERM] Upload complete (%.1fKB/s).\n", 1000.0*(double)length/((double)millisecs*1024.0));
  189
+	return length;
  190
+}
  191
+
  192
+static const char sfl_magic_req[SFL_MAGIC_LEN] = SFL_MAGIC_REQ;
  193
+static const char sfl_magic_ack[SFL_MAGIC_LEN] = SFL_MAGIC_ACK;
  194
+
  195
+static void answer_magic(int serialfd,
  196
+	const char *kernel_image, unsigned int kernel_address,
  197
+	const char *cmdline, unsigned int cmdline_address,
  198
+	const char *initrd_image, unsigned int initrd_address)
  199
+{
  200
+	int kernelfd, initrdfd;
  201
+	struct sfl_frame frame;
  202
+	
  203
+	printf("[FLTERM] Received firmware download request from the device.\n");
  204
+	
  205
+	kernelfd = open(kernel_image, O_RDONLY);
  206
+	if(kernelfd == -1) {
  207
+		perror("[FLTERM] Unable to open kernel image (request ignored).");
  208
+		return;
  209
+	}
  210
+	initrdfd = -1;
  211
+	if(initrd_image != NULL) {
  212
+		initrdfd = open(initrd_image, O_RDONLY);
  213
+		if(initrdfd == -1) {
  214
+			perror("[FLTERM] Unable to open initrd image (request ignored).");
  215
+			close(kernelfd);
  216
+			return;
  217
+		}
  218
+	}
  219
+
  220
+	write_exact(serialfd, sfl_magic_ack, SFL_MAGIC_LEN);
  221
+	
  222
+	upload_fd(serialfd, "kernel", kernelfd, kernel_address);
  223
+	if(cmdline != NULL) {
  224
+		int len;
  225
+
  226
+		printf("[FLTERM] Setting kernel command line: '%s'.\n", cmdline);
  227
+
  228
+		len = strlen(cmdline)+1;
  229
+		if(len > (254-4)) {
  230
+			fprintf(stderr, "[FLTERM] Kernel command line too long, load aborted.\n");
  231
+			close(initrdfd);
  232
+			close(kernelfd);
  233
+			return;
  234
+		}
  235
+		frame.length = len+4;
  236
+		frame.cmd = SFL_CMD_LOAD;
  237
+		frame.payload[0] = (cmdline_address & 0xff000000) >> 24;
  238
+		frame.payload[1] = (cmdline_address & 0x00ff0000) >> 16;
  239
+		frame.payload[2] = (cmdline_address & 0x0000ff00) >> 8;
  240
+		frame.payload[3] = (cmdline_address & 0x000000ff);
  241
+		strcpy((char *)&frame.payload[4], cmdline);
  242
+		send_frame(serialfd, &frame);
  243
+
  244
+		frame.length = 4;
  245
+		frame.cmd = SFL_CMD_CMDLINE;
  246
+		frame.payload[0] = (cmdline_address & 0xff000000) >> 24;
  247
+		frame.payload[1] = (cmdline_address & 0x00ff0000) >> 16;
  248
+		frame.payload[2] = (cmdline_address & 0x0000ff00) >> 8;
  249
+		frame.payload[3] = (cmdline_address & 0x000000ff);
  250
+		send_frame(serialfd, &frame);
  251
+	}
  252
+	if(initrdfd != -1) {
  253
+		int len;
  254
+		
  255
+		len = upload_fd(serialfd, "initrd", initrdfd, initrd_address);
  256
+		if(len <= 0) return;
  257
+		
  258
+		frame.length = 4;
  259
+		frame.cmd = SFL_CMD_INITRDSTART;
  260
+		frame.payload[0] = (initrd_address & 0xff000000) >> 24;
  261
+		frame.payload[1] = (initrd_address & 0x00ff0000) >> 16;
  262
+		frame.payload[2] = (initrd_address & 0x0000ff00) >> 8;
  263
+		frame.payload[3] = (initrd_address & 0x000000ff);
  264
+		send_frame(serialfd, &frame);
  265
+
  266
+		initrd_address += len-1;
  267
+
  268
+		frame.length = 4;
  269
+		frame.cmd = SFL_CMD_INITRDEND;
  270
+		frame.payload[0] = (initrd_address & 0xff000000) >> 24;
  271
+		frame.payload[1] = (initrd_address & 0x00ff0000) >> 16;
  272
+		frame.payload[2] = (initrd_address & 0x0000ff00) >> 8;
  273
+		frame.payload[3] = (initrd_address & 0x000000ff);
  274
+		send_frame(serialfd, &frame);
  275
+	}
  276
+
  277
+	/* Send the jump command */
  278
+	printf("[FLTERM] Booting the device.\n");
  279
+	frame.length = 4;
  280
+	frame.cmd = SFL_CMD_JUMP;
  281
+	frame.payload[0] = (kernel_address & 0xff000000) >> 24;
  282
+	frame.payload[1] = (kernel_address & 0x00ff0000) >> 16;
  283
+	frame.payload[2] = (kernel_address & 0x0000ff00) >> 8;
  284
+	frame.payload[3] = (kernel_address & 0x000000ff);
  285
+	if(!send_frame(serialfd, &frame)) return;
  286
+
  287
+	printf("[FLTERM] Done.\n");
  288
+
  289
+	close(initrdfd);
  290
+	close(kernelfd);
  291
+}
  292
+
  293
+static int hex(unsigned char c)
  294
+{
  295
+	if(c >= 'a' && c <= 'f') {
  296
+		return c - 'a' + 10;
  297
+	}
  298
+	if(c >= '0' && c <= '9') {
  299
+		return c - '0';
  300
+	}
  301
+	if(c >= 'A' && c <= 'F') {
  302
+		return c - 'A' + 10;
  303
+	}
  304
+	return 0;
  305
+}
  306
+
  307
+/*
  308
+ * This is taken from kdmx2.
  309
+ * Author: Tom Rini <trini@mvista.com>
  310
+ */
  311
+static void gdb_process_packet(int infd, int outfd, int altfd)
  312
+{
  313
+	/* gdb packet handling */
  314
+	char gdbbuf[GDBBUFLEN + 1];
  315
+	int pos = 0;
  316
+	unsigned char runcksum = 0;
  317
+	unsigned char recvcksum = 0;
  318
+	struct pollfd fds;
  319
+	char c;
  320
+	int seen_hash = 0;
  321
+
  322
+	fds.fd = infd;
  323
+	fds.events = POLLIN;
  324
+
  325
+	memset(gdbbuf, 0, sizeof(gdbbuf));
  326
+	gdbbuf[0] = '$';
  327
+	pos++;
  328
+
  329
+	while (1) {
  330
+		fds.revents = 0;
  331
+		if(poll(&fds, 1, 100) == 0) {
  332
+			/* timeout */
  333
+			if(altfd != -1) {
  334
+				write(altfd, gdbbuf, pos);
  335
+			}
  336
+			break;
  337
+		}
  338
+		if(pos == GDBBUFLEN) {
  339
+			if(altfd != -1) {
  340
+				write(altfd, gdbbuf, pos);
  341
+			}
  342
+			break;
  343
+		}
  344
+		read(infd, &c, 1);
  345
+		gdbbuf[pos++] = c;
  346
+		if(c == '#') {
  347
+			seen_hash = 1;
  348
+		} else if(seen_hash == 0) {
  349
+			runcksum += c;
  350
+		} else if(seen_hash == 1) {
  351
+			recvcksum = hex(c) << 4;
  352
+			seen_hash = 2;
  353
+		} else if(seen_hash == 2) {
  354
+			recvcksum |= hex(c);
  355
+			seen_hash = 3;
  356
+		}
  357
+
  358
+		if(seen_hash == 3) {
  359
+			/* we're done */
  360
+			runcksum %= 256;
  361
+			if(recvcksum == runcksum) {
  362
+				if(debug) {
  363
+					fprintf(stderr, "[GDB %s]\n", gdbbuf);
  364
+				}
  365
+				write(outfd, gdbbuf, pos);
  366
+			} else {
  367
+				if(altfd != -1) {
  368
+					write(altfd, gdbbuf, pos);
  369
+				}
  370
+			}
  371
+			seen_hash = 0;
  372
+			break;
  373
+		}
  374
+	}
  375
+}
  376
+
  377
+static void do_terminal(char *serial_port,
  378
+	int doublerate, int gdb_passthrough,
  379
+	const char *kernel_image, unsigned int kernel_address,
  380
+	const char *cmdline, unsigned int cmdline_address,
  381
+	const char *initrd_image, unsigned int initrd_address,
  382
+	char *log_path)
  383
+{
  384
+	int serialfd;
  385
+	int gdbfd = -1;
  386
+	FILE *logfd = NULL;
  387
+	struct termios my_termios;
  388
+	char c;
  389
+	int recognized;
  390
+	struct pollfd fds[3];
  391
+	int flags;
  392
+	int rsp_pending = 0;
  393
+	
  394
+	/* Open and configure the serial port */
  395
+	if(log_path != NULL) {
  396
+		logfd = fopen(log_path, "a+");
  397
+		if(logfd == NULL) {
  398
+			perror("Unable to open log file");
  399
+			return;
  400
+		}
  401
+	}
  402
+
  403
+	serialfd = open(serial_port, O_RDWR|O_NOCTTY);
  404
+	if(serialfd == -1) {
  405
+		perror("Unable to open serial port");
  406
+		return;
  407
+	}
  408
+
  409
+	/* Thanks to Julien Schmitt (GTKTerm) for figuring out the correct parameters
  410
+	 * to put into that weird struct.
  411
+	 */
  412
+	tcgetattr(serialfd, &my_termios);
  413
+	my_termios.c_cflag = doublerate ? B230400 : B115200;
  414
+	my_termios.c_cflag |= CS8;
  415
+	my_termios.c_cflag |= CREAD;
  416
+	my_termios.c_iflag = IGNPAR | IGNBRK;
  417
+	my_termios.c_cflag |= CLOCAL;
  418
+	my_termios.c_oflag = 0;
  419
+	my_termios.c_lflag = 0;
  420
+	my_termios.c_cc[VTIME] = 0;
  421
+	my_termios.c_cc[VMIN] = 1;
  422
+	tcsetattr(serialfd, TCSANOW, &my_termios);
  423
+	tcflush(serialfd, TCOFLUSH);
  424
+	tcflush(serialfd, TCIFLUSH);
  425
+
  426
+	/* Prepare the fdset for poll() */
  427
+	fds[0].fd = 0;
  428
+	fds[0].events = POLLIN;
  429
+	fds[1].fd = serialfd;
  430
+	fds[1].events = POLLIN;
  431
+
  432
+	recognized = 0;
  433
+	flags = fcntl(serialfd, F_GETFL, 0);
  434
+	while(1) {
  435
+		if(gdbfd == -1 && gdb_passthrough) {
  436
+			gdbfd = open("/dev/ptmx", O_RDWR);
  437
+			if(grantpt(gdbfd) != 0) {
  438
+				perror("grantpt()");
  439
+				return;
  440
+			}
  441
+			if(unlockpt(gdbfd) != 0) {
  442
+				perror("unlockpt()");
  443
+				return;
  444
+			}
  445
+			printf("[GDB passthrough] use %s as GDB remote device\n",
  446
+					ptsname(gdbfd));
  447
+			fds[2].fd = gdbfd;
  448
+			fds[2].events = POLLIN;
  449
+		}
  450
+
  451
+		fds[0].revents = 0;
  452
+		fds[1].revents = 0;
  453
+		fds[2].revents = 0;
  454
+
  455
+		/* poll() behaves strangely when the serial port descriptor is in
  456
+		 * blocking mode. So work around this.
  457
+		 */
  458
+		fcntl(serialfd, F_SETFL, flags|O_NONBLOCK);
  459
+		if(poll(&fds[0], (gdbfd == -1) ? 2 : 3, -1) < 0) break;
  460
+		fcntl(serialfd, F_SETFL, flags);
  461
+
  462
+		if(fds[0].revents & POLLIN) {
  463
+			if(read(0, &c, 1) <= 0) break;
  464
+			if(write(serialfd, &c, 1) <= 0) break;
  465
+		}
  466
+
  467
+		if(fds[2].revents & POLLIN) {
  468
+			rsp_pending = 1;
  469
+			if(read(gdbfd, &c, 1) <= 0) break;
  470
+			if(c == '\03') {
  471
+				/* convert ETX to breaks */
  472
+				if(debug) {
  473
+					fprintf(stderr, "[GDB BREAK]\n");
  474
+				}
  475
+				tcsendbreak(serialfd, 0);
  476
+			} else if(c == '$') {
  477
+				gdb_process_packet(gdbfd, serialfd, -1);
  478
+			} else if(c == '+' || c == '-') {
  479
+				write(serialfd, &c, 1);
  480
+			} else {
  481
+				fprintf(stderr, "Internal error (line %d)", __LINE__);
  482
+				exit(1);
  483
+			}
  484
+		}
  485
+
  486
+		if(fds[2].revents & POLLHUP) {
  487
+			/* close and reopen new pair */
  488
+			close(gdbfd);
  489
+			gdbfd = -1;
  490
+			continue;
  491
+		}
  492
+
  493
+		if(fds[1].revents & POLLIN) {
  494
+			if(read(serialfd, &c, 1) <= 0) break;
  495
+
  496
+			if(logfd && c && isascii(c)) {
  497
+				fwrite(&c, sizeof(c), 1, logfd);
  498
+				if(c == '\n') fflush(logfd);
  499
+			}
  500
+
  501
+			if(gdbfd != -1 && rsp_pending && (c == '+' || c == '-')) {
  502
+				rsp_pending = 0;
  503
+				write(gdbfd, &c, 1);
  504
+			} else if(gdbfd != -1 && c == '$') {
  505
+				gdb_process_packet(serialfd, gdbfd, 0);
  506
+			} else {
  507
+				/* write to terminal */
  508
+				write(0, &c, 1);
  509
+			
  510
+				if(kernel_image != NULL) {
  511
+					if(c == sfl_magic_req[recognized]) {
  512
+						recognized++;
  513
+						if(recognized == SFL_MAGIC_LEN) {
  514
+							/* We've got the magic string ! */
  515
+							recognized = 0;
  516
+							answer_magic(serialfd,
  517
+								kernel_image, kernel_address,
  518
+								cmdline, cmdline_address,
  519
+								initrd_image, initrd_address);
  520
+						}
  521
+					} else {
  522
+						if(c == sfl_magic_req[0]) recognized = 1; else recognized = 0;
  523
+					}
  524
+				}
  525
+			}
  526
+		}
  527
+	}
  528
+	
  529
+	close(serialfd);
  530
+
  531
+	if(gdbfd != -1) close(gdbfd);
  532
+	if(logfd) fclose(logfd);
  533
+}
  534
+
  535
+enum {
  536
+	OPTION_PORT,
  537
+	OPTION_GDB_PASSTHROUGH,
  538
+	OPTION_DOUBLERATE,
  539
+	OPTION_DEBUG,
  540
+	OPTION_KERNEL,
  541
+	OPTION_KERNELADR,
  542
+	OPTION_CMDLINE,
  543
+	OPTION_CMDLINEADR,
  544
+	OPTION_INITRD,
  545
+	OPTION_INITRDADR,
  546
+	OPTION_LOG
  547
+};
  548
+
  549
+static const struct option options[] = {
  550
+	{
  551
+		.name = "port",
  552
+		.has_arg = 1,
  553
+		.val = OPTION_PORT
  554
+	},
  555
+	{
  556
+		.name = "gdb-passthrough",
  557
+		.has_arg = 0,
  558
+		.val = OPTION_GDB_PASSTHROUGH
  559
+	},
  560
+	{
  561
+		.name = "debug",
  562
+		.has_arg = 0,
  563
+		.val = OPTION_DEBUG
  564
+	},
  565
+	{
  566
+		.name = "double-rate",
  567
+		.has_arg = 0,
  568
+		.val = OPTION_DOUBLERATE
  569
+	},
  570
+	{
  571
+		.name = "kernel",
  572
+		.has_arg = 1,
  573
+		.val = OPTION_KERNEL
  574
+	},
  575
+	{
  576
+		.name = "kernel-adr",
  577
+		.has_arg = 1,
  578
+		.val = OPTION_KERNELADR
  579
+	},
  580
+	{
  581
+		.name = "cmdline",
  582
+		.has_arg = 1,
  583
+		.val = OPTION_CMDLINE
  584
+	},
  585
+	{
  586
+		.name = "cmdline-adr",
  587
+		.has_arg = 1,
  588
+		.val = OPTION_CMDLINEADR
  589
+	},
  590
+	{
  591
+		.name = "initrd",
  592
+		.has_arg = 1,
  593
+		.val = OPTION_INITRD
  594
+	},
  595
+	{
  596
+		.name = "initrd-adr",
  597
+		.has_arg = 1,
  598
+		.val = OPTION_INITRDADR
  599
+	},
  600
+	{
  601
+		.name = "log",
  602
+		.has_arg = 1,
  603
+		.val = OPTION_LOG
  604
+	},
  605
+	{
  606
+		.name = NULL
  607
+	}
  608
+};
  609
+
  610
+static void print_usage()
  611
+{
  612
+	fprintf(stderr, "Serial boot program for Milkymist SoC - v. 2.2\n");
  613
+	fprintf(stderr, "Copyright (C) 2007, 2008, 2009, 2010, 2011 Sebastien Bourdeauducq\n");
  614
+	fprintf(stderr, "Copyright (C) 2011 Michael Walle\n");
  615
+	fprintf(stderr, "Copyright (C) 2004 MontaVista Software, Inc\n\n");
  616
+
  617
+	fprintf(stderr, "This program is free software: you can redistribute it and/or modify\n");
  618
+	fprintf(stderr, "it under the terms of the GNU General Public License as published by\n");
  619
+	fprintf(stderr, "the Free Software Foundation, version 3 of the License.\n\n");
  620
+
  621
+	fprintf(stderr, "Usage: flterm --port <port>\n");
  622
+	fprintf(stderr, "              [--double-rate] [--gdb-passthrough] [--debug]\n");
  623
+	fprintf(stderr, "              [--kernel <kernel_image> [--kernel-adr <address>]]\n");
  624
+	fprintf(stderr, "              [--cmdline <cmdline> [--cmdline-adr <address>]]\n");
  625
+	fprintf(stderr, "              [--initrd <initrd_image> [--initrd-adr <address>]]\n");
  626
+	fprintf(stderr, "              [--log <log_file>]\n\n");
  627
+	fprintf(stderr, "Default load addresses:\n");
  628
+	fprintf(stderr, "  kernel:  0x%08x\n", DEFAULT_KERNELADR);
  629
+	fprintf(stderr, "  cmdline: 0x%08x\n", DEFAULT_CMDLINEADR);
  630
+	fprintf(stderr, "  initrd:  0x%08x\n", DEFAULT_INITRDADR);
  631
+}
  632
+
  633
+int main(int argc, char *argv[])
  634
+{
  635
+	int opt;
  636
+	char *serial_port;
  637
+	int doublerate;
  638
+	int gdb_passthrough;
  639
+	char *kernel_image;
  640
+	unsigned int kernel_address;
  641
+	char *cmdline;
  642
+	unsigned int cmdline_address;
  643
+	char *initrd_image;
  644
+	unsigned int initrd_address;
  645
+	char *endptr;
  646
+	char *log_path;
  647
+	struct termios otty, ntty;
  648
+	
  649
+	/* Fetch command line arguments */
  650
+	serial_port = NULL;
  651
+	doublerate = 0;
  652
+	gdb_passthrough = 0;
  653
+	kernel_image = NULL;
  654
+	kernel_address = DEFAULT_KERNELADR;
  655
+	cmdline = NULL;
  656
+	cmdline_address = DEFAULT_CMDLINEADR;
  657
+	initrd_image = NULL;
  658
+	initrd_address = DEFAULT_INITRDADR;
  659
+	log_path = NULL;
  660
+	while((opt = getopt_long(argc, argv, "", options, NULL)) != -1) {
  661
+		if(opt == '?') {
  662
+			print_usage();
  663
+			return 1;
  664
+		}
  665
+		switch(opt) {
  666
+			case OPTION_PORT:
  667
+				free(serial_port);
  668
+				serial_port = strdup(optarg);
  669
+				break;
  670
+			case OPTION_DOUBLERATE:
  671
+				doublerate = 1;
  672
+				break;
  673
+			case OPTION_DEBUG:
  674
+				debug = 1;
  675
+				break;
  676
+			case OPTION_GDB_PASSTHROUGH:
  677
+				gdb_passthrough = 1;
  678
+				break;
  679
+			case OPTION_KERNEL:
  680
+				free(kernel_image);
  681
+				kernel_image = strdup(optarg);
  682
+				break;
  683
+			case OPTION_KERNELADR:
  684
+				kernel_address = strtoul(optarg, &endptr, 0);
  685
+				if(*endptr != 0) kernel_address = 0;
  686
+				break;
  687
+			case OPTION_CMDLINE:
  688
+				free(cmdline);
  689
+				cmdline = strdup(optarg);
  690
+				break;
  691
+			case OPTION_CMDLINEADR:
  692
+				cmdline_address = strtoul(optarg, &endptr, 0);
  693
+				if(*endptr != 0) cmdline_address = 0;
  694
+				break;
  695
+			case OPTION_INITRD:
  696
+				free(initrd_image);
  697
+				initrd_image = strdup(optarg);
  698
+				break;
  699
+			case OPTION_INITRDADR:
  700
+				initrd_address = strtoul(optarg, &endptr, 0);
  701
+				if(*endptr != 0) initrd_address = 0;
  702
+				break;
  703
+			case OPTION_LOG:
  704
+				free(log_path);
  705
+				log_path = strdup(optarg);
  706
+				break;
  707
+		}
  708
+	}
  709
+
  710
+	if(serial_port == NULL) {
  711
+		print_usage();
  712
+		return 1;
  713
+	}
  714
+
  715
+	/* Banner */
  716
+	printf("[FLTERM] Starting...\n");
  717
+	
  718
+	/* Set up stdin/out */
  719
+	tcgetattr(0, &otty);
  720
+	ntty = otty;
  721
+	ntty.c_lflag &= ~(ECHO | ICANON);
  722
+	tcsetattr(0, TCSANOW, &ntty);
  723
+
  724
+	/* Do the bulk of the work */
  725
+	do_terminal(serial_port, doublerate, gdb_passthrough,
  726
+		kernel_image, kernel_address,
  727
+		cmdline, cmdline_address,
  728
+		initrd_image, initrd_address,
  729
+		log_path);
  730
+	
  731
+	/* Restore stdin/out into their previous state */
  732
+	tcsetattr(0, TCSANOW, &otty);
  733
+	
  734
+	return 0;
  735
+}
174  tools/mkmmimg.c
... ...
@@ -0,0 +1,174 @@
  1
+/*
  2
+ * CRC32 computation tool and Milkymist image file writer
  3
+ * (c) 2009, 2010, Sebastien Bourdeauducq
  4
+ * Released under GNU GPL v3
  5
+ * This file is part of Milkymist.
  6
+ */
  7
+
  8
+/* crc32.c -- compute the CRC-32 of a data stream
  9
+ * Copyright (C) 1995-1998 Mark Adler
  10
+ * For conditions of distribution and use, see copyright notice in zlib.h
  11
+ */
  12
+
  13
+#include <stdio.h>
  14
+#include <stdlib.h>
  15
+#include <sys/types.h>
  16
+#include <sys/stat.h>
  17
+#include <sys/mman.h>
  18
+#include <string.h>
  19
+#include <fcntl.h>
  20
+#include <unistd.h>
  21
+
  22
+const unsigned int crc_table[256] = {
  23
+	0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
  24
+	0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
  25
+	0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
  26
+	0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
  27
+	0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
  28
+	0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
  29
+	0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
  30
+	0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
  31
+	0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
  32
+	0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
  33
+	0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
  34
+	0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
  35
+	0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
  36
+	0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
  37
+	0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
  38
+	0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
  39
+	0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
  40
+	0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
  41
+	0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
  42
+	0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
  43
+	0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
  44
+	0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
  45
+	0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
  46
+	0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
  47
+	0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
  48
+	0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
  49
+	0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
  50
+	0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
  51
+	0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
  52
+	0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
  53
+	0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
  54
+	0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
  55
+	0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
  56
+	0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
  57
+	0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
  58
+	0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
  59
+	0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
  60
+	0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
  61
+	0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
  62
+	0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
  63
+	0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
  64
+	0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
  65
+	0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
  66
+	0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
  67
+	0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
  68
+	0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
  69
+	0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
  70
+	0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
  71
+	0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
  72
+	0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
  73
+	0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
  74
+	0x2d02ef8dL
  75
+};
  76
+
  77
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
  78
+#define DO2(buf)  DO1(buf); DO1(buf);
  79
+#define DO4(buf)  DO2(buf); DO2(buf);
  80
+#define DO8(buf)  DO4(buf); DO4(buf);
  81
+
  82
+static unsigned int crc32(const unsigned char *buffer, unsigned int len)
  83
+{
  84
+	unsigned int crc;
  85
+	crc = 0;
  86
+	crc = crc ^ 0xffffffffL;
  87
+	while(len >= 8) {
  88
+		DO8(buffer);
  89
+		len -= 8;
  90
+	}
  91
+	if(len) do {
  92
+		DO1(buffer);
  93
+	} while(--len);
  94
+	return crc ^ 0xffffffffL;
  95
+}
  96
+
  97
+int main(int argc, char *argv[])
  98
+{
  99
+	int fd, fd_out;
  100
+	unsigned char *buffer;
  101
+	unsigned int length;
  102
+	unsigned int crc;
  103
+	
  104
+	if(((argc != 2) && (argc != 3) && (argc != 4))
  105
+		|| ((argc > 2) && (strcmp(argv[2], "write") && (strcmp(argv[2], "writelzma"))))) {
  106
+		fprintf(stderr, "Usage: mkmmimg <filename> [write[lzma]] [dest]\n");
  107
+		return 1;
  108
+	}
  109
+	
  110
+	fd = open(argv[1], O_RDONLY);
  111
+	if(fd == -1) {
  112
+		perror("open");
  113
+		return 1;
  114
+	}
  115
+	
  116
+	length = lseek(fd, 0, SEEK_END);
  117
+	lseek(fd, 0, SEEK_SET);
  118
+	
  119
+	buffer = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0);
  120
+	if(!buffer) {
  121
+		perror("mmap");
  122
+		close(fd);
  123
+		return 1;
  124
+	}
  125
+	crc = crc32(buffer, length);
  126
+	printf("CRC32 (%s): %08x\n", argv[1], crc);
  127
+
  128
+	if(argc == 3) {
  129
+		/* Write the CRC32 in big endian at the end of the file */
  130
+		char b[4];
  131
+
  132
+		fd_out = open(argv[1], O_WRONLY|O_APPEND);
  133
+		if(fd_out == -1) {
  134
+			perror("open");
  135
+			return 1;
  136
+		}
  137
+		b[0] = (crc & 0xff000000) >> 24;
  138
+		b[1] = (crc & 0x00ff0000) >> 16;
  139
+		b[2] = (crc & 0x0000ff00) >> 8;
  140
+		b[3] = (crc & 0x000000ff) >> 0;
  141
+		write(fd_out, &b[0], 4);
  142
+		close(fd_out);
  143
+	}
  144
+
  145
+	if(argc == 4) {
  146
+		/* Write a new file prepended with the size and CRC */
  147
+		char b[4];
  148
+
  149
+		fd_out = open(argv[3], O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
  150
+		if(fd_out == -1) {
  151
+			perror("open");
  152
+			return 1;
  153
+		}
  154
+		b[0] = (length & 0xff000000) >> 24;
  155
+		b[1] = (length & 0x00ff0000) >> 16;
  156
+		b[2] = (length & 0x0000ff00) >> 8;
  157
+		b[3] = (length & 0x000000ff) >> 0;
  158
+		if(strcmp(argv[2], "writelzma") == 0)
  159
+			b[0] |= 0x80;
  160
+		write(fd_out, &b[0], 4);
  161
+		b[0] = (crc & 0xff000000) >> 24;
  162
+		b[1] = (crc & 0x00ff0000) >> 16;
  163
+		b[2] = (crc & 0x0000ff00) >> 8;
  164
+		b[3] = (crc & 0x000000ff) >> 0;
  165
+		write(fd_out, &b[0], 4);
  166
+		write(fd_out, buffer, length);
  167
+		close(fd_out);
  168
+	}
  169
+
  170
+	munmap(buffer, length);
  171
+	close(fd);
  172
+
  173
+	return 0;
  174
+}
48  tools/sfl.h
... ...
@@ -0,0 +1,48 @@
  1
+/*
  2
+ * Milkymist SoC
  3
+ * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
  4
+ *
  5
+ * This program is free software: you can redistribute it and/or modify
  6
+ * it under the terms of the GNU General Public License as published by
  7
+ * the Free Software Foundation, version 3 of the License.
  8
+ *
  9
+ * This program is distributed in the hope that it will be useful,
  10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12
+ * GNU General Public License for more details.
  13
+ *
  14
+ * You should have received a copy of the GNU General Public License
  15
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16
+ */
  17
+
  18
+#ifndef __SFL_H
  19
+#define __SFL_H
  20
+
  21
+#define SFL_MAGIC_LEN 14
  22
+#define SFL_MAGIC_REQ "sL5DdSMmkekro\n"
  23
+#define SFL_MAGIC_ACK "z6IHG7cYDID6o\n"
  24
+
  25
+struct sfl_frame {
  26
+	unsigned char length;
  27
+	unsigned char crc[2];
  28
+	unsigned char cmd;
  29
+	unsigned char payload[255];
  30
+} __attribute__((packed));
  31
+
  32
+/* General commands */
  33
+#define SFL_CMD_ABORT		0x00
  34
+#define SFL_CMD_LOAD		0x01
  35
+#define SFL_CMD_JUMP		0x02
  36
+
  37
+/* Linux-specific commands */
  38
+#define SFL_CMD_CMDLINE		0x03
  39
+#define SFL_CMD_INITRDSTART	0x04
  40
+#define SFL_CMD_INITRDEND	0x05
  41
+
  42
+/* Replies */
  43
+#define SFL_ACK_SUCCESS		'K'
  44
+#define SFL_ACK_CRCERROR	'C'
  45
+#define SFL_ACK_UNKNOWN		'U'
  46
+#define SFL_ACK_ERROR		'E'
  47
+
  48
+#endif /* __SFL_H */

No commit comments for this range

Something went wrong with that request. Please try again.