Welcome! Log In Create A New Profile

Advanced

reading GPIO registers in RAM

Posted by bobafetthotmail 
reading GPIO registers in RAM
July 05, 2015 12:11PM
Following a lead in a message left by the ALARM dev of the kirkwood kernel/u-boot, I would need some help to read GPIO registers in RAM so I can disable nsa325 watchdog with a mw from stock u-boot.

I've seen around people using mw in u-boot envs to power up USB or to turn on leds, so I am hoping there is some method.

I did try making mem dumps with LiME but i cannot get at these registers it seems.



Edited 1 time(s). Last edit at 07/05/2015 12:15PM by bobafetthotmail.
Re: reading GPIO registers in RAM
July 05, 2015 04:18PM
bobafett,

I'll work out the values and you can try it.

-bodhi
===========================
Forum Wiki
bodhi's corner (buy bodhi a beer)
Re: reading GPIO registers in RAM
July 05, 2015 06:32PM
@bobafett,

Since I don't have access to my NSA325v2, you'll need to try it!

Kirkwood GPIO base adress is 0xF1010100, so we dump this address to take a look

md 0xF1010100

Watchdog GPIO is 14, so basically we need to turn on bit 14 in this unsigned integer 32 by writing the bitmask M = (1 << 14) to this location

mw 0xF1010100  0  M

Now I'm not sure the value of M.

1. According to the code, M is unsigned integer 32 bit, with only the bit 14 on (1 << 14). Normally, in writing GPIO, we just write it to the location (we are not doing integer OR the bit to the existing memory value). I would trust the code.

2. If that does not work out, then perhaps integer OR to the memory location would do it. This is how we set up the GPIO initially when u-boot starts...

I guess, take your pick which one to try first.

Warning: please do it at your own risk! if the NSA325 went up in smoke, I'm not responsible :)) And I think you should remove all peripherals and HDDs before doing this.

-bodhi
===========================
Forum Wiki
bodhi's corner (buy bodhi a beer)



Edited 2 time(s). Last edit at 07/05/2015 06:34PM by bodhi.
Re: reading GPIO registers in RAM
July 07, 2015 01:36AM
Thanks for the help!
I was looking at the wrong address then... :/

Hmmm.... that's strange. After I switched back to stock u-boot I updated the firmware of the NSA325v2, now whatever I do the watchdog just gives the usual kick at startup (reboots after 2 seconds I powered it on).
Otherwise it appears to be disabled.

I tried with M = 0x4000, and also by copy-pasting the whole number I read from ram after uart-booting your u-boot.
No watchdog.
It seems Zyxel decided to kill their own watchdog in their own u-boot, because the same value I want to add is there already. (if I'm reading this correctly)
Of course no official version changes, so no indication that it was an official change.

Stock u-boot, ram dump with md 0xF1010100

f1010100: 00004000 00000000 00000000 00000000 .@..............
f1010110: 00004000 cfd35f35 00000000 00000000 .@..5_..........
f1010120: 00000000 00000000 00000000 00000000 ................
f1010130: 00000000 00000000 00000000 00000000 ................
f1010140: 00000000 00000000 00000000 00000040 ............@...
f1010150: 00000040 0002007d 00000000 00000000 @...}...........
f1010160: 00000000 00000000 00000000 00000000 ................
f1010170: 00000000 00000000 00000000 00000000 ................
f1010180: 00000000 00000000 00000000 00000000 ................
f1010190: 00000000 00000000 00000000 00000000 ................
f10101a0: 00000000 00000000 00000000 00000000 ................
f10101b0: 00000000 00000000 00000000 00000000 ................
f10101c0: 00000000 00000000 00000000 00000000 ................
f10101d0: 00000000 00000000 00000000 00000000 ................
f10101e0: 00000000 00000000 00000000 00000000 ................
f10101f0: 00000000 00000000 00000000 00000000 ................



your u-boot, 2013 test version i uart-booted, same ram address dump.

f1010100: 10204000 cfdf0fff 00000000 00000000 .@ .............
f1010110: dff34080 dff35fb5 00000000 00000000 .@..._..........
f1010120: 00000000 00000000 00000000 00000000 ................
f1010130: 00000000 00000000 00000000 00000000 ................
f1010140: 0000c000 ffff387f 00000000 00000000 .....8..........
f1010150: 0002c03d 0002c03d 00000000 00000000 =...=...........
f1010160: 00000000 00000000 00000000 00000000 ................
f1010170: 00000000 00000000 00000000 00000000 ................
f1010180: 00000000 00000000 00000000 00000000 ................
f1010190: 00000000 00000000 00000000 00000000 ................
f10101a0: 00000000 00000000 00000000 00000000 ................
f10101b0: 00000000 00000000 00000000 00000000 ................
f10101c0: 00000000 00000000 00000000 00000000 ................
f10101d0: 00000000 00000000 00000000 00000000 ................
f10101e0: 00000000 00000000 00000000 00000000 ................
f10101f0: 00000000 00000000 00000000 00000000 ................


I installed the rootfs and modified u-boot envs, booted fine in kernel 3.17 with dtb (dtb in zimage, not tried true dtb boot)

I left the box unpowered and disconnected the whole night, powered up without any console or anything attached and it booted fine to Debian, no watchdog.
It's running for a hour or so and no watchdog.

But I did nothing. I just updated the firmware after I reflashed the stock u-boot I backed up before I installed yours.

That's cool, but I'm a bit puzzled.

Maybe the u-boot I installed did linger even after I reverted back to stock? I doubt it...

If someone could check his own to see if it's not just mine that does this.



Edited 1 time(s). Last edit at 07/07/2015 01:47AM by bobafetthotmail.
Re: reading GPIO registers in RAM
July 07, 2015 10:07AM
Please do this test sequence with stock u-boot.

Objective:

a.To test if the GPIO write is working.
b. Whether the GPIO 14 is a toggle.
c. Stock u-boot does not clear the watchdog.

Step 1. Boot with stock u-boot and interrupt it. Wait at serial console prompt for more than 30 seconds. If the watchdog is inactive, then it will not restart. Dump memory. Write to GPIO 14. Wait again to see if it was activated by this poke. If it was, interrupt u-boot and power down.

Step 2. Power up and then interrupt u-boot. Wait at serial console prompt for more than 30 seconds. If the watchdog is active, it will restart the box. If it does restart, then interrupt it again and write to GPIO 14 and wait again to see if it was deactivated.

Step 3. Repeat step 1. If the watchdog was activated by the poke, let it restart and interupt u-boot, dump memory, and wait again to see if the watchdog will kick in. If it does, then dump memory and let it restart. Repeat this a couple times.

Please post your serial console log for the test.

-bodhi
===========================
Forum Wiki
bodhi's corner (buy bodhi a beer)



Edited 1 time(s). Last edit at 07/07/2015 10:12AM by bodhi.
Re: reading GPIO registers in RAM
July 08, 2015 05:56PM
As said above, I can't activate the watchdog by any means. The only sign that it is still alive is that if I pull the power plug and then power up again the NSA325v2 starts up then reboots after a couple seconds.

After it has booted once there is no way to get it to show up again.

Here serial console log with some comments.


__  __                      _ _
        |  \/  | __ _ _ ____   _____| | |
        | |\/| |/ _` | '__\ \ / / _ \ | |
        | |  | | (_| | |   \ V /  __/ | |
        |_|  |_|\__,_|_|    \_/ \___|_|_|
 _   _     ____              _
| | | |   | __ )  ___   ___ | |_ 
| | | |___|  _ \ / _ \ / _ \| __| 
| |_| |___| |_) | (_) | (_) | |_ 
 \___/    |____/ \___/ \___/ \__| 
 ** MARVELL BOARD: DB-88F6282A-BP LE 

U-Boot 1.1.4 (Jul 18 2013 - 10:47:29) Marvell version: 3.5.9

U-Boot code: 00600000 -> 0067FFF0  BSS: -> 006CFB00

Soc: 88F6282 A1CPU running @ 1600Mhz L2 running @ 533Mhz
SysClock = 533Mhz , TClock = 200Mhz 

DRAM (DDR3) CAS Latency = 7 tRP = 8 tRAS = 24 tRCD=8
DRAM CS[0] base 0x00000000   size 512MB 
DRAM Total size 512MB  16bit width
Addresses 10M - 0M are saved for the U-Boot usage.
Mem malloc Initialization (10M - 7M): Done
NAND:128 MB
Flash:  0 kB

CPU : Marvell Feroceon (Rev 1)
Kernel address is 0xc80000.

Streaming disabled 
Write allocate disabled


USB 0: host mode
	[BlueDBG] reseting SoC Pex[0]  0 ...
PEX 0: PCI Express Root Complex Interface
PEX interface detected Link X1
	[BlueDBG] reseting SoC Pex[1]  0 ...
	[BlueDBG] reseting SoC Pex[1]  1 ...
	[BlueDBG] reseting SoC Pex[1]  2 ...
	[BlueDBG] reseting SoC Pex[1]  3 ...
	[BlueDBG] reseting SoC Pex[1]  4 ...
	[BlueDBG] reseting SoC Pex[1]  5 ...
	[BlueDBG] reseting SoC Pex[1]  6 ...
	[BlueDBG] reseting SoC Pex[1]  7 ...
	[BlueDBG] reseting SoC Pex[1]  8 ...
	[BlueDBG] reseting SoC Pex[1]  9 ...
	[BlueDBG] reseting SoC Pex[1]  10 ...
PEX 1: interface detected no Link.
Net:   egiga0 [PRIME]
Hit any key to stop autoboot:  2 1 0
Marvell>> a

######waited 30 seconds, no reboot

Marvell>> md 0xF1010100 

f1010100: 00004000 00000000 00000000 00000000    .@..............
f1010110: 00004000 cfd35f35 00000000 00000000    .@..5_..........
f1010120: 00000000 00000000 00000000 00000000    ................
f1010130: 00000000 00000000 00000000 00000000    ................
f1010140: 00000000 00000000 00000000 00000040    ............@...
f1010150: 00000040 0002007d 00000000 00000000    @...}...........
f1010160: 00000000 00000000 00000000 00000000    ................
f1010170: 00000000 00000000 00000000 00000000    ................
f1010180: 00000000 00000000 00000000 00000000    ................
f1010190: 00000000 00000000 00000000 00000000    ................
f10101a0: 00000000 00000000 00000000 00000000    ................
f10101b0: 00000000 00000000 00000000 00000000    ................
f10101c0: 00000000 00000000 00000000 00000000    ................
f10101d0: 00000000 00000000 00000000 00000000    ................
f10101e0: 00000000 00000000 00000000 00000000    ................
f10101f0: 00000000 00000000 00000000 00000000    ................
Marvell>> mw 0xf1010100  0x4000

####Writing "mw  0xF1010100  0  0x4000" was not working

#### waited 30 seconds again. No signs of anything.

Marvell>> reset

        __  __                      _ _
        |  \/  | __ _ _ ____   _____| | |
        | |\/| |/ _` | '__\ \ / / _ \ | |
        | |  | | (_| | |   \ V /  __/ | |
        |_|  |_|\__,_|_|    \_/ \___|_|_|
 _   _     ____              _
| | | |   | __ )  ___   ___ | |_ 
| | | |___|  _ \ / _ \ / _ \| __| 
| |_| |___| |_) | (_) | (_) | |_ 
 \___/    |____/ \___/ \___/ \__| 
 ** MARVELL BOARD: DB-88F6282A-BP LE 

U-Boot 1.1.4 (Jul 18 2013 - 10:47:29) Marvell version: 3.5.9

U-Boot code: 00600000 -> 0067FFF0  BSS: -> 006CFB00

Soc: 88F6282 A1CPU running @ 1600Mhz L2 running @ 800Mhz
SysClock = 533Mhz , TClock = 200Mhz 

DRAM (DDR3) CAS Latency = 7 tRP = 8 tRAS = 24 tRCD=8
DRAM CS[0] base 0x00000000   size 512MB 
DRAM Total size 512MB  16bit width
Addresses 10M - 0M are saved for the U-Boot usage.
Mem malloc Initialization (10M - 7M): Done
NAND:128 MB
Flash:  0 kB

CPU : Marvell Feroceon (Rev 1)
Kernel address is 0xc80000.

Streaming disabled 
Write allocate disabled


USB 0: host mode
	[BlueDBG] reseting SoC Pex[0]  0 ...
PEX 0: PCI Express Root Complex Interface
PEX interface detected Link X1
	[BlueDBG] reseting SoC Pex[1]  0 ...
	[BlueDBG] reseting SoC Pex[1]  1 ...
	[BlueDBG] reseting SoC Pex[1]  2 ...
	[BlueDBG] reseting SoC Pex[1]  3 ...
	[BlueDBG] reseting SoC Pex[1]  4 ...
	[BlueDBG] reseting SoC Pex[1]  5 ...
	[BlueDBG] reseting SoC Pex[1]  6 ...
	[BlueDBG] reseting SoC Pex[1]  7 ...
	[BlueDBG] reseting SoC Pex[1]  8 ...
	[BlueDBG] reseting SoC Pex[1]  9 ...
	[BlueDBG] reseting SoC Pex[1]  10 ...
PEX 1: interface detected no Link.
Net:   egiga0 [PRIME]
Hit any key to stop autoboot:  2 1 0
Marvell>> md f1010100

f1010100: 00004000 00000000 00000000 00000000    .@..............
f1010110: 00004000 cfd35f35 00000000 00000000    .@..5_..........
f1010120: 00000000 00000000 00000000 00000000    ................
f1010130: 00000000 00000000 00000000 00000000    ................
f1010140: 00000000 00000000 00000000 00000040    ............@...
f1010150: 00000040 0002007d 00000000 00000000    @...}...........
f1010160: 00000000 00000000 00000000 00000000    ................
f1010170: 00000000 00000000 00000000 00000000    ................
f1010180: 00000000 00000000 00000000 00000000    ................
f1010190: 00000000 00000000 00000000 00000000    ................
f10101a0: 00000000 00000000 00000000 00000000    ................
f10101b0: 00000000 00000000 00000000 00000000    ................
f10101c0: 00000000 00000000 00000000 00000000    ................
f10101d0: 00000000 00000000 00000000 00000000    ................
f10101e0: 00000000 00000000 00000000 00000000    ................
f10101f0: 00000000 00000000 00000000 00000000    ................

###########let's try zeroing the GPIO

Marvell>> mw f1010100 0x00

#######waited 30 seconds, nothing happens.

Marvell>> md f1010100

f1010100: 00000000 00000000 00000000 00000000    ................
f1010110: 00000000 cfd35f35 00000000 00000000    ....5_..........
f1010120: 00000000 00000000 00000000 00000000    ................
f1010130: 00000000 00000000 00000000 00000000    ................
f1010140: 00000000 00000000 00000000 00000040    ............@...
f1010150: 00000040 0002007d 00000000 00000000    @...}...........
f1010160: 00000000 00000000 00000000 00000000    ................
f1010170: 00000000 00000000 00000000 00000000    ................
f1010180: 00000000 00000000 00000000 00000000    ................
f1010190: 00000000 00000000 00000000 00000000    ................
f10101a0: 00000000 00000000 00000000 00000000    ................
f10101b0: 00000000 00000000 00000000 00000000    ................
f10101c0: 00000000 00000000 00000000 00000000    ................
f10101d0: 00000000 00000000 00000000 00000000    ................
f10101e0: 00000000 00000000 00000000 00000000    ................
f10101f0: 00000000 00000000 00000000 00000000    ................

########yep, the change went through.

######## sending the GPIO again

Marvell>> mw f1010100 0x4000

######## waiting 30 seconds, nothing happens.

Marvell>> md f1010100

f1010100: 00004000 00000000 00000000 00000000    .@..............
f1010110: 00004000 cfd35f35 00000000 00000000    .@..5_..........
f1010120: 00000000 00000000 00000000 00000000    ................
f1010130: 00000000 00000000 00000000 00000000    ................
f1010140: 00000000 00000000 00000000 00000040    ............@...
f1010150: 00000040 0002007d 00000000 00000000    @...}...........
f1010160: 00000000 00000000 00000000 00000000    ................
f1010170: 00000000 00000000 00000000 00000000    ................
f1010180: 00000000 00000000 00000000 00000000    ................
f1010190: 00000000 00000000 00000000 00000000    ................
f10101a0: 00000000 00000000 00000000 00000000    ................
f10101b0: 00000000 00000000 00000000 00000000    ................
f10101c0: 00000000 00000000 00000000 00000000    ................
f10101d0: 00000000 00000000 00000000 00000000    ................
f10101e0: 00000000 00000000 00000000 00000000    ................
f10101f0: 00000000 00000000 00000000 00000000    ................

###########Doing it again and rebooting

Marvell>> mw f1010100 0x00

Marvell>> md f1010100

f1010100: 00000000 00000000 00000000 00000000    ................
f1010110: 00000000 cfd35f35 00000000 00000000    ....5_..........
f1010120: 00000000 00000000 00000000 00000000    ................
f1010130: 00000000 00000000 00000000 00000000    ................
f1010140: 00000000 00000000 00000000 00000040    ............@...
f1010150: 00000040 0002007d 00000000 00000000    @...}...........
f1010160: 00000000 00000000 00000000 00000000    ................
f1010170: 00000000 00000000 00000000 00000000    ................
f1010180: 00000000 00000000 00000000 00000000    ................
f1010190: 00000000 00000000 00000000 00000000    ................
f10101a0: 00000000 00000000 00000000 00000000    ................
f10101b0: 00000000 00000000 00000000 00000000    ................
f10101c0: 00000000 00000000 00000000 00000000    ................
f10101d0: 00000000 00000000 00000000 00000000    ................
f10101e0: 00000000 00000000 00000000 00000000    ................
f10101f0: 00000000 00000000 00000000 00000000    ................
Marvell>> reset

ΓΌ
         __  __                      _ _
        |  \/  | __ _ _ ____   _____| | |
        | |\/| |/ _` | '__\ \ / / _ \ | |
        | |  | | (_| | |   \ V /  __/ | |
        |_|  |_|\__,_|_|    \_/ \___|_|_|
 _   _     ____              _
| | | |   | __ )  ___   ___ | |_ 
| | | |___|  _ \ / _ \ / _ \| __| 
| |_| |___| |_) | (_) | (_) | |_ 
 \___/    |____/ \___/ \___/ \__| 
 ** MARVELL BOARD: DB-88F6282A-BP LE 

U-Boot 1.1.4 (Jul 18 2013 - 10:47:29) Marvell version: 3.5.9

U-Boot code: 00600000 -> 0067FFF0  BSS: -> 006CFB00

Soc: 88F6282 A1CPU running @ 1600Mhz L2 running @ 800Mhz
SysClock = 533Mhz , TClock = 200Mhz 

DRAM (DDR3) CAS Latency = 7 tRP = 8 tRAS = 24 tRCD=8
DRAM CS[0] base 0x00000000   size 512MB 
DRAM Total size 512MB  16bit width
Addresses 10M - 0M are saved for the U-Boot usage.
Mem malloc Initialization (10M - 7M): Done
NAND:128 MB
Flash:  0 kB

CPU : Marvell Feroceon (Rev 1)
Kernel address is 0xc80000.

Streaming disabled 
Write allocate disabled


USB 0: host mode
	[BlueDBG] reseting SoC Pex[0]  0 ...
PEX 0: PCI Express Root Complex Interface
PEX interface detected Link X1
	[BlueDBG] reseting SoC Pex[1]  0 ...
	[BlueDBG] reseting SoC Pex[1]  1 ...
	[BlueDBG] reseting SoC Pex[1]  2 ...
	[BlueDBG] reseting SoC Pex[1]  3 ...
	[BlueDBG] reseting SoC Pex[1]  4 ...
	[BlueDBG] reseting SoC Pex[1]  5 ...
	[BlueDBG] reseting SoC Pex[1]  6 ...
	[BlueDBG] reseting SoC Pex[1]  7 ...
	[BlueDBG] reseting SoC Pex[1]  8 ...
	[BlueDBG] reseting SoC Pex[1]  9 ...
	[BlueDBG] reseting SoC Pex[1]  10 ...
PEX 1: interface detected no Link.
Net:   egiga0 [PRIME]
Hit any key to stop autoboot:  2 1 0
Marvell>> a

######## waiting for 30 seconds, nothing happens.

Marvell>> md f1010100

f1010100: 00004000 00000000 00000000 00000000    .@..............
f1010110: 00004000 cfd35f35 00000000 00000000    .@..5_..........
f1010120: 00000000 00000000 00000000 00000000    ................
f1010130: 00000000 00000000 00000000 00000000    ................
f1010140: 00000000 00000000 00000000 00000040    ............@...
f1010150: 00000040 0002007d 00000000 00000000    @...}...........
f1010160: 00000000 00000000 00000000 00000000    ................
f1010170: 00000000 00000000 00000000 00000000    ................
f1010180: 00000000 00000000 00000000 00000000    ................
f1010190: 00000000 00000000 00000000 00000000    ................
f10101a0: 00000000 00000000 00000000 00000000    ................
f10101b0: 00000000 00000000 00000000 00000000    ................
f10101c0: 00000000 00000000 00000000 00000000    ................
f10101d0: 00000000 00000000 00000000 00000000    ................
f10101e0: 00000000 00000000 00000000 00000000    ................
f10101f0: 00000000 00000000 00000000 00000000    ................
Marvell>>

######### yep, the GPIO is set again by the u-boot.

I was on your u-boot for a while, but for development purposes I switched back to a mtd0 backup I did, it is a 1MB image I restored following the same instructions you posted to flash your u-boot.
There are no bad blocks in my u-boot.

I updated the Nas's firmware to firmware v4.71.
Re: reading GPIO registers in RAM
July 08, 2015 06:35PM
@bobafetthotmail,

Thanks for running the test!

It is kind of good news/bad news! isn't it :) now we know the watchdog is somehow not activated or killed by this stock u-boot version. But whatever the modification was done with no indication that Zyxel did something in the new version of stock FW OS (I think it is likely).

I guess for your target audience, they could make sure that the FW was updated to the same version as yours, before installing your OMV rootfs.

-bodhi
===========================
Forum Wiki
bodhi's corner (buy bodhi a beer)
Re: reading GPIO registers in RAM
July 08, 2015 07:52PM
meh, it would have been cooler if they left it active so we could have taken some credit for disabling it. :)

Anyway, before putting my face on this I'm probably asking some brave volunteers to do the same tests I did.
I have access to a relatively large pool of NSA325v1/v2 users at various skill levels in one of my favourite forums, I should be able to get at least one or two volunteers for this (because quite a few are annoyed by Zyxel firmware).

I really hope this is an official change and not just a screwed-up u-boot in my box. :S

I do remember some months ago when I first got my box, the dumb watchdog killing a few times even stock firmware so I cannot exclude that a dev got pissed off and silently modded their u-boot without telling anyone.

Will report here results.
Re: reading GPIO registers in RAM
July 10, 2015 07:05PM
> I really hope this is an official change and not
> just a screwed-up u-boot in my box. :S

If that were true, it''ll be forgiven once you got it consistently working :))

-bodhi
===========================
Forum Wiki
bodhi's corner (buy bodhi a beer)
Re: reading GPIO registers in RAM
July 22, 2015 10:27PM
bobafetthotmail & others,

I'm looking to get a JTAG header to install on NSA325v2. Would this fit?

http://www.ebay.com/itm/20-Pcs-2-54mm-Pitch-10x2-20Pin-ISP-Download-Header-JTAG-I-O-Socket-DIY-DC3-20P-/271675139331?pt=LH_DefaultDomain_0&hash=item3f4119a503

This product says it has 2.54 mm pitch. The unpopulated 20 pins on the NSA325 board seems to be a standard JTAG connector.

-bodhi
===========================
Forum Wiki
bodhi's corner (buy bodhi a beer)
Re: reading GPIO registers in RAM
July 23, 2015 08:10AM
I think yes.
the space between the holes is indeed a bit more than 2 mm. (just checked)

Might be a PITA to solder it without a hot-air station though.

Why do you want to connect a Jtag? Better understanding of the SoC/box?

Btw, a german guy seems to have installed (your) Debian + OMV successfully with my script, no watchdog in his box either.

I hoped for a bit more volunteers for testing than this :/ .
Re: reading GPIO registers in RAM
July 23, 2015 05:12PM
bobafetthotmail,

Thanks for confirming!

> Why do you want to connect a Jtag? Better
> understanding of the SoC/box?

Yes. I'm hoping to learn something new about this SoC using this interface. Besides, I have a friend offering to do the soldering for me at his work place after hours, so I though why not :)

> Btw, a german guy seems to have installed (your)
> Debian + OMV successfully with my script, no
> watchdog in his box either.

Cool!

-bodhi
===========================
Forum Wiki
bodhi's corner (buy bodhi a beer)
Author:

Your Email:


Subject:


Spam prevention:
Please, enter the code that you see below in the input field. This is for blocking bots that try to post this form automatically. If the code is hard to read, then just try to guess it right. If you enter the wrong code, a new image is created and you get another chance to enter it right.
Message: