summaryrefslogtreecommitdiff
path: root/recipes/simpad-utilities
diff options
context:
space:
mode:
authorDenys Dmytriyenko <denis@denix.org>2009-03-17 14:32:59 -0400
committerDenys Dmytriyenko <denis@denix.org>2009-03-17 14:32:59 -0400
commit709c4d66e0b107ca606941b988bad717c0b45d9b (patch)
tree37ee08b1eb308f3b2b6426d5793545c38396b838 /recipes/simpad-utilities
parentfa6cd5a3b993f16c27de4ff82b42684516d433ba (diff)
rename packages/ to recipes/ per earlier agreement
See links below for more details: http://thread.gmane.org/gmane.comp.handhelds.openembedded/21326 http://thread.gmane.org/gmane.comp.handhelds.openembedded/21816 Signed-off-by: Denys Dmytriyenko <denis@denix.org> Acked-by: Mike Westerhof <mwester@dls.net> Acked-by: Philip Balister <philip@balister.org> Acked-by: Khem Raj <raj.khem@gmail.com> Acked-by: Marcin Juszkiewicz <hrw@openembedded.org> Acked-by: Koen Kooi <koen@openembedded.org> Acked-by: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>
Diffstat (limited to 'recipes/simpad-utilities')
-rw-r--r--recipes/simpad-utilities/genboot-native.bb20
-rw-r--r--recipes/simpad-utilities/genboot/arnold_boot.h28
-rw-r--r--recipes/simpad-utilities/genboot/gen_boot.c99
-rwxr-xr-xrecipes/simpad-utilities/genboot/simpad-make-flashimg89
-rw-r--r--recipes/simpad-utilities/serload-native.bb16
-rw-r--r--recipes/simpad-utilities/serload/main.cpp136
-rw-r--r--recipes/simpad-utilities/serload/serialdownload.cpp408
-rw-r--r--recipes/simpad-utilities/serload/serialdownload.h158
-rw-r--r--recipes/simpad-utilities/serload/serload.138
-rw-r--r--recipes/simpad-utilities/simpad-utilities.bb5
10 files changed, 997 insertions, 0 deletions
diff --git a/recipes/simpad-utilities/genboot-native.bb b/recipes/simpad-utilities/genboot-native.bb
new file mode 100644
index 0000000000..47b9b34640
--- /dev/null
+++ b/recipes/simpad-utilities/genboot-native.bb
@@ -0,0 +1,20 @@
+SECTION = "console/utils"
+PR = "r1"
+DESCRIPTION = "Console utility for generating a SIMpad boot image for the proprietary SIEMENS Switzerland bootloader"
+FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/genboot"
+SRC_URI = "file://gen_boot.c file://arnold_boot.h file://simpad-make-flashimg"
+LICENSE = "GPL"
+
+DEPENDS = "pad-native"
+
+inherit native
+
+do_compile() {
+ cp ${WORKDIR}/*.h ${WORKDIR}/*.c .
+ ${CC} -I. -o genboot gen_boot.c
+}
+
+do_stage() {
+ install -m 0755 genboot ${STAGING_BINDIR}/
+ install -m 0755 ${WORKDIR}/simpad-make-flashimg ${STAGING_BINDIR}/
+}
diff --git a/recipes/simpad-utilities/genboot/arnold_boot.h b/recipes/simpad-utilities/genboot/arnold_boot.h
new file mode 100644
index 0000000000..7c8399ac2e
--- /dev/null
+++ b/recipes/simpad-utilities/genboot/arnold_boot.h
@@ -0,0 +1,28 @@
+
+#define ARNOLDMAGIC "ARNOLDBOOTBLOCK"
+#define MAXSEG 32
+#define WRITE_SMART_MAGIC 3141 /* write tftp data to smart */
+#define BOOT_SMART_MAGIC 9876 /* Start an Smartmedia */
+#define REBOOT_MAGIC 9123 /* restart old image ? */
+#define EXTRA_BOOT 0xdead /* Load named image */
+
+struct segment { void *base; long len; }; /* len MUST be Multiple of 512 */
+
+struct arnold_bootheader {
+ char magic[16];
+ long exec_adr;
+ long nosegs;
+ struct segment lseg[MAXSEG];
+ long stack_p;
+ short debuggit;
+ short writesmart;
+ unsigned short extrafile;
+ char otherfile[20];
+
+ char reserved[1]; /* reserved for future use */
+};
+union bootblock {
+ char buffer[512];
+ struct arnold_bootheader boot;
+};
+
diff --git a/recipes/simpad-utilities/genboot/gen_boot.c b/recipes/simpad-utilities/genboot/gen_boot.c
new file mode 100644
index 0000000000..1444f60d0b
--- /dev/null
+++ b/recipes/simpad-utilities/genboot/gen_boot.c
@@ -0,0 +1,99 @@
+#include "arnold_boot.h"
+#include <stdio.h>
+volatile void
+error (char *msg)
+{
+ fprintf (stderr, "Fatal Error:%s\n", msg);
+ exit (2);
+}
+#ifdef LITTLE_END
+#define order(x) ((x&0xff)<<24 | (x&0xff00) << 8 | (x&0xff0000) >>8 | (x&0xff000000)>>24)
+#define swap(x) ((x&0xff)<<8 | (x&0xff00)>>8)
+#else
+#define order(x) (x)
+#define swap(x) (x)
+#endif
+
+main (int argc, char *argv[])
+{
+ union bootblock block0;
+ char *ep;
+ int nseg;
+
+ memset ((void *) &block0, 0, sizeof (block0));
+ strcpy (block0.boot.magic, ARNOLDMAGIC);
+ if (argc < 3)
+ error ("Bad Number of args:\n"
+ " Usage: gen_boot [-d[n]][-w][-r][-x filename] exec_adr nseg base1 len1 [base len]");
+
+ if (strncmp (argv[1], "-d",2) == 0)
+ {
+ /* Set debugging to value (default 1) */
+ if ( argv[1][2] == 0 ) {
+ block0.boot.debuggit = swap(1);
+ }else{
+ block0.boot.debuggit = swap(argv[1][2] - '0');
+ }
+ argv++;
+ argc--;
+ }
+ if (strcmp (argv[1], "-w") == 0)
+ {
+ block0.boot.writesmart = swap(WRITE_SMART_MAGIC);
+ argv++;
+ argc--;
+ }
+ if (strcmp (argv[1], "-r") == 0)
+ {
+ block0.boot.writesmart = swap(REBOOT_MAGIC); /* Try to reboot ram image */
+ argv++;
+ argc--;
+ }
+ if (strcmp (argv[1], "-x") == 0)
+ {
+ block0.boot.extrafile=swap(EXTRA_BOOT);
+ strncpy (block0.boot.otherfile,argv[2],sizeof(block0.boot.otherfile));
+
+ argv+=2;
+ argc-=2;
+ }
+ block0.boot.exec_adr = order (strtoul (argv[1], &ep, 0));
+ if (ep != 0 && *ep != 0)
+ {
+ error ("Exec_addr ?");
+ }
+ argv++;
+ argc--;
+ nseg = strtoul (argv[1], &ep, 0);
+ block0.boot.nosegs = order (nseg);
+ if (ep != 0 && *ep != 0)
+ {
+ error ("Number of Segments ?");
+ }
+ argv++;
+ argc--;
+ argv++;
+ argc--; /* Start from index 0 */
+ if (argc != (nseg * 2))
+ {
+ error ("Wrong number of arguments");
+ }
+ for (nseg = 0; (nseg * 2) < argc; nseg++)
+ {
+ block0.boot.lseg[nseg].base = (void *) order (strtoul (argv[nseg * 2], &ep, 0));
+ if (ep != 0 && *ep != 0)
+ {
+ error ("Base addr of Segment ?");
+ }
+ block0.boot.lseg[nseg].len = order (strtoul (argv[nseg * 2 + 1], &ep, 0));
+ if (ep != 0 && *ep != 0)
+ {
+ error ("Length of Segment ?");
+ }
+ }
+ fwrite((void *) &block0, sizeof(block0), 1, stdout);
+ fflush(stdout);
+// write (1, block0, sizeof (block0));
+
+ exit (0);
+}
diff --git a/recipes/simpad-utilities/genboot/simpad-make-flashimg b/recipes/simpad-utilities/genboot/simpad-make-flashimg
new file mode 100755
index 0000000000..e29de3f94f
--- /dev/null
+++ b/recipes/simpad-utilities/genboot/simpad-make-flashimg
@@ -0,0 +1,89 @@
+#!/bin/sh
+# Script to build a full (kernel+initrd) flash rom bootimage
+# (C) 2003-2004 Michael 'Mickey' Lauer <mickey@Vanille.de>
+# Use serload to flash the image on your SIMpad
+
+#
+# vars
+#
+GENBOOT=genboot
+PAD=pad
+KERNEL=$2
+INITRD=$3
+
+doComplete()
+{
+ kernel=$(basename $KERNEL)
+ initrd=$INITRD
+ outfile=/tmp/tmpfile
+ padfile=/tmp/tmpfile2
+ flashfile=$kernel.initrd.flashfile
+
+ cp -f $KERNEL $padfile
+ $PAD 1048556 $padfile
+ cat $padfile $initrd >$outfile
+ set X`ls -l $outfile`
+ filelen=$5
+
+ loader_start="0xc0208000"
+ loader_entry="0xc0208000"
+
+ echo "File: $flashfile Exec: $loader_entry $filelen "
+ $GENBOOT -d3 $loader_entry 1 $loader_start $filelen >/tmp/bheader
+ cat /tmp/bheader $outfile >$flashfile
+ rm $outfile
+ rm $padfile
+ exit 0
+}
+
+doKernel()
+{
+ kernel=$(basename $KERNEL)
+ outfile=/tmp/tmpfile
+ flashfile=$kernel.flashfile
+
+ cat $KERNEL >$outfile
+ set X`ls -l $outfile`
+ filelen=$5
+
+ loader_start="0xc0208000"
+ loader_entry="0xc0208000"
+
+ echo "File: $flashfile Exec: $loader_entry $filelen "
+ $GENBOOT -d3 $loader_entry 1 $loader_start $filelen >/tmp/bheader
+ cat /tmp/bheader $outfile >$flashfile
+ rm $outfile
+ exit 0
+}
+
+doKernelInPlace()
+{
+ kernel=$(basename $KERNEL)
+ outfile=/tmp/tmpfile
+ flashfile=$kernel.flashfile
+
+ cat $KERNEL >$outfile
+ set X`ls -l $outfile`
+ filelen=$5
+
+ loader_start="0xc0080000"
+ loader_entry="0xc0080000"
+
+ echo "File: $flashfile Exec: $loader_entry $filelen "
+ $GENBOOT $loader_entry 1 $loader_start $filelen >/tmp/bheader
+ cat /tmp/bheader $outfile >$flashfile.inplace
+ rm $outfile
+ exit 0
+}
+
+if [ $# -lt 2 ]
+ then echo "Usage: ./simpad-make-flashimg [kernel|complete|inplace] <kernel> [rootfs.jffs2]" && exit -1
+fi
+
+case "$1" in
+kernel) doKernel;;
+complete) doComplete;;
+inplace) doKernelInPlace;;
+*) echo "Usage: ./simpad-make-flashimg [kernel|complete|inplace] <kernel> [rootfs.jffs2]"; exit;;
+esac
+
diff --git a/recipes/simpad-utilities/serload-native.bb b/recipes/simpad-utilities/serload-native.bb
new file mode 100644
index 0000000000..9be199f1e8
--- /dev/null
+++ b/recipes/simpad-utilities/serload-native.bb
@@ -0,0 +1,16 @@
+SECTION = "console/utils"
+LICENSE= "GPL"
+DESCRIPTION = "Console utility for transferring a SIMpad boot image via serial a SIMpad"
+FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/serload"
+SRC_URI = "file://serialdownload.cpp file://main.cpp file://serialdownload.h"
+
+inherit native
+
+do_compile() {
+ cp ${WORKDIR}/*.h ${WORKDIR}/*.cpp .
+ ${CXX} -I. -o serload main.cpp serialdownload.cpp
+}
+
+do_stage() {
+ install -m 0755 serload ${STAGING_BINDIR}/
+}
diff --git a/recipes/simpad-utilities/serload/main.cpp b/recipes/simpad-utilities/serload/main.cpp
new file mode 100644
index 0000000000..b65d71753c
--- /dev/null
+++ b/recipes/simpad-utilities/serload/main.cpp
@@ -0,0 +1,136 @@
+//=============================================================================
+// Project: SIMpad
+//=============================================================================
+// FILE-NAME: main.cpp
+// FUNCTION: Serial download of a new image from PC to SIMpad
+//
+// AUTHOR: Juergen Messerer, Peter Voser
+// CREAT.-DATE: 01.04.2001 (dd.mm.yy)
+//
+// NOTES: -
+//
+//=============================================================================
+
+#include <unistd.h>
+#include <iostream>
+#include <string.h>
+#include "serialdownload.h"
+using namespace std;
+
+const int STRING_LENGTH = 128;
+
+//=============================================================================
+//=============================================================================
+void printHelp(void)
+{
+ cout << "serload V1.0 for Linux " << endl;
+ cout << "Downloading a new image to the SIMpad "
+ << "using the serial interface." << endl << endl;
+ cout << "Invocation: serload [IMAGEFILE] [ttyS-PORT]" << endl;
+ cout << "IMAGEFILE: the file with the new image prepared for the"
+ << " SIMpad Bootloader."
+ << endl;
+ cout << "ttyS-PORT: number of the ttyS-Port for the download."
+ << endl;
+ cout << "Note: ttyS0 = COM1, ttyS1 = COM2, ..." << endl << endl;
+}
+
+//=============================================================================
+//=============================================================================
+int main(int argc, char *argv[])
+{
+ int i;
+ for(i = 0; i < argc; ++i)
+ {
+ if(strcmp(argv[i], "--help") == 0)
+ {
+ // The user asks for help.
+ printHelp();
+ exit(0);
+ }
+ }
+
+ if(argc != 3 && argc != 2)
+ {
+ cerr << endl << "Usage: serload [IMAGEFILE] [ttyS-PORT]" << endl;
+ cerr << "See also \"serload --help\"!" << endl << endl;
+ exit(1);
+ }
+
+ char device[STRING_LENGTH];
+ if(argc == 3)
+ {
+ strcpy(device, "/dev/ttyS");
+ strcat(device, argv[2]);
+ }
+ else
+ {
+ // If no serial port is given, use ttyS0 as default.
+ strcpy(device, "/dev/ttyS0");
+ }
+
+ SerialDownload serload;
+ int myError, imagesize;
+ static char *image;
+
+ int success = serload.openSerialPort(device, myError);
+ if(success != 0)
+ {
+ cerr << "Error: cannot open " << device << ". Aborting."
+ << endl << endl;
+ exit(2);
+ }
+
+ myError = serload.loadFile(argv[1], image, imagesize);
+ if(myError != 0)
+ {
+ cerr << "Error: cannot load file "
+ << argv[1] << "! Aborting." << endl << endl;
+ exit(3);
+ }
+
+ cout << "Please press RESET at the back of the SIMpad!" << endl;
+ int reply = serload.connectToSimpad(115200, myError);
+
+ if(reply != 0)
+ {
+ cerr << "Error: cannot connect to SIMpad! Aborting."
+ << endl << endl;
+ exit(4);
+ }
+
+ // Determine number of blocks to send without remaining bytes!
+ int progress = 0;
+ int size = imagesize;
+ int totalBlocks = size / 512;
+ int numberOfBlocksToSend = totalBlocks;
+ int numberOfBlocksSent = 0;
+
+ // Send blocks.
+ while(numberOfBlocksToSend)
+ {
+ serload.sendBlock(image, 512, myError);
+ image += 512;
+ --numberOfBlocksToSend;
+ // Update progress info every 100th block.
+ if(!(numberOfBlocksSent % 100))
+ {
+ progress = 100 * numberOfBlocksSent / totalBlocks;
+ }
+ ++numberOfBlocksSent;
+ }
+
+ // Determine, if there are remaining bytes.
+ int numberOfRemainingBytes = size % 512;
+ if(numberOfRemainingBytes)
+ {
+ serload.sendBlock(image, numberOfRemainingBytes, myError);
+ }
+
+ // The bootloader burns the new image.
+ serload.waitForEndOfBurning();
+
+ cout << "Update successfully finished! Swich the SIMpad on." << endl;
+
+ return 0;
+}
diff --git a/recipes/simpad-utilities/serload/serialdownload.cpp b/recipes/simpad-utilities/serload/serialdownload.cpp
new file mode 100644
index 0000000000..c58de2280f
--- /dev/null
+++ b/recipes/simpad-utilities/serload/serialdownload.cpp
@@ -0,0 +1,408 @@
+//=============================================================================
+// Project: SIMpad
+//=============================================================================
+// FILE-NAME: serialdownload.cpp
+// FUNCTION: Serial download of a new image from PC to SIMpad
+//
+// AUTHOR: Juergen Messerer, Peter Voser
+// CREAT.-DATE: 01.04.2001 (dd.mm.yy)
+//
+// NOTES: -
+//
+//=============================================================================
+
+#include <iostream>
+#include "serialdownload.h"
+using namespace std;
+
+//=============================================================================
+//=============================================================================
+SerialDownload::SerialDownload()
+{
+}
+
+//=============================================================================
+//=============================================================================
+SerialDownload::~SerialDownload()
+{
+}
+
+//=============================================================================
+//=============================================================================
+int SerialDownload::openSerialPort(const char* portDev, int& errorNumber)
+{
+ _serialPort = open(portDev, O_RDWR | O_NONBLOCK);
+
+ if (_serialPort == -1)
+ {
+ errorNumber = errno;
+ return -1;
+ }
+
+ // Read old serial port setup
+ termios serialPortSetup;
+ int success = tcgetattr(_serialPort, &serialPortSetup );
+ if (success < 0)
+ {
+ errorNumber = errno;
+ perror(0);
+ return -1;
+ }
+
+ serialPortSetup.c_iflag = 0L;
+ serialPortSetup.c_oflag = 0L;
+
+ // Control mode flags
+ serialPortSetup.c_cflag &= ~(CSTOPB|PARENB|CRTSCTS);
+ serialPortSetup.c_cflag |= (CS8|CLOCAL);
+
+ // Local mode flags
+ serialPortSetup.c_lflag = 0L;
+
+ // control characters
+ serialPortSetup.c_cc[VTIME] = 0;
+ serialPortSetup.c_cc[VMIN] = 0;
+
+ // Set baud rate = 38.4kBaud
+ cfsetispeed(&serialPortSetup, B38400);
+ cfsetospeed(&serialPortSetup, B38400);
+
+ success=tcsetattr(_serialPort, TCSANOW, &serialPortSetup);
+ if(success < 0)
+ {
+ errorNumber = errno;
+ perror(0);
+ return -1;
+ }
+
+ return 0;
+}
+
+//=============================================================================
+//=============================================================================
+int SerialDownload::loadFile(const char *fileName,
+ char *&buffer,
+ int &numberOfBytes)
+{
+ FILE *path;
+
+ if((path = fopen(fileName,"rb")) == 0)
+ {
+ // Specified file not found.
+ return -1;
+ }
+
+ fseek(path, 0, 2);
+ numberOfBytes = ftell(path);
+ rewind(path);
+
+ buffer = (char*)malloc((size_t)numberOfBytes);
+ if(buffer == 0)
+ {
+ // Insufficient memory to load file.
+ fclose(path);
+ return -2;
+ }
+
+ if(fread(buffer, numberOfBytes, 1, path) != 1)
+ {
+ // Cannot read file.
+ fclose(path);
+ return -3;
+ }
+
+ fclose(path);
+ return 0;
+}
+
+//=============================================================================
+//=============================================================================
+bool SerialDownload::changeBaudRate(const int newBaudRate,
+ int& errorNumber)
+{
+ int success;
+ int baudRate;
+ struct termios setup;
+
+ switch(newBaudRate)
+ {
+ case 9600:
+ baudRate = B9600;
+ break;
+ case 19200:
+ baudRate = B19200;
+ break;
+ case 38400:
+ baudRate = B38400;
+ break;
+ case 57600:
+ baudRate = B57600;
+ break;
+ case 115200:
+ baudRate = B115200;
+ break;
+ case 230400:
+ baudRate = B230400;
+ break;
+ case 460800:
+ baudRate = B460800;
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ success = tcgetattr(_serialPort, &setup);
+ if (success < 0)
+ {
+ errorNumber = errno;
+ perror(0);
+ return 0;
+ }
+
+ cfsetispeed(&setup, baudRate);
+ cfsetospeed(&setup, baudRate);
+ success = tcsetattr(_serialPort, TCSANOW, &setup);
+ if (success < 0)
+ {
+ errorNumber = errno;
+ perror(0);
+ return 0;
+ }
+
+ return 1;
+}
+
+//=============================================================================
+//=============================================================================
+unsigned char SerialDownload::waitForReply(const int transparent)
+{
+ unsigned char c(0);
+ int numberBytes(0);
+ int reply(0);
+
+ struct pollfd commEvent;
+ commEvent.fd = _serialPort;
+ commEvent.events = POLLIN;
+
+ for(;;)
+ {
+ // Wait until a character has received.
+ do
+ {
+ reply = poll(&commEvent, 1, 1000);
+ }
+ while(reply == 0);
+
+ if(commEvent.revents == POLLIN)
+ {
+ do
+ {
+ numberBytes=read(_serialPort, &c, 1);
+ if(transparent && numberBytes)
+ {
+ cout << c;
+ cout.flush();
+ }
+ if((c == STX) ||
+ (c == ETX) ||
+ (c == BEL) ||
+ (c == ACK_OK) ||
+ (c == ACK_NOK))
+ {
+ return c;
+ }
+ }
+ while(numberBytes);
+ }
+ }
+ return 0;
+}
+
+//=============================================================================
+//=============================================================================
+int SerialDownload::connectToSimpad(const int fastBaudRate,
+ int& errorNumber)
+{
+ errorNumber = 0;
+ int bytesWritten;
+ unsigned char c;
+
+ // Switch baud rate to low connecting baud rate.
+ if(!changeBaudRate(38400, errorNumber))
+ {
+ return -1;
+ }
+
+ // Wait for character STX (02) and BEL (07)
+ while(waitForReply(1) != STX);
+ while(waitForReply(1) != BEL);
+ bytesWritten = write(_serialPort, &ACK_BD, 1);
+ if(!bytesWritten)
+ {
+ errorNumber = errno;
+ return -2;
+ }
+
+ // Send byte #2 of baud rate
+ c = (fastBaudRate>>16)&0xff;
+ bytesWritten = write(_serialPort, &c, 1);
+ if(!bytesWritten)
+ {
+ errorNumber = errno;
+ return -2;
+ }
+
+ // Send byte #1 of baud rate
+ c = (fastBaudRate>>8)&0xff;
+ bytesWritten = write(_serialPort, &c, 1);
+ if(!bytesWritten)
+ {
+ errorNumber = errno;
+ return -2;
+ }
+
+ // Send byte #0 of baud rate
+ c = fastBaudRate&0xff;
+ bytesWritten = write(_serialPort, &c, 1);
+ if(!bytesWritten)
+ {
+ errorNumber = errno;
+ return -2;
+ }
+
+ c = waitForReply(1);
+ if (c == ACK_OK)
+ {
+ // Switch baud rate to fast baud rate.
+ if(!changeBaudRate(fastBaudRate, errorNumber))
+ {
+ return -3;
+ }
+ }
+
+ // Wait for 1st character with new baud rate.
+ while(waitForReply(1) != STX);
+
+ bytesWritten = write(_serialPort, &STX, 1);
+ if(!bytesWritten)
+ {
+ errorNumber = errno;
+ return -4;
+ }
+
+ while(waitForReply(1) != STX);
+ return 0;
+}
+
+//=============================================================================
+//=============================================================================
+bool SerialDownload::sendBlock(const char *buffer,
+ const int length,
+ int& errorNumber)
+{
+ errorNumber = 0;
+ unsigned char c, check=0xff;
+ int i;
+ int bytesWritten;
+
+ while(1)
+ {
+ if(length == 512)
+ {
+ // It's a complete block.
+ bytesWritten = write(_serialPort, buffer, 512);
+ if(!bytesWritten)
+ {
+ errorNumber = errno;
+ return 0;
+ }
+ // Create checksum.
+ for(i = 0; i < 512; ++i)
+ {
+ check=(check<<1) ^ buffer[i];
+ }
+ }
+ else
+ {
+ // It's an incomplete block, which must be filled with
+ // the FILLER pattern.
+ char lastBlock[512];
+ for(i = 0; i < 512; ++i)
+ {
+ if(i < length)
+ {
+ // Create checksum.
+ check=(check<<1) ^ buffer[i];
+ lastBlock[i] = buffer[i];
+ }
+ else
+ {
+ // Create checksum
+ check=(check<<1) ^ FILLER;
+ lastBlock[i] = FILLER;
+ }
+ }
+ bytesWritten = write(_serialPort, lastBlock, 512);
+ if(!bytesWritten)
+ {
+ errorNumber = errno;
+ return 0;
+ }
+ }
+
+ while(waitForReply(1) != STX);
+
+ if(length == 512)
+ {
+ bytesWritten = write(_serialPort, &STX, 1);
+ if(!bytesWritten)
+ {
+ errorNumber = errno;
+ return 0;
+ }
+ }
+ else
+ {
+ // It was the last block.
+ bytesWritten = write(_serialPort, &ETX, 1);
+ if(!bytesWritten)
+ {
+ errorNumber = errno;
+ return 0;
+ }
+ }
+
+ // Send checksum.
+ bytesWritten = write(_serialPort, &check, 1);
+ if(!bytesWritten)
+ {
+ errorNumber = errno;
+ return 0;
+ }
+
+ // Wait for ACK_OK as confirmation. Send block again otherwise.
+ c = waitForReply(1);
+ if(c == ACK_OK)
+ {
+ // The block was successfully sent.
+ return 1;
+ }
+ }
+}
+
+//=============================================================================
+//=============================================================================
+void SerialDownload::waitForEndOfBurning(void)
+{
+ // Wait for ETX, which indicates the end of burning.
+ while(waitForReply(1) != ETX);
+
+ // Send the characters "r" (erase registry) and "o" (power off).
+ char c = 'r';
+ int bytesWritten;
+ bytesWritten = write(_serialPort, &c, 1);
+ c = 'o';
+ bytesWritten = write(_serialPort, &c, 1);
+ usleep(7000);
+}
diff --git a/recipes/simpad-utilities/serload/serialdownload.h b/recipes/simpad-utilities/serload/serialdownload.h
new file mode 100644
index 0000000000..1dd05892b1
--- /dev/null
+++ b/recipes/simpad-utilities/serload/serialdownload.h
@@ -0,0 +1,158 @@
+//=============================================================================
+// Project: SIMpad
+//=============================================================================
+// FILE-NAME: serialdownload.hpp
+// FUNCTION: Serial download interface.
+//
+// AUTHOR: Juergen Messerer, Peter Voser
+// CREAT.-DATE: 01.04.2001 (dd.mm.yy)
+//
+// NOTES: -
+//
+//=============================================================================
+
+#ifndef __SERIAL_DOWNLOAD
+#define __SERIAL_DOWNLOAD
+
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+const unsigned char STX = 2;
+const unsigned char ETX = 3;
+const unsigned char BEL = 7;
+const unsigned char ACK_BD = 11;
+const unsigned char ACK_OK = 6;
+const unsigned char ACK_NOK = 15;
+const unsigned char FILLER = 0xff;
+
+class SerialDownload
+{
+public:
+ SerialDownload();
+ ~SerialDownload();
+//=============================================================================
+// PURPOSE: Opening a serial port.
+//
+// PARAMETERS:
+// portDev: (IN) port device to open.
+// errorNumber: (OUT) error number determined with
+// GetLastError().
+// RETURN VALUE:
+// serialPort: Filedescriptor of opened serial port.
+// If the function fails, it returns -1.
+//
+// COMMENTS: -
+//=============================================================================
+ int openSerialPort(const char* portDev, int &errorNumber);
+
+//=============================================================================
+// PURPOSE: Loading file with a image
+//
+// PARAMETERS:
+// fileName: (IN) name of file to open
+// buffer: (OUT) pointer to loaded image file.
+// numberOfBytes: (OUT) size of file.
+//
+// RETURN VALUE:
+// 0: success
+// -1: specified file not found
+// -2: not enough memory to load file
+// -3: cannot read file
+//
+// COMMENTS: -
+//=============================================================================
+ int loadFile(const char *fileName, char *&buffer, int &numberOfBytes);
+
+//=============================================================================
+// PURPOSE: Connecting to the SIMpad.
+//
+// PARAMETERS:
+// fastBaudRate: (IN) value of fast baud rate.
+// errorNumber: (OUT) error number errno
+//
+// RETURN VALUE:
+// 0: success
+// -1: switching to connection baud rate 38400baud failed.
+// -2: writing to serial port failed.
+// -3: switching to fast baud rate failed.
+// -4: writing to serial port with fast baud rate failed.
+//
+// COMMENTS: The connection is set up according to the bootloader's
+// serial download protocoll.
+//=============================================================================
+ int connectToSimpad(const int fastBaudRate,
+ int& errorNumber);
+
+//=============================================================================
+// PURPOSE: Sending a block of 512byte.
+//
+// PARAMETERS:
+// b: (IN) pointer to the beginning of the 512byte buffer.
+// len: (IN) length of the buffer.
+// errorNumber: (OUT) error number determined with
+// GetLastError().
+// RETURN VALUE:
+// TRUE: success
+// FALSE: error. See errorNumber for the reason.
+//
+// COMMENTS: The block, which is sent, is always 512byte long. If the
+// buffer counts less than 512byte, the block is filled with
+// the FILLER pattern.
+//=============================================================================
+ bool sendBlock(const char *b,
+ const int len,
+ int& errorNumber);
+
+//=============================================================================
+// PURPOSE: Waiting for the end of burning.
+//
+// PARAMETERS: -
+//
+// RETURN VALUE: -
+//
+// COMMENTS: -
+//=============================================================================
+ void waitForEndOfBurning(void);
+
+private:
+ // File descriptor of open serial port.
+ int _serialPort;
+
+//=============================================================================
+// PURPOSE: Changing baud rate.
+//
+// PARAMETERS:
+// newBaudRate: (IN) new baud rate to switch to.
+// errorNumber: (OUT) error number determined with
+// GetLastError().
+//
+// RETURN VALUE:
+// TRUE: success
+// FALSE: error. See errorNumber for the reason.
+//
+// serialMENTS: -
+//=============================================================================
+ bool changeBaudRate(const int newBaudRate,
+ int &errorNumber);
+
+//=============================================================================
+// PURPOSE: Waiting for control character.
+//
+// PARAMETERS:
+// transparent: (IN) 0 = received characters are sent to
+// stdout.
+//
+// RETURN VALUE:
+// c: control character.
+//
+// COMMENTS: -
+//=============================================================================
+ unsigned char waitForReply(const int transparent);
+
+};
+#endif // __SERIAL_DOWNLOAD
diff --git a/recipes/simpad-utilities/serload/serload.1 b/recipes/simpad-utilities/serload/serload.1
new file mode 100644
index 0000000000..4d5738b7de
--- /dev/null
+++ b/recipes/simpad-utilities/serload/serload.1
@@ -0,0 +1,38 @@
+.TH serload 1 19.08.2001 Distribution "SIMpad Serial Download"
+.SH NAME
+serload - Downloading a new image to the SIMpad
+
+.SH SYNOPSIS
+.B serload
+.I [IMAGEFILENAME] [ttyS-PORT]
+
+.SH DESCRIPTION
+.B serload
+downloads a new image to the SIMpad using
+the serial port. You need to connect the SIMpad
+to your PC with the delivered serial crossover cable
+and execute
+.B serload
+with the image name as parameter.
+As an optional parameter, you can provide the serial port
+for
+.B serload
+to use, otherwise, /dev/ttyS0 is assumed as
+default.
+.B serload
+will ask you to reset the SIMpad to
+download the new image. Depending on the image, it will
+be burnt into the Flash or directly executed in the
+RAM without burning.
+.P
+You can update the operating system,
+the firmware (PBL), and the bootloader with this utility. Updating
+the bootloader needs two steps: 1st downloading/burning
+a special bootloader (the so-called alternativ bootloader),
+2nd downloading/burning the new bootloader.
+
+.SH AUTHORS
+Peter Voser, peter.voser@siemens.ch
+.br
+Juergen Messerer, juergen.messerer@siemens.ch
+
diff --git a/recipes/simpad-utilities/simpad-utilities.bb b/recipes/simpad-utilities/simpad-utilities.bb
new file mode 100644
index 0000000000..572098a0ad
--- /dev/null
+++ b/recipes/simpad-utilities/simpad-utilities.bb
@@ -0,0 +1,5 @@
+SECTION = "console/utils"
+DESCRIPTION = "Console utilities for building the OpenSIMpad linux distribution"
+HOMEPAGE = "http://opensimpad.org"
+DEPENDS = "pad-native genboot-native serload-native"
+LICENSE = "MIT" \ No newline at end of file