Compare commits

...

4 commits

Author SHA1 Message Date
tomtomx3
7dd3a01989
Just for test purposes 2026-06-25 01:37:48 +02:00
8eb749f6f2 Build Script angepasst um arch derivate zu Unterstützen. 2026-06-24 22:31:20 +02:00
DefenderOfHyrule
71266314eb remove CLK check, apparently it's problematic for some specific/random consoles? 2026-04-19 11:05:57 +02:00
DefenderOfHyrule
c0f8d7c186
More proper implementation of my BCT resync fix and add CLK detection (#9)
* add CLK detection, apparently was never checked :P

* 2.82, more proper implementation of the BCT resync fix.

* 2.82 also contains a fingerprint (first few characters of BCT pubkey) that can be used with modchip toolbox 1.0.2.
2026-04-15 20:33:56 +02:00
6 changed files with 51 additions and 18 deletions

View file

@ -4,7 +4,7 @@
#define OFFSET_MAX 6900 #define OFFSET_MAX 6900
#define VER_HI 2 #define VER_HI 2
#define VER_LO 81 #define VER_LO 82
bool is_configured(); bool is_configured();
void init_config(); void init_config();

2
main.c
View file

@ -55,7 +55,7 @@ void self_test()
{ {
absolute_time_t tio_time = make_timeout_time_ms(2500); absolute_time_t tio_time = make_timeout_time_ms(2500);
adc_init(); adc_init();
bool rst_ok = false, cmd_ok = false, d0_ok = false, clk_ok = false; bool rst_ok = false, cmd_ok = false, d0_ok = false;
while (!time_reached(tio_time)) { while (!time_reached(tio_time)) {
if (!rst_ok) if (!rst_ok)
rst_ok |= safe_test_voltage(PIN_RST, 1.8f, 0.2f); rst_ok |= safe_test_voltage(PIN_RST, 1.8f, 0.2f);

View file

@ -544,8 +544,19 @@ bool update_firmware(uint32_t start_block, uint32_t size_blocks) {
} }
return true; return true;
} }
struct fw_info
{
uint32_t signature;
uint32_t fw_major;
uint32_t fw_minor;
uint32_t sdloader_hash;
uint32_t firmware_hash;
uint32_t fuse_count;
uint32_t bct_sub_fingerprint; // first 4 bytes of BctNormalSub
};
bool was_self_reset = false; bool was_self_reset = false;
extern int boot_try; extern int boot_try;
bool check_and_resync_bct();
bool fast_check() { bool fast_check() {
start_mmc(); start_mmc();
reinit_mmc(); reinit_mmc();
@ -596,6 +607,26 @@ bool fast_check() {
gpio_deinit(sda_pin()); gpio_deinit(sda_pin());
gpio_deinit(scl_pin()); gpio_deinit(scl_pin());
} }
// check if a syscfw update has written a new BCT to BctNormalSub since the last
// write_payload(). write_descriptor() stores a fingerprint of BctNormalSub's
// pubkey at the time write_payload() ran. if this has changed, Atmosphere has dropped
// a Main write and Sub is now ahead, resync Sub> Main and trigger rewrite_payload().
// on every normal boot this reads two blocks and returns is_space_bl unchanged.
if (is_space_bl && cmd_mmc_read(0x1FFF)) {
struct fw_info * fwi = (struct fw_info *)data_buf;
if (fwi->signature == 0x9cabe959) {
uint32_t stored = fwi->bct_sub_fingerprint;
if (cmd_mmc_read(0x040)) {
uint32_t current = *(uint32_t *)(data_buf + 0x10);
if (stored != current) {
// BctNormalSub has changed since last write_payload(), resync and rewrite
check_and_resync_bct();
stop_mmc();
return false;
}
}
}
}
stop_mmc(); stop_mmc();
return is_space_bl; return is_space_bl;
} }
@ -642,16 +673,6 @@ void copy_bct(int start, int end) {
} }
} }
struct fw_info
{
uint32_t signature;
uint32_t fw_major;
uint32_t fw_minor;
uint32_t sdloader_hash;
uint32_t firmware_hash;
uint32_t fuse_count;
};
extern bool do_burn_fuses; extern bool do_burn_fuses;
void write_descriptor() void write_descriptor()
@ -668,6 +689,11 @@ void write_descriptor()
fwi->fw_minor = VER_LO; fwi->fw_minor = VER_LO;
fwi->sdloader_hash = payload_crc(); fwi->sdloader_hash = payload_crc();
fwi->firmware_hash = boot_slot ? fw_slot_1->crc : fw_slot_0->crc; fwi->firmware_hash = boot_slot ? fw_slot_1->crc : fw_slot_0->crc;
// store first 4 bytes of BctNormalSub pubkey
// so we can detect on next boot if a syscfw update has written a new BCT to Sub
fwi->bct_sub_fingerprint = 0;
if (cmd_mmc_read(0x040))
fwi->bct_sub_fingerprint = *(uint32_t *)(data_buf + 0x10);
// write the info block // write the info block
write_data(desc_block, temp_buf, 512); write_data(desc_block, temp_buf, 512);
} }
@ -745,21 +771,24 @@ static bool bct_block_has_modchip_magic(int bct_start_block) {
return magic == (mariko ? 0xA56CA203 : 0x69696969); return magic == (mariko ? 0xA56CA203 : 0x69696969);
} }
void check_and_resync_bct() { bool check_and_resync_bct() {
// only relevant on a configured boot where space_bl magic is already present, // only relevant on a configured boot where space_bl magic is already present,
// meaning write_payload has previously run and wrote the synthetic/fake BCT. // meaning write_payload has previously run and wrote the synthetic/fake BCT.
// if the chip is not yet configured there is nothing to resync. // if the chip is not yet configured there is nothing to resync.
if (!is_space_bl) if (!is_space_bl)
return; return false;
// check Normal BCT pair; Main has magic, Sub does not > Sub has a newer Nintendo BCT // check Normal BCT pair; Main has magic, Sub does not > Sub has a newer Nintendo BCT
bool normal_main_magic = bct_block_has_modchip_magic(0x000); bool normal_main_magic = bct_block_has_modchip_magic(0x000);
bool normal_sub_magic = bct_block_has_modchip_magic(0x040); bool normal_sub_magic = bct_block_has_modchip_magic(0x040);
bool resynced = false;
if (normal_main_magic && !normal_sub_magic) { if (normal_main_magic && !normal_sub_magic) {
// BctNormalSub was updated by a firmware update but BctNormalMain write was // BctNormalSub was updated by a firmware update but BctNormalMain write was
// dropped by Atmosphere. copy Sub > Main to resync. // dropped by Atmosphere. copy Sub > Main to resync.
copy_bct(0x040, 0x000); copy_bct(0x040, 0x000);
resynced = true;
} }
// check Safe BCT pair; uses same logic // check Safe BCT pair; uses same logic
@ -768,7 +797,10 @@ void check_and_resync_bct() {
if (safe_main_magic && !safe_sub_magic) { if (safe_main_magic && !safe_sub_magic) {
copy_bct(0x060, 0x020); copy_bct(0x060, 0x020);
resynced = true;
} }
return resynced;
} }
void write_payload() { void write_payload() {

View file

@ -19,7 +19,7 @@ fi
# detect distribution # detect distribution
if [ -f /etc/os-release ]; then if [ -f /etc/os-release ]; then
. /etc/os-release . /etc/os-release
DISTRO=$ID DISTRO=${ID-LIKE:-$ID}
else else
echo -e "${RED}Error: Cannot detect distribution${NC}" echo -e "${RED}Error: Cannot detect distribution${NC}"
exit 1 exit 1
@ -128,4 +128,4 @@ echo -e " - update.bin: ${WORKSPACE}/build/usk/update.bin"
USK_VERSION_LO=$(sed -n 's/#define VER_LO \([0-9]*\)/\1/p' "$USK_DIR/config.h") USK_VERSION_LO=$(sed -n 's/#define VER_LO \([0-9]*\)/\1/p' "$USK_DIR/config.h")
USK_VERSION_HI=$(sed -n 's/#define VER_HI \([0-9]*\)/\1/p' "$USK_DIR/config.h") USK_VERSION_HI=$(sed -n 's/#define VER_HI \([0-9]*\)/\1/p' "$USK_DIR/config.h")
USK_VERSION="${USK_VERSION_HI}.${USK_VERSION_LO}" USK_VERSION="${USK_VERSION_HI}.${USK_VERSION_LO}"
echo -e "${GREEN}Version: Picofly ${USK_VERSION}${NC}\n" echo -e "${GREEN}Version: Picofly ${USK_VERSION}${NC}\n"

View file

@ -12,7 +12,7 @@ echo -e "${GREEN}=== Picofly build script (multi-distro) ===${NC}\n"
# detect distribution # detect distribution
if [ -f /etc/os-release ]; then if [ -f /etc/os-release ]; then
. /etc/os-release . /etc/os-release
DISTRO=$ID DISTRO=${ID_LIKE:-$ID}
else else
echo -e "${RED}Error: Cannot detect distribution${NC}" echo -e "${RED}Error: Cannot detect distribution${NC}"
exit 1 exit 1
@ -127,4 +127,4 @@ echo -e " - update.bin: ${WORKSPACE}/build/usk/update.bin"
USK_VERSION_LO=$(sed -n 's/#define VER_LO \([0-9]*\)/\1/p' "$WORKSPACE/usk/config.h") USK_VERSION_LO=$(sed -n 's/#define VER_LO \([0-9]*\)/\1/p' "$WORKSPACE/usk/config.h")
USK_VERSION_HI=$(sed -n 's/#define VER_HI \([0-9]*\)/\1/p' "$WORKSPACE/usk/config.h") USK_VERSION_HI=$(sed -n 's/#define VER_HI \([0-9]*\)/\1/p' "$WORKSPACE/usk/config.h")
USK_VERSION="${USK_VERSION_HI}.${USK_VERSION_LO}" USK_VERSION="${USK_VERSION_HI}.${USK_VERSION_LO}"
echo -e "${GREEN}Version: Picofly ${USK_VERSION}${NC}\n" echo -e "${GREEN}Version: Picofly ${USK_VERSION}${NC}\n"

1
test123 Normal file
View file

@ -0,0 +1 @@
asdöfgljkklgj