4
0
raspi-alpine-builder/resources/uboot.c
2019-11-08 22:33:12 +01:00

126 lines
3.1 KiB
C

#include <stdio.h>
#include <stdint.h>
#include <string.h>
char* uboot_file = "/uboot/uboot.dat";
void printHelp() {
printf("Usage: uboot_tool [COMMAND]\n");
printf("\n");
printf("Commands:\n");
printf(" part_current - show current partition\n");
printf(" part_switch - switch active partition\n");
printf(" reset_counter - reset boot counter\n");
printf(" version - show version of file\n");
}
uint32_t crc32(uint8_t* data, size_t length, uint32_t seed) {
uint32_t crc = ~seed;
while (length--) {
crc ^= (*data++);
for (unsigned int j = 0; j < 8; j++) {
if (crc & 1) {
crc = (crc >> 1) ^ 0xedb88320L;
} else {
crc = crc >> 1;
}
}
}
return ~crc;
}
int main(int argc, char* argv[]) {
// show help if no command given
if (argc < 2) {
printHelp();
return 1;
}
char* cmd = argv[1];
// read uboot file
FILE* file = fopen(uboot_file, "rb");
if (file == NULL) {
printf("Failed to open uboot file: %s\n", uboot_file);
return 2;
}
uint8_t data[1024];
size_t err = fread(data, 1, sizeof(data), file);
if (err == 0) {
printf("Failed to read uboot file: %s\n", uboot_file);
return 2;
}
fclose(file);
// get crc from file
uint32_t crc = (data[1023] << 24) +
(data[1022] << 16) +
(data[1021] << 8) +
data[1020];
// check if CRC is valid
if (crc != crc32(data, 0x3FC, 0)) {
fprintf(stderr, "Invalid CRC -> fallback to default\n");
memset(data, 0, sizeof(data));
// file version
data[0] = 1;
// boot counter
data[1] = 0;
// boot partition
data[2] = 2; // A=2, B=3
}
// handle commands
uint8_t save = 0;
if (strcmp(cmd, "version") == 0) {
printf("0x%02x\n", data[0]);
} else if (strcmp(cmd, "part_current") == 0) {
printf("%d\n", data[2]);
} else if (strcmp(cmd, "part_switch") == 0) {
if (data[2] == 2) {
data[2] = 3;
} else {
data[2] = 2;
}
save = 1;
} else if (strcmp(cmd, "reset_counter") == 0) {
data[1] = 0;
save = 1;
} else {
printf("Unknown command\n");
return 10;
}
if (save == 1) {
// calculate new CRC
crc = crc32(data, 0x3FC, 0);
data[1023] = (uint8_t)((crc & 0xFF000000U)>>24);
data[1022] = (uint8_t)((crc & 0x00FF0000U)>>16);
data[1021] = (uint8_t)((crc & 0x0000FF00U)>>8);
data[1020] = (uint8_t)((crc & 0x000000FFU));
// write uboot file
file = fopen(uboot_file, "wb");
if (file == NULL) {
printf("Failed to open uboot file: %s\n", uboot_file);
return 4;
}
size_t err = fwrite(data, 1, sizeof(data), file);
if (err == 0) {
printf("Failed to write uboot file: %s\n", uboot_file);
return 4;
}
fclose(file);
}
return 0;
}