Hardware nand flash dump (3ds xl)

  • Thread starter Thread starter lightenup
  • Start date Start date
  • Views Views 640,687
  • Replies Replies 1,973
  • Likes Likes 6
hey if i make a DIY/NAND backup of my 4.5 firmware befor using my gateway, and get bricked in the future i can allways unbrick my 3ds, by reinstalling the old nand.bin right?

nope, gateway locks the eMMC controller and you cant reflash a new NAND onto it. I and some other users are working on a way to unlock it, but we still have a lot to do.
 
Dan-the-Rebirth
As stated before in this thread, it is not that easy.
You need a device capable of doing low level communication with the eMMC. That can be an Arduino or a Raspberry or something similar. A simple Card reader will not be enough if you are bricked.

EDIT: Well, that was too late.
 
nope, gateway locks the eMMC controller and you cant reflash a new NAND onto it. I and some other users are working on a way to unlock it, but we still have a lot to do.

Why not create a new thread writing in first post your updates? :toot: All the info are dispersed and it´s difficult for newbs
 
Why not create a new thread writing in first post your updates? :toot: All the info are dispersed and it´s difficult for newbs

I dont really have anything atm, I have some code on pc but I cant test it because my arduino should come on friday or next monday.
 
Has anyone tried any of this yet? Or people still waiting for their parts to arrive?
Seems promising, would be good to know there's always a Unbricking method
 
How successful are clone-card NAND backup? I did one a while ago but haven't tested it. Can I trust the backup-file 100%?
 
so it means the faq on maxconsoles is wrong
Q: My 3DS is stuck on Blue Screen of Death after playing. GW is dangerous aaah!
A: Calm down. This crash is due to a memory corruption from modified GW software (such as the region free patch and clone firmware). You will have to reflash a 4.5 back to the 3DS. If you did not back up your NAND before use, then I'm sorry, you failed lesson number 2: Better safe than sorry.
 
20140123_000050.jpg
20140123_000220.jpg


just finished mine
 
Wow........that is nice, super clean. I like how you used the existing hole in the case (used for the strap?) to place the usb port. Did you have to cut it any or did the port just fit right in there?
 
Wow........that is nice, super clean. I like how you used the existing hole in the case (used for the strap?) to place the usb port. Did you have to cut it any or did the port just fit right in there?


Only Microusb, Miniusb makes a huge mess :P
 
Personally, I don't like having it so blatantly obvious that you've modded your hardware. When I get mine done, I'm having it put under the battery cover like some of the earlier posts, that way nobody will know unless you take the battery cover off.

It's not like you're going to be NAND flashing every day or something, it's more of a fail-safe backup system.
 
If we are unlucky, the eMMC doesn't even support SPI Mode... It was removed from v4.4 v4.3 of the specs in 2009...

EDIT. Sorry, krisztian1997 is right. It was removed even earlier in 4.3

That would be unfortunate, because SPI allows no CRC detection (unsafe but guaranteed CMDs will arrive at some moment).


And if everything fails:
one can still access these commands (SD or SPI mode):
33wy73r.jpg

given eMMC does not support SPI mode (1bit), it would jump directly to SD0(1bit) mode, right? CMD42 can still be accessed.

SD0 (1bit) mode is CLK,GND,CMD,VCC,DAT0 (1:1 SD to SD controller) or, the same approach used in this guide.


But for SD mode we need the CRC16 sent to be correct. And, i'm 99% sure this can be issued in SD mode as well:
316m9gm.jpg

Remember that SD mode is the one used by the OP (DAT0,CMD,GND,VCC,CLK) 1:1 on both devices

This is for people with raspberry pi's:

Code:
typedef struct EMMCCommand
  {
  const char* name;
  unsigned int code;
  unsigned char resp;
  unsigned char rca;
  int delay;
  } EMMCCommand;
 
// Command table.
static EMMCCommand sdCommandTable[] =
  {
  { "GO_IDLE_STATE", 0x00000000|CMD_RSPNS_NO                            , RESP_NO , RCA_NO  ,0},
  { "ALL_SEND_CID" , 0x02000000|CMD_RSPNS_136                            , RESP_R2I, RCA_NO  ,0},
  { "SEND_REL_ADDR", 0x03000000|CMD_RSPNS_48                            , RESP_R6 , RCA_NO  ,0},
  { "SET_DSR"      , 0x04000000|CMD_RSPNS_NO                            , RESP_NO , RCA_NO  ,0},
  { "SWITCH_FUNC"  , 0x06000000|CMD_RSPNS_48                            , RESP_R1 , RCA_NO  ,0},
  { "CARD_SELECT"  , 0x07000000|CMD_RSPNS_48B                            , RESP_R1b, RCA_YES ,0},
  { "SEND_IF_COND" , 0x08000000|CMD_RSPNS_48                            , RESP_R7 , RCA_NO  ,100},
  { "SEND_CSD"    , 0x09000000|CMD_RSPNS_136                            , RESP_R2S, RCA_YES ,0},
  { "SEND_CID"    , 0x0A000000|CMD_RSPNS_136                            , RESP_R2I, RCA_YES ,0},
  { "VOLT_SWITCH"  , 0x0B000000|CMD_RSPNS_48                            , RESP_R1 , RCA_NO  ,0},
  { "STOP_TRANS"  , 0x0C000000|CMD_RSPNS_48B                            , RESP_R1b, RCA_NO  ,0},
  { "SEND_STATUS"  , 0x0D000000|CMD_RSPNS_48                            , RESP_R1 , RCA_YES ,0},
  { "GO_INACTIVE"  , 0x0F000000|CMD_RSPNS_NO                            , RESP_NO , RCA_YES ,0},
  { "SET_BLOCKLEN" , 0x10000000|CMD_RSPNS_48                            , RESP_R1 , RCA_NO  ,0},
  { "READ_SINGLE"  , 0x11000000|CMD_RSPNS_48 |CMD_IS_DATA  |TM_DAT_DIR_CH, RESP_R1 , RCA_NO  ,0},
  { "READ_MULTI"  , 0x12000000|CMD_RSPNS_48 |TM_MULTI_DATA|TM_DAT_DIR_CH, RESP_R1 , RCA_NO  ,0},
  { "SEND_TUNING"  , 0x13000000|CMD_RSPNS_48                            , RESP_R1 , RCA_NO  ,0},
  { "SPEED_CLASS"  , 0x14000000|CMD_RSPNS_48B                            , RESP_R1b, RCA_NO  ,0},
  { "SET_BLOCKCNT" , 0x17000000|CMD_RSPNS_48                            , RESP_R1 , RCA_NO  ,0},
  { "WRITE_SINGLE" , 0x18000000|CMD_RSPNS_48 |CMD_IS_DATA  |TM_DAT_DIR_HC, RESP_R1 , RCA_NO  ,0},
  { "WRITE_MULTI"  , 0x19000000|CMD_RSPNS_48 |TM_MULTI_DATA|TM_DAT_DIR_HC, RESP_R1 , RCA_NO  ,0},
  { "PROGRAM_CSD"  , 0x1B000000|CMD_RSPNS_48                            , RESP_R1 , RCA_NO  ,0},
  { "SET_WRITE_PR" , 0x1C000000|CMD_RSPNS_48B                            , RESP_R1b, RCA_NO  ,0},
  { "CLR_WRITE_PR" , 0x1D000000|CMD_RSPNS_48B                            , RESP_R1b, RCA_NO  ,0},
  { "SND_WRITE_PR" , 0x1E000000|CMD_RSPNS_48                            , RESP_R1 , RCA_NO  ,0},
  { "ERASE_WR_ST"  , 0x20000000|CMD_RSPNS_48                            , RESP_R1 , RCA_NO  ,0},
  { "ERASE_WR_END" , 0x21000000|CMD_RSPNS_48                            , RESP_R1 , RCA_NO  ,0},
  { "ERASE"        , 0x26000000|CMD_RSPNS_48B                            , RESP_R1b, RCA_NO  ,0},
  { "LOCK_UNLOCK"  , 0x2A000000|CMD_RSPNS_48                            , RESP_R1 , RCA_NO  ,0},
  { "APP_CMD"      , 0x37000000|CMD_RSPNS_NO                            , RESP_NO , RCA_NO  ,100},
  { "APP_CMD"      , 0x37000000|CMD_RSPNS_48                            , RESP_R1 , RCA_YES ,0},
  { "GEN_CMD"      , 0x38000000|CMD_RSPNS_48                            , RESP_R1 , RCA_NO  ,0},
 
  // APP commands must be prefixed by an APP_CMD.
  { "SET_BUS_WIDTH", 0x06000000|CMD_RSPNS_48                            , RESP_R1 , RCA_NO  ,0},
  { "SD_STATUS"    , 0x0D000000|CMD_RSPNS_48                            , RESP_R1 , RCA_YES ,0}, // RCA???
  { "SEND_NUM_WRBL", 0x16000000|CMD_RSPNS_48                            , RESP_R1 , RCA_NO  ,0},
  { "SEND_NUM_ERS" , 0x17000000|CMD_RSPNS_48                            , RESP_R1 , RCA_NO  ,0},
  { "SD_SENDOPCOND", 0x29000000|CMD_RSPNS_48                            , RESP_R3 , RCA_NO  ,1000},
  { "SET_CLR_DET"  , 0x2A000000|CMD_RSPNS_48                            , RESP_R1 , RCA_NO  ,0},
  { "SEND_SCR"    , 0x33000000|CMD_RSPNS_48|CMD_IS_DATA|TM_DAT_DIR_CH  , RESP_R1 , RCA_NO  ,0},
  };
 
static int sdSendCommand( int index )
  { // ... get cmd from table; check if APP_CMD is needed, sends that if so.
    // checks cmd->rca and if set uses card's rca as the arg value, then calls sdSendCommandP(cmd,arg); }
 
static int sdSendCommand( int index, int arg )
  { // ... get cmd from table; check if APP_CMD is needed, sends that if so.
    // calls sdSendCommandP(cmd,arg); }
 
static int sdSendCommandP( EMMCCommand* cmd, int arg )
  {
  // Clear interrupt flags.  This is done by setting the ones that are currently set.
  *EMMC_INTERRUPT = *EMMC_INTERRUPT;
 
  // Set the argument and the command code.
  // Some commands require a delay before reading the response.
  *EMMC_ARG1 = arg;
  *EMMC_CMDTM = cmd->code;
  if( cmd->delay ) waitMicro(cmd->delay);
 
  // Wait until command complete interrupt.
  if( (result = sdWaitForInterrupt(INT_CMD_DONE)) ) return result;
 
  // Get response from RESP0.
  int resp0 = *EMMC_RESP0;
 
  // Handle response types.
  switch( cmd->resp )
    {
    // No response.
    case RESP_NO:
 
  ...etc...
taken from http://www.raspberrypi.org/forums/viewtopic.php?f=72&t=59395, the guy who pasted this code explains that he could not enter SPI mode on his eMMC, but could send SD CMDs.
 
https://github.com/Nephiel/sdlocker-tiny

Maybe change the program inside and add the reset/clear commando.
Only don't know where connect the *CS signal.

To DAT3. Thx for that code, looking over it right now to see if we can use it with a normal sd card to test some stuffs.
EDIT: That code is an older version of SD lock 2, and only enables/disables write acces... so that is not what we want
 

Site & Scene News

Popular threads in this forum