Last active
November 19, 2019 17:03
-
-
Save pixel-stuck/b87ca37a7e5de9af5e53040a3e95bf1a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <string.h> | |
#include <fcntl.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
typedef struct __attribute__((packed)) uf2_block | |
{ | |
uint32_t magic_begin_string; | |
uint32_t magic_begin_random; | |
uint32_t flags; | |
uint32_t addr; | |
uint32_t data_size; | |
uint32_t block_num; | |
uint32_t total_blocks; | |
uint32_t family_id; | |
uint8_t data[476]; | |
uint32_t magic_end; | |
} uf2_block_t; | |
enum uf2_flags | |
{ | |
skip = 1, | |
file_container = 0x1000, | |
family_id_present = 0x2000, | |
checksum_present = 0x4000 | |
}; | |
int main(int argc, char *argv[]) | |
{ | |
if(argc < 2) | |
{ | |
printf("Please specify an input file.\n"); | |
} | |
printf("converting file %s...\n", argv[1]); | |
size_t arg_str_len = strlen(argv[1]); | |
char *out_str; | |
if(!strcmp(".uf2", &argv[1][arg_str_len - 4]) || !strcmp(".UF2", &argv[1][arg_str_len - 4])) | |
{ | |
out_str = malloc(arg_str_len + 1); | |
memset(out_str, 0, arg_str_len + 1); | |
strncpy(out_str, argv[1], arg_str_len - 4); | |
strcat(out_str, ".bin"); | |
} | |
else | |
{ | |
out_str = malloc(strlen("output.bin") + 1); | |
strcpy(out_str, "output.bin"); | |
} | |
FILE *uf2_file = fopen(argv[1], "rb"); | |
FILE *out_file = fopen(out_str, "wb"); | |
if(!uf2_file) | |
{ | |
printf("Failed to open %s\n", argv[1]); | |
return -1; | |
} | |
if(!out_file) | |
{ | |
printf("Failed to open output file %s\n", out_str); | |
return -1; | |
} | |
struct stat uf2_stat; | |
if(stat(argv[1], &uf2_stat) < 0) | |
{ | |
printf("Failed to stat %s!\nPlease make sure the file exists.\n", argv[1]); | |
return -1; | |
} | |
size_t uf2_size = uf2_stat.st_size; | |
uf2_block_t block; | |
for(int i = 0; i < uf2_size / 0x200; i++) | |
{ | |
fread(&block, 1, 0x200, uf2_file); | |
if(block.magic_begin_string == 0x0A324655 && block.magic_begin_random == 0x9E5D5157 && block.magic_end == 0x0AB16F30 && block.flags != skip) | |
{ | |
if(block.addr >= 0x2000) /* The bootloader lives in the range 0-0x1FFF, make sure we're outside of the bootloader. */ | |
{ | |
fseek(out_file, block.addr - 0x2000, SEEK_SET); | |
fwrite(&block.data[0], 1, block.data_size, out_file); | |
} | |
} | |
} | |
printf("Finished conversion!\nOutput file: %s\n", out_str); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
namespace uf2_to_bin | |
{ | |
class uf2_block | |
{ | |
public UInt32 magic_begin_string; | |
public UInt32 magic_begin_random; | |
public UInt32 flags; | |
public UInt32 addr; | |
public UInt32 data_size; | |
public UInt32 block_num; | |
public UInt32 total_blocks; | |
public UInt32 family_id; | |
public byte[] data; | |
public UInt32 magic_end; | |
} | |
class program | |
{ | |
static uf2_block read_block(FileStream uf2_f) | |
{ | |
uf2_block block = new uf2_block(); | |
byte[] tmp = new byte[4]; | |
uf2_f.Read(tmp, 0, 4); | |
block.magic_begin_string = Convert.ToUInt32(tmp); | |
if(block.magic_begin_string != 0x0A324655) | |
return null; | |
uf2_f.Read(tmp, 0, 4); | |
block.magic_begin_random = Convert.ToUInt32(tmp); | |
if(block.magic_begin_random != 0x9E5D5157) | |
return null; | |
uf2_f.Read(tmp, 0, 4); | |
block.flags = Convert.ToUInt32(tmp); | |
if((block.flags & 1) == 1) | |
return null; | |
uf2_f.Read(tmp, 0, 4); | |
block.addr = Convert.ToUInt32(tmp); | |
if(block.addr < 0x2000) | |
return null; | |
uf2_f.Read(tmp, 0, 4); | |
block.data_size = Convert.ToUInt32(tmp); | |
if(block.data_size > 476) | |
return null; | |
uf2_f.Read(tmp, 0, 4); | |
block.block_num = Convert.ToUInt32(tmp); | |
uf2_f.Read(tmp, 0, 4); | |
block.total_blocks = Convert.ToUInt32(tmp); | |
uf2_f.Read(tmp, 0, 4); | |
block.family_id = Convert.ToUInt32(tmp); | |
uf2_f.Read(block.data, 0, 476); | |
uf2_f.Read(tmp, 0, 4); | |
block.magic_end = Convert.ToUInt32(tmp); | |
if(block.magic_end != 0x0AB16F30) | |
return null; | |
return block; | |
} | |
static void main(string[] args) | |
{ | |
if(args.length < 2) | |
{ | |
Console.WriteLine("Please specify a file!\n"); | |
return 1; | |
} | |
FileStream uf2_f = new FileStream(args[1], FileMode.Open, FileAccess.Read); //open new file as read-only. | |
FileStream out_f = new FileStream("output.bin", FileMode.CreateNew, FileAccess.Write); //creates new file and opens as write-only | |
long uf2_len = uf2_f.Length | |
for(long i = 0; i < uf2_len / 0x200; i++) | |
{ | |
uf2_block block = read_block(uf2_f); | |
if(block != null) | |
{ | |
out_f.Write(block.data, block.addr - 0x2000, block.data_size); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment