diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 0000000..e1c3fc5 --- /dev/null +++ b/tools/README.md @@ -0,0 +1,28 @@ +# Tools + +This folder contains tools to communicate to Collapse OS machines from a modern +environment or to manipulate a blkfs. + +Communication tools all take a device path as a first argument. That device is +the serial device that connects you to your machine. It's often a USB-to-TTL +dongle. When `-` is specified, `stdin` is used as the device. + +Note that for these tools to work well, you need the serial device to be +properly set up, TTY-wise. You'll probably want to do that with `stty`. The tool +itself takes care of setting the regular stuff (`cs8`, `-parenb`, etc), but you +need to set the speed. Here's an example working on OpenBSD: + + $ ( stty 115200 ; ./upload - a000 os.bin ) <>/dev/cuaU0 + +To be honest, I'm having a bit of troubles making these tools work as well on +OpenBSD as they do in Linux. But it *does* work. Here are some advices: + +* Use `cuaXX` instead of `ttyXX`. +* Run `cu -l /dev/cuaXX` before running your tool and run a dummy command to + make sure that the output buffer is flushed. + +On Linux, it's generally easier: + +* Run screen on the device (often `/dev/ttyUSBX`) +* Quit with `CTRL+A :quit` +* Run the tool on the same device diff --git a/tools/blkup.c b/tools/blkup.c index 25dffb5..fb09ad2 100644 --- a/tools/blkup.c +++ b/tools/blkup.c @@ -22,13 +22,11 @@ int main(int argc, char **argv) fprintf(stderr, "Can't open %s.\n", argv[3]); return 1; } - int fd = open(argv[1], O_RDWR|O_NOCTTY|O_SYNC); + int fd = ttyopen(argv[1]); if (fd < 0) { fprintf(stderr, "Could not open %s\n", argv[1]); return 1; } - set_interface_attribs(fd, 0, 0); - set_blocking(fd, 1); char s[0x40]; char buf[1024] = {0}; sendcmdp(fd, ": _ 1024 0 DO KEY DUP .x I BLK( + C! LOOP ;"); diff --git a/tools/common.c b/tools/common.c index e868dda..77ad5b9 100644 --- a/tools/common.c +++ b/tools/common.c @@ -4,18 +4,33 @@ #include #include #include +#include + +#define BREATHE usleep(2000) +//#define DEBUG(...) fprintf(stderr, __VA_ARGS__) +#define DEBUG(...) void mread(int fd, char *s, int count) { while (count) { while (read(fd, s, 1) == 0) { - usleep(1000); + BREATHE; } s++; count--; } } +// Make sure that nothing is waiting in the pipeline +static void mempty(int fd) +{ + char c; + while (read(fd, &c, 1) == 1) { + DEBUG("Emptying %d\n", c); + BREATHE; + } +} + static void mexpect(int fd, char ec) { char c; @@ -36,19 +51,23 @@ void readprompt(int fd) void sendcmd(int fd, char *cmd) { + DEBUG("Sending %s\n", cmd); char junk[2]; while (*cmd) { + DEBUG("W: %d\n", *cmd); write(fd, cmd, 1); + BREATHE; read(fd, &junk, 1); + DEBUG("R: %d\n", *junk); cmd++; // The other side is sometimes much slower than us and if we don't let // it breathe, it can choke. - usleep(1000); + BREATHE; } write(fd, "\r", 1); mexpect(fd, '\r'); mexpect(fd, '\n'); - usleep(1000); + BREATHE; } // Send a cmd and also read the " ok" prompt @@ -79,6 +98,7 @@ int set_interface_attribs(int fd, int speed, int parity) // disable IGNBRK for mismatched speed tests; otherwise receive break // as \000 chars tty.c_iflag &= ~IGNBRK; // disable break processing + tty.c_iflag &= ~ICRNL; // disable CR->NL mapping tty.c_lflag = 0; // no signaling chars, no echo, // no canonical processing tty.c_oflag = 0; // no remapping, no delays @@ -118,3 +138,15 @@ void set_blocking(int fd, int should_block) } } +int ttyopen(char *devname) +{ + int fd = 0; + if (strcmp(devname, "-") != 0) { + fd = open(devname, O_RDWR|O_NOCTTY|O_SYNC); + } + set_interface_attribs(fd, 0, 0); + set_blocking(fd, 0); + mempty(fd); + set_blocking(fd, 1); + return fd; +} diff --git a/tools/common.h b/tools/common.h index 0c662b9..afba841 100644 --- a/tools/common.h +++ b/tools/common.h @@ -4,4 +4,4 @@ void mread(int fd, char *s, int count); void readprompt(int fd); int set_interface_attribs(int fd, int speed, int parity); void set_blocking(int fd, int should_block); - +int ttyopen(char *devname); diff --git a/tools/exec.c b/tools/exec.c index 5fae28d..7622b05 100644 --- a/tools/exec.c +++ b/tools/exec.c @@ -14,12 +14,11 @@ int main(int argc, char **argv) fprintf(stderr, "Usage: ./exec device\n"); return 1; } - int fd = open(argv[1], O_RDWR|O_NOCTTY|O_SYNC); + int fd = ttyopen(argv[1]); if (fd < 0) { fprintf(stderr, "Could not open %s\n", argv[1]); return 1; } - set_interface_attribs(fd, 0, 0); set_blocking(fd, 0); int c = getchar(); while (c != EOF) { diff --git a/tools/memdump.c b/tools/memdump.c index 027f302..a29ced8 100644 --- a/tools/memdump.c +++ b/tools/memdump.c @@ -27,13 +27,17 @@ int main(int argc, char **argv) return 0; } - int fd = open(argv[1], O_RDWR|O_NOCTTY); + int fd = ttyopen(argv[1]); + if (fd < 0) { + fprintf(stderr, "Could not open %s\n", argv[1]); + return 1; + } char s[0x30]; sprintf(s, ": _ 0x%04x 0x%04x DO I @ .x LOOP ; _", memptr+bytecount, memptr); sendcmd(fd, s); for (int i=0; i 0) { + close(fd); + } return returncode; }