collapseos/tools/upload.py
Virgil Dupras 73c3fc7947 shell/stdio: decouple from blkdev (again)
Move load/save to blkdev_cmds and add a new "poke" builtin shell cmd
that is the mirror of "peek" and strictly uses stdio (no blkdev
involved).

This allows us to slim the minimal OS size but, more importantly, change
the behavior of "load" so that we don't expect GetC to block until Z is
set. This way, using "load X" with X being larger than the blkdev size
won't block forever.

This also brings our RC2014 minimal kernel below the 1K mark again.
2019-06-02 11:06:38 -04:00

66 lines
2.0 KiB
Python
Executable File

#!/usr/bin/python
# Push specified file (max 0xff bytes) to specified device and verify that
# the contents is correct by sending a "peek" command afterwards and check
# the output. Errors out if the contents isn't the same. The parameter
# passed to the "peek" command is the length of the uploaded file.
import argparse
import os
import sys
import time
def sendcmd(fd, cmd):
# The serial link echoes back all typed characters and expects us to read
# them. We have to send each char one at a time.
print("Executing {}".format(cmd.decode()))
for c in cmd:
os.write(fd, bytes([c]))
os.read(fd, 1)
os.write(fd, b'\n')
os.read(fd, 2) # sends back \r\n
def main():
parser = argparse.ArgumentParser()
parser.add_argument('device')
parser.add_argument('filename')
args = parser.parse_args()
st = os.stat(args.filename)
if st.st_size > 0xff:
print("File too big. 0xff bytes max")
return 1
fd = os.open(args.device, os.O_RDWR)
sendcmd(fd, 'poke {:x}'.format(st.st_size).encode())
print("Poking...")
with open(args.filename, 'rb') as fp:
fcontents = fp.read()
for c in fcontents:
os.write(fd, bytes([c]))
# Let's give the machine a bit of time to breathe. We ain't in a
# hurry now, are we?
time.sleep(0.0001)
print("Poked")
os.read(fd, 5)
print("Peeking back...")
sendcmd(fd, 'peek {:x}'.format(st.st_size).encode())
peek = b''
while len(peek) < st.st_size * 2:
peek += os.read(fd, 1)
time.sleep(0.0001)
os.close(fd)
print("Got {}".format(peek.decode()))
print("Comparing...")
for i, c in enumerate(fcontents):
hexfmt = '{:02X}'.format(c).encode()
if hexfmt != peek[:2]:
print("Mismatch at byte {}! {} != {}".format(i, peek[:2], hexfmt))
return 1
peek = peek[2:]
print("All good!")
return 0
if __name__ == '__main__':
sys.exit(main())