Browse Source

tools: improve usability on OpenBSD

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
Virgil Dupras 3 years ago
parent
commit
c2b507eaff
7 changed files with 79 additions and 17 deletions
  1. +28
    -0
      tools/README.md
  2. +1
    -3
      tools/blkup.c
  3. +35
    -3
      tools/common.c
  4. +1
    -1
      tools/common.h
  5. +1
    -2
      tools/exec.c
  6. +6
    -2
      tools/memdump.c
  7. +7
    -6
      tools/upload.c

+ 28
- 0
tools/README.md View File

@@ -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

+ 1
- 3
tools/blkup.c View File

@@ -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 ;");


+ 35
- 3
tools/common.c View File

@@ -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;
}

+ 1
- 1
tools/common.h View File

@@ -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);

+ 1
- 2
tools/exec.c View File

@@ -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) {


+ 6
- 2
tools/memdump.c View File

@@ -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);


+ 7
- 6
tools/upload.c View File

@@ -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;
}


Loading…
Cancel
Save