Add cmd checksum check
This commit is contained in:
parent
da195bbba5
commit
a865750dca
BIN
Overlay.ovl0
BIN
Overlay.ovl0
Binary file not shown.
BIN
Overlay.ovl1
BIN
Overlay.ovl1
Binary file not shown.
Binary file not shown.
15
ovl-upload.c
15
ovl-upload.c
@ -110,7 +110,7 @@ char * ptrToChar[8]; // Will hold the name of the file to load.
|
|||||||
|
|
||||||
volatile u_char loadFileID = 0; // Will hold an ID that's unique for each file.
|
volatile u_char loadFileID = 0; // Will hold an ID that's unique for each file.
|
||||||
|
|
||||||
u_char overlayFileID, loadFileIDwas;
|
u_char overlayFileID = 0, loadFileIDwas = 0;
|
||||||
|
|
||||||
// Timer for the pad
|
// Timer for the pad
|
||||||
|
|
||||||
@ -124,6 +124,8 @@ u_char protocol = 1; // Hypothetical ID number for the pcdrv protocol in
|
|||||||
|
|
||||||
u_char command = LOAD; // We're loading the data here
|
u_char command = LOAD; // We're loading the data here
|
||||||
|
|
||||||
|
uint32_t checkSum = 0;
|
||||||
|
|
||||||
// Prototypes
|
// Prototypes
|
||||||
|
|
||||||
void init(void);
|
void init(void);
|
||||||
@ -334,9 +336,9 @@ int main() {
|
|||||||
// We send the memory address where the file should be loaded, the memory address of the loadFileID, so that the screen is updated when it changes, and the file id.
|
// We send the memory address where the file should be loaded, the memory address of the loadFileID, so that the screen is updated when it changes, and the file id.
|
||||||
// format : 00(:)01(:)06(:)04 xx xx xx xx(:)04 xx xx xx xx(:)01 (separators are not send)
|
// format : 00(:)01(:)06(:)04 xx xx xx xx(:)04 xx xx xx xx(:)01 (separators are not send)
|
||||||
// 14 bytes
|
// 14 bytes
|
||||||
|
|
||||||
PCload( &load_all_overlays_here, &loadFileID, overlayFileID );
|
PCload( &load_all_overlays_here, &loadFileID, overlayFileID );
|
||||||
|
|
||||||
#ifdef USECD
|
#ifdef USECD
|
||||||
|
|
||||||
// We can do that because we only have two files
|
// We can do that because we only have two files
|
||||||
@ -429,15 +431,12 @@ int main() {
|
|||||||
nextpri += sizeof(DR_MODE);
|
nextpri += sizeof(DR_MODE);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FntPrint("Hello overlay!\n");
|
FntPrint("Hello overlay!\n");
|
||||||
|
|
||||||
#ifndef USECD
|
#ifndef USECD
|
||||||
|
|
||||||
//~ u_int cmdChecksum = 8 + ptrChecksum(&load_all_overlays_here) +
|
FntPrint("Overlay with id %d loaded at 0x%08x\n%x", overlayFileID, &load_all_overlays_here, &overlayFileID );
|
||||||
//~ 8 + ptrChecksum((u_long *)&loadFileID) +
|
|
||||||
//~ overlayFileID;
|
|
||||||
|
|
||||||
FntPrint("Overlay with id %d loaded at 0x%08x", overlayFileID, &load_all_overlays_here );
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Binary file not shown.
271
ovl-upload.py
271
ovl-upload.py
@ -25,7 +25,6 @@ import serial
|
|||||||
import time
|
import time
|
||||||
import calendar
|
import calendar
|
||||||
import math
|
import math
|
||||||
import signal
|
|
||||||
|
|
||||||
DEBUG = 1
|
DEBUG = 1
|
||||||
|
|
||||||
@ -100,12 +99,6 @@ Transfer = 0
|
|||||||
|
|
||||||
sleepTime = 0.08 # Seems like safe minimum
|
sleepTime = 0.08 # Seems like safe minimum
|
||||||
|
|
||||||
def sig_interrupt_handler(signal, frame):
|
|
||||||
|
|
||||||
global Run
|
|
||||||
|
|
||||||
Run = False
|
|
||||||
|
|
||||||
def setDEBG():
|
def setDEBG():
|
||||||
|
|
||||||
global sleepTime, ser, uniDebugMode
|
global sleepTime, ser, uniDebugMode
|
||||||
@ -126,6 +119,19 @@ def setDEBG():
|
|||||||
|
|
||||||
uniDebugMode = 1
|
uniDebugMode = 1
|
||||||
|
|
||||||
|
# stole it here : https://gist.github.com/amakukha/7854a3e910cb5866b53bf4b2af1af968
|
||||||
|
# TODO : fixit to have the same results as https://github.com/grumpycoders/pcsx-redux/blob/main/src/mips/common/util/djbhash.h
|
||||||
|
|
||||||
|
def hash_djb2(s):
|
||||||
|
|
||||||
|
hash = 5381
|
||||||
|
|
||||||
|
for x in s:
|
||||||
|
|
||||||
|
hash = ((( hash << 5) + hash) ^ x) & 0xFFFFFFFF
|
||||||
|
|
||||||
|
return hash
|
||||||
|
|
||||||
def WaitForResponse( expectedAnswer ):
|
def WaitForResponse( expectedAnswer ):
|
||||||
|
|
||||||
# Get incoming data from the serial port in a rolling buffer
|
# Get incoming data from the serial port in a rolling buffer
|
||||||
@ -498,166 +504,151 @@ def main(args):
|
|||||||
if inputBuffer:
|
if inputBuffer:
|
||||||
|
|
||||||
# We're expecting the command with format : 00 01 06 08 xx xx xx xx 08 xx xx xx xx 01 xx xx (16 bytes)
|
# We're expecting the command with format : 00 01 06 08 xx xx xx xx 08 xx xx xx xx 01 xx xx (16 bytes)
|
||||||
|
|
||||||
# Rolling buffer
|
|
||||||
|
|
||||||
# ~ byte = ser.read(1)
|
|
||||||
|
|
||||||
# Make sure byte value is < 128 so that it can be decoded to ascii
|
|
||||||
|
|
||||||
# ~ if byte[0] < 128:
|
|
||||||
|
|
||||||
# ~ inputBuffer += byte.decode('ascii')
|
|
||||||
|
|
||||||
# ~ else:
|
|
||||||
|
|
||||||
# ~ inputBuffer += '.'
|
if len(inputBuffer) == 38:
|
||||||
|
|
||||||
if len(inputBuffer) >= 32:
|
|
||||||
|
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
|
|
||||||
print( "Incoming data : " + inputBuffer )
|
print( "Incoming data : " + inputBuffer )
|
||||||
|
|
||||||
# If inputBuffer is > 32, remove first char
|
# Get the checksum and remove it from the buffer
|
||||||
|
|
||||||
# ~ if len(inputBuffer) > 32:
|
CmdCheckSum = inputBuffer[-10:]
|
||||||
|
|
||||||
# ~ inputBuffer = inputBuffer[1:]
|
|
||||||
|
|
||||||
# Parse command
|
|
||||||
|
|
||||||
if inputBuffer[:2] == pcdrvEscape:
|
if DEBUG:
|
||||||
|
|
||||||
|
print( "Received ChkSm: " + CmdCheckSum )
|
||||||
|
|
||||||
if DEBUG:
|
# Remove checksum from data
|
||||||
|
|
||||||
|
inputBuffer = inputBuffer[:28]
|
||||||
|
|
||||||
|
dataCheckSum = hash_djb2(bytes(inputBuffer, 'ascii'))
|
||||||
|
|
||||||
|
if DEBUG:
|
||||||
|
|
||||||
|
print( "Computed ChkSm: " + str(dataCheckSum) )
|
||||||
|
|
||||||
|
# Not using the checksum for now
|
||||||
|
|
||||||
|
# ~ dataCheckSum = 0
|
||||||
|
|
||||||
|
# ~ CmdCheckSum = 0
|
||||||
|
|
||||||
|
# Check
|
||||||
|
|
||||||
|
if int(dataCheckSum) == int(CmdCheckSum):
|
||||||
|
|
||||||
print( "Received Escape : " + inputBuffer[:2] )
|
# Parse command
|
||||||
|
|
||||||
# Escape byte received, remove it from buffer and continue
|
if inputBuffer[:2] == pcdrvEscape:
|
||||||
|
|
||||||
inputBuffer = inputBuffer[2:]
|
|
||||||
|
|
||||||
if inputBuffer[:2] == pcdrvProtocol:
|
|
||||||
|
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
|
|
||||||
print( "Received Proto: " + inputBuffer[:2] )
|
|
||||||
|
|
||||||
# Protocol byte is pcdrv (01), remove it from buffer and continue
|
print( "Received Escape : " + inputBuffer[:2] )
|
||||||
|
|
||||||
|
# Escape byte received, remove it from buffer and continue
|
||||||
|
|
||||||
inputBuffer = inputBuffer[2:]
|
inputBuffer = inputBuffer[2:]
|
||||||
|
|
||||||
if inputBuffer[:2] == pcdrvCommand:
|
if inputBuffer[:2] == pcdrvProtocol:
|
||||||
|
|
||||||
if DEBUG:
|
|
||||||
|
|
||||||
print( "Received Cmd: " + inputBuffer[:2] )
|
if DEBUG:
|
||||||
|
|
||||||
# Command byte is valid (06), remove it from buffer and continue
|
print( "Received Proto: " + inputBuffer[:2] )
|
||||||
|
|
||||||
|
# Protocol byte is pcdrv (01), remove it from buffer and continue
|
||||||
|
|
||||||
inputBuffer = inputBuffer[2:]
|
inputBuffer = inputBuffer[2:]
|
||||||
|
|
||||||
# Get 2 checksum bytes in buffer
|
|
||||||
|
|
||||||
CmdCheckSum = inputBuffer[-4:]
|
if inputBuffer[:2] == pcdrvCommand:
|
||||||
|
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
|
|
||||||
print( "Received ChkSm: " + CmdCheckSum )
|
|
||||||
|
|
||||||
# Calculate checksum on the data - 2 checksum bytes
|
|
||||||
|
|
||||||
dataInBuffer = inputBuffer[:-4]
|
|
||||||
|
|
||||||
if DEBUG:
|
|
||||||
|
|
||||||
print( "Data in buffer: " + dataInBuffer )
|
|
||||||
|
|
||||||
# TODO find a way to calc command checksum in ovl-upload.c ( see l.440 )
|
|
||||||
|
|
||||||
# ~ work = dataInBuffer
|
|
||||||
|
|
||||||
# ~ for c in dataInBuffer:
|
|
||||||
|
|
||||||
# ~ dataCheckSum += int(c, 16)
|
print( "Received Cmd: " + inputBuffer[:2] )
|
||||||
|
|
||||||
|
# Command byte is valid (06), remove it from buffer and continue
|
||||||
|
|
||||||
# ~ if DEBUG:
|
inputBuffer = inputBuffer[2:]
|
||||||
|
|
||||||
# ~ print( "Generated ChkSm: " + str(dataCheckSum) )
|
|
||||||
|
|
||||||
# Not using the checksum for now
|
|
||||||
|
|
||||||
dataCheckSum = 0
|
|
||||||
|
|
||||||
CmdCheckSum = 0
|
|
||||||
|
|
||||||
# Check
|
|
||||||
|
|
||||||
if int(dataCheckSum) == int(CmdCheckSum):
|
|
||||||
|
|
||||||
dataLen = 0
|
|
||||||
|
|
||||||
# Get data length byte
|
dataInBuffer = inputBuffer
|
||||||
|
|
||||||
dataLen = dataInBuffer[:2]
|
|
||||||
|
|
||||||
dataInBuffer = dataInBuffer[2:]
|
|
||||||
|
|
||||||
# Get actual data
|
|
||||||
|
|
||||||
for b in dataInBuffer :
|
|
||||||
|
|
||||||
if len(memAddr) < int(dataLen) :
|
|
||||||
|
|
||||||
memAddr += b
|
|
||||||
|
|
||||||
# Remove data from buffer
|
|
||||||
|
|
||||||
dataInBuffer = dataInBuffer[int(dataLen):]
|
|
||||||
|
|
||||||
if DEBUG > 1:
|
|
||||||
|
|
||||||
print( "Data in buffer 1: " + dataInBuffer )
|
|
||||||
|
|
||||||
dataLen = 0
|
|
||||||
|
|
||||||
dataLen = dataInBuffer[:2]
|
|
||||||
|
|
||||||
dataInBuffer = dataInBuffer[2:]
|
|
||||||
|
|
||||||
# Get actual data
|
|
||||||
|
|
||||||
for b in dataInBuffer :
|
|
||||||
|
|
||||||
if len(flagAddr) < int(dataLen) :
|
|
||||||
|
|
||||||
flagAddr += b
|
|
||||||
|
|
||||||
# Remove data from buffer
|
|
||||||
|
|
||||||
dataInBuffer = dataInBuffer[int(dataLen):]
|
|
||||||
|
|
||||||
if DEBUG > 1:
|
|
||||||
|
|
||||||
print( "Data in buffer 2: " + dataInBuffer )
|
|
||||||
|
|
||||||
# We should only have two bytes remaining
|
|
||||||
|
|
||||||
if len(dataInBuffer) == 2:
|
|
||||||
|
|
||||||
loadFile = int(dataInBuffer)
|
|
||||||
|
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
|
|
||||||
print( memAddr + " - " + flagAddr + " - " + str(loadFile) )
|
print( "Data in buffer: " + dataInBuffer )
|
||||||
|
|
||||||
|
dataLen = 0
|
||||||
|
|
||||||
|
# Get data length byte
|
||||||
|
|
||||||
|
dataLen = dataInBuffer[:2]
|
||||||
|
|
||||||
|
dataInBuffer = dataInBuffer[2:]
|
||||||
|
|
||||||
|
# Get actual data
|
||||||
|
|
||||||
|
for b in dataInBuffer :
|
||||||
|
|
||||||
|
if len(memAddr) < int(dataLen) :
|
||||||
|
|
||||||
|
memAddr += b
|
||||||
|
|
||||||
|
# Remove data from buffer
|
||||||
|
|
||||||
|
dataInBuffer = dataInBuffer[int(dataLen):]
|
||||||
|
|
||||||
|
if DEBUG > 1:
|
||||||
|
|
||||||
|
print( "Data in buffer 1: " + dataInBuffer )
|
||||||
|
|
||||||
|
dataLen = 0
|
||||||
|
|
||||||
|
dataLen = dataInBuffer[:2]
|
||||||
|
|
||||||
|
dataInBuffer = dataInBuffer[2:]
|
||||||
|
|
||||||
|
# Get actual data
|
||||||
|
|
||||||
|
for b in dataInBuffer :
|
||||||
|
|
||||||
|
if len(flagAddr) < int(dataLen) :
|
||||||
|
|
||||||
|
flagAddr += b
|
||||||
|
|
||||||
|
# Remove data from buffer
|
||||||
|
|
||||||
|
dataInBuffer = dataInBuffer[int(dataLen):]
|
||||||
|
|
||||||
|
if DEBUG > 1:
|
||||||
|
|
||||||
|
print( "Data in buffer 2: " + dataInBuffer )
|
||||||
|
|
||||||
|
# We should only have two bytes remaining
|
||||||
|
|
||||||
|
if len(dataInBuffer) == 2:
|
||||||
|
|
||||||
|
loadFile = int(dataInBuffer)
|
||||||
|
|
||||||
|
if DEBUG:
|
||||||
|
|
||||||
|
print( memAddr + " - " + flagAddr + " - " + str(loadFile) )
|
||||||
|
|
||||||
ser.reset_input_buffer()
|
ser.reset_input_buffer()
|
||||||
|
|
||||||
|
inputBuffer = ""
|
||||||
|
|
||||||
|
Listen = 0
|
||||||
|
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
|
||||||
inputBuffer = ""
|
print("Command checksum not matching ! Aborting...")
|
||||||
|
|
||||||
Listen = 0
|
ser.reset_input_buffer()
|
||||||
|
|
||||||
break
|
inputBuffer = ""
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
|
29
pcdrv.c
29
pcdrv.c
@ -1,6 +1,6 @@
|
|||||||
#include "pcdrv.h"
|
#include "pcdrv.h"
|
||||||
|
|
||||||
int ptrChecksum( u_long * pointer ){
|
int doChecksum( u_long * pointer ){
|
||||||
|
|
||||||
u_int checksum = 0;
|
u_int checksum = 0;
|
||||||
|
|
||||||
@ -8,7 +8,7 @@ int ptrChecksum( u_long * pointer ){
|
|||||||
|
|
||||||
work = ( u_long ) pointer - 0x80000000 ;
|
work = ( u_long ) pointer - 0x80000000 ;
|
||||||
|
|
||||||
while( work != 0 ){
|
while( work != 0 ){
|
||||||
|
|
||||||
checksum += work % 10;
|
checksum += work % 10;
|
||||||
|
|
||||||
@ -19,12 +19,25 @@ int ptrChecksum( u_long * pointer ){
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Hashing algorythm from @nicolasnoble : https://github.com/grumpycoders/pcsx-redux/blob/main/src/mips/common/util/djbhash.h
|
||||||
|
|
||||||
|
static inline uint32_t djbProcess(uint32_t hash, const char str[], unsigned n) {
|
||||||
|
|
||||||
|
return n ? djbProcess ( ( ( hash << 5 ) + hash ) ^ str[0], str + 1, n - 1) : hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t djbHash( const char* str, unsigned n ){
|
||||||
|
|
||||||
|
return djbProcess( 5381, str, n);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
int waitForSIODone( int * flag ){
|
int waitForSIODone( int * flag ){
|
||||||
|
|
||||||
// This should wait for a signal from the SIO to tell when it's done
|
// This should wait for a signal from the SIO to tell when it's done
|
||||||
// Returns val < 0 if wrong
|
// Returns val < 0 if wrong
|
||||||
|
|
||||||
uint timeOut = 1000;
|
uint16_t timeOut = 1000;
|
||||||
|
|
||||||
char result = 0;
|
char result = 0;
|
||||||
|
|
||||||
@ -51,8 +64,14 @@ void PCload( u_long * loadAddress, volatile u_char * flagAddress, u_char overlay
|
|||||||
|
|
||||||
u_char protocol = 1; // Hypothetical protocol indicator for unirom
|
u_char protocol = 1; // Hypothetical protocol indicator for unirom
|
||||||
|
|
||||||
u_char cmdChecksum = 0; // Not using that yet, ideally, should allow to check that the received command on the pc is the same as the one sent by the psx
|
//~ u_char cmdChecksum = 0; // Not using that yet, ideally, should allow to check that the received command on the pc is the same as the one sent by the psx
|
||||||
|
|
||||||
printf("%02u%02u%02u08%08x08%08x%02u%04u", escape, protocol, LOAD, loadAddress, flagAddress, overlayFileID, cmdChecksum);
|
char commandBuffer[28];
|
||||||
|
|
||||||
|
sprintf(commandBuffer, "%02u%02u%02u08%08x08%08x%02u", escape, protocol, LOAD, loadAddress, flagAddress, overlayFileID);
|
||||||
|
|
||||||
|
u_int cmdChecksum = djbHash(commandBuffer, 28);
|
||||||
|
|
||||||
|
printf("%s%10u", commandBuffer, cmdChecksum);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
28
pcdrv.h
28
pcdrv.h
@ -1,7 +1,24 @@
|
|||||||
|
// https://discord.com/channels/642647820683444236/646765703143227394/836663602718048297
|
||||||
|
// 28-04-2021 - @nicolasnoble:
|
||||||
|
//
|
||||||
|
// step 0 : have a protocol that can handle open / close / seek / read / write
|
||||||
|
//
|
||||||
|
// step 1 : have an unhandled exception handler installed in the kernel to capture the pcdrv functions; that sounds scary, but it's extremely straightforward (I think @sickle currently has one for his debugger)
|
||||||
|
//
|
||||||
|
// step 1.5: implement the pcopen / pcclose / pcread / pcwrite / pcseek functions, which are basically the same model as my syscalls.h file
|
||||||
|
//
|
||||||
|
// step 2 : implement the unhandler exception handler in a way that properly redirects the calls to the step 0 protocol, and returns gracefully to the caller when done - that can be a bit tricky, but it's totally doable
|
||||||
|
// this step requires understanding the ReturnFromException mechanism basically which, to be fair, is sort of understandable from this one file:
|
||||||
|
// https://github.com/grumpycoders/pcsx-redux/blob/main/src/mips/openbios/handlers/syscall.c
|
||||||
|
// you can see the syscall_unresolvedException() call at the bottom , this just needs to follow the same pattern
|
||||||
|
// and break down the caller, modify the current thread's registers, and return to the caller
|
||||||
|
// at this point, we have a working basic pcdrv feature, using pcopen / pcclose / pcread / pcwrite / pcseek
|
||||||
|
//
|
||||||
|
// step 3 : add a kernel driver for "pcdrv:" that just piggy backs on pc* functions so that people can simply do a int file = open("pcdrv:blah.txt", O_RDONLY);
|
||||||
|
// (and thus support things like CSOTN technically)
|
||||||
|
//
|
||||||
// https://discord.com/channels/642647820683444236/646765703143227394/837416216640618558
|
// https://discord.com/channels/642647820683444236/646765703143227394/837416216640618558
|
||||||
|
|
||||||
// So like we'd have, say,
|
// So like we'd have, say,
|
||||||
|
|
||||||
// 00 01 00 03 58 58 58 01 xx for pcdrv' file open to open the file name "XXX" and attribute 1
|
// 00 01 00 03 58 58 58 01 xx for pcdrv' file open to open the file name "XXX" and attribute 1
|
||||||
|
|
||||||
// (escape) (pcdrv command) (pcdrv open) (filename with length as prefix) (attributes) (checksum)
|
// (escape) (pcdrv command) (pcdrv open) (filename with length as prefix) (attributes) (checksum)
|
||||||
@ -10,6 +27,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
@ -23,7 +41,11 @@
|
|||||||
#define CREATE 5
|
#define CREATE 5
|
||||||
#define LOAD 6
|
#define LOAD 6
|
||||||
|
|
||||||
int ptrChecksum( u_long * pointer );
|
static inline uint32_t djbHash( const char* str, unsigned n );
|
||||||
|
|
||||||
|
static inline uint32_t djbProcess(uint32_t hash, const char str[], unsigned n);
|
||||||
|
|
||||||
|
int doChecksum( u_long * pointer );
|
||||||
|
|
||||||
int waitForSIODone( int * flag );
|
int waitForSIODone( int * flag );
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user