So far, I hadn't managed to run those tools properly on OpenBSD. I was too confused by its stty peculiarities. I'm still confused, but at least I managed to make them work... most of the time...master
@@ -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 |
@@ -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 ;"); | |||
@@ -4,18 +4,33 @@ | |||
#include <errno.h> | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include <fcntl.h> | |||
#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; | |||
} |
@@ -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); |
@@ -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) { | |||
@@ -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<bytecount; i++) { | |||
read(fd, s, 2); // read hex pair | |||
mread(fd, s, 2); // read hex pair | |||
s[2] = 0; // null terminate | |||
unsigned char c = strtol(s, NULL, 16); | |||
putchar(c); | |||
@@ -35,13 +35,11 @@ int main(int argc, char **argv) | |||
return 1; | |||
} | |||
rewind(fp); | |||
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]; | |||
sprintf(s, | |||
": _ 0x%04x 0x%04x DO KEY DUP .x I C! LOOP ; _", | |||
@@ -50,8 +48,8 @@ int main(int argc, char **argv) | |||
int returncode = 0; | |||
while (fread(s, 1, 1, fp)) { | |||
putchar('.'); | |||
fflush(stdout); | |||
putc('.', stderr); | |||
fflush(stderr); | |||
unsigned char c = s[0]; | |||
write(fd, &c, 1); | |||
usleep(1000); // let it breathe | |||
@@ -69,8 +67,11 @@ int main(int argc, char **argv) | |||
} | |||
readprompt(fd); | |||
sendcmdp(fd, "FORGET _"); | |||
printf("Done!\n"); | |||
fprintf(stderr, "Done!\n"); | |||
fclose(fp); | |||
if (fd > 0) { | |||
close(fd); | |||
} | |||
return returncode; | |||
} | |||