Micron NAND (MT29F2G08ABAEAWP): Cannot successfully flash first block (address 0x0) - u-boot

We are trying to get our Micron NAND flash chip (MT29F2G08ABAEAWP) working. We are using u-boot as bootloader and our main processor is a TI DM8148. For evaluation we are using this evaluation module.
Now, the flash itself gets recognized by u-boot as 8-bit 2Gb NAND (which is correct). I'm able to flash 1st stage u-boot to 0x0 using the following uboot commands:
// select BCH8 as HW ECC
nandecc hw 2
// erase the first block
nand erase 0x0 0x20000
// write the content from RAM address 0x81000000 to the
// first flash block (0x0)
nand write.i 0x81000000 0x0 0x20000
However, when I try to read from that address using
nand read.i 0x81000000 0x0 0x20000
I get a lot of ECC: Uncorrectable errors. Choosing another ECC algorithm doesn't help. Booting from NAND (via ROM boot) doesn't work.
Any ideas?
Update:
Writing and reading every other block works like charm. Just the first one (Block 0) has those issues.
I know that issue is very specific. But I'm hoping that someone else might have had the same problems.
Thanks and greeting,
SamuelTee

Related

Encountering offset for logical block address in libusb using xusb.c example code?

I'm using the example file xusb.c in the libusb library to talk to a flash drive and have modified the command descriptor block of the read(10) in the test_mass_storage function by setting bytes 2-5 to set the logical block address parameter. However, I'm getting a weird result with the returned sector / block address, with:
cdb[2] = 0x00;
cdb[3] = 0x00;
cdb[4] = 0x00;
cdb[5] = 0x61;
returning sector / block address 1 of the disk, 0x62 is sector 2, etc. Nothing in the documentation I can find suggests there should by an offset of 0x60 or 96.. so is this device specific, an error in the code, or something in the specification?
read(10) structure
Now that I'm delving into the fat32 filesystem, the issue became apparent. I was opening the drive as a logical disk using HxD which I was using as a method of comparison to the xusb.c output. This started the sector count at the beginning of the volume rather than the start of the physical drive. Opening the drive under the Physical Disk tab resolved the issue.

Atmel SAM3X dual bank switching not working

I'm currently working with an Atmel SAM3X8 ARM microcontroller that features a dual banked 2 x 256KB flash memory. I'm trying to implement a firmware update feature, that puts the new firmware into the currently unused flash bank, and when done swaps the banks using the flash remapping to run the new firmware.
The datasheet states to do so I need to set the GPNVM2 bit, then the MCU will remap the memory, so Flash 1 is now at 0x80000 and Flash 0 at 0xC0000. This will also lead to the MCU executing code beginning from Flash 1.
To cite the datasheet:
The GPNVM2 is used only to swap the Flash 0 and Flash 1. If GPNVM2 is ENABLE, the Flash 1 is mapped at
address 0x0008_0000 (Flash 1 and Flash 0 are continuous). If GPNVM2 is DISABLE, the Flash 0 is mapped at
address 0x0008_0000 (Flash 0 and Flash 1 are continuous).
[...]
GPNVM2 enables to select if Flash 0 or Flash 1 is used for the boot.
Setting GPNVM bit 2 selects the boot from Flash 1, clearing it selects the boot from Flash 0.
But when I set GPNVM2, either via SAM-BA or my own firmware using flash_set_gpnvm(2) (ASF SAM Flash Service API), it will still boot from the program in Flash 0, and the new program will still reside at Flash 1's offset 0xC0000. The state of GPNVM2 has been verified by flash_is_gpnvm_set(2)
Flashing the firmware itself to Flash1 bank works flawlessly, that has been verified by dumping the whole flash memory with SAM-BA.
There is an errata from Atmel about an issue, that the flash remapping only works for portions smaller than 64KB. My code is less than that (40KB), so this shouldn't be an issue.
I've not found any other people having this issue, nor any example how to use it, so maybe somebody could tell me if I'm doing something wrong here, or what else to check.
I had the same issue (see here: Atmel SAM3X8E dual bank switching for booting different behaviour).
After some more research I found an Application Note (Link: http://ww1.microchip.com/downloads/en/AppNotes/Atmel-42141-SAM-AT02333-Safe-and-Secure-Bootloader-Implementation-for-SAM3-4_Application-Note.pdf) which explains the boot behaviour of the SAM3X in a more clear way. The problem is that the datasheet is a bit misleading (at least I was confused too). The SAM3X has no ability to remap the the Flash banks. The booting behaviour is a bit different (see the picture in the link, it's a snipped from the Application note, page 33/34):
Booting behaviour SAM3X
Picture 3-9 shows the SAM3X's behaviour at the boot-up. The GPNVM bits 1 and 2 just determine which memory section (ROM/Flash0/Flash1) is mirrored to the boot memory (located at 0x00000000). The mapping of the Flash banks is not changed. Therefore Flash0 still is mapped to 0x00080000 and Flash1 to 0x000C0000).
As the Application Note states some other Atmel microcontrollers are able to really remap the Flash banks (e.g. SAM3SD8 and SAM4SD32/16). These processors change the location of the Flash banks as you can see in picture 3-10.
To be able to update your firmware it is therefore necessary to implement some kind of bootloader. I implemented one by myself and was able to update my firmware even without using the GPNVM bits at all. I also opend a support ticket at Microchip to clarify the booting behaviour. When I receive an answer I hope to tell you more.
EDIT:
Here's the answer from the Microchip support:
Setting the GPNVM2 bit in SAM3X will merely make the CPU 'jump to' or start from flash bank 1 i.e. 0xC0000.
No actual swap of memory addresses will take place.
To use flash bank 1, you will need to change the linker file (flash.ld) to reflect the flash start address 0xC0000.
For flash bank 0 application, change:
rom (rx) : ORIGIN = 0x00080000, LENGTH = 0x00080000 /* Flash, 512K /
to:
rom (rx) : ORIGIN = 0x00080000, LENGTH = 0x00040000 / Flash, 256K */
For flash bank 1 application, change:
rom (rx) : ORIGIN = 0x00080000, LENGTH = 0x00080000 /* Flash, 512K /
to:
rom (rx) : ORIGIN = 0x000C0000, LENGTH = 0x00040000 / Flash, 256K */
If this is not done, the reset handler in the flash 1 application will point to an address in the flash 0 application.
So, although code will start execution in flash 1 (if GPNVM2 is set), it will jump back to the flash 0 application.
The errata stating the 64kb limitation can be ignored.
Therefore the Application Note is right and no actual change of the mmory mapping is performed.
Cheers
Lukas

Why uboot need to load at specific address in beagleoboard?

In beagle board bring up we use this specific address below to load up uImage and dtb?
loaduImage=fatload mmc 0:1 0x80007fc0 uImage
loadfdt=fatload mmc 0:1 ${dtaddr} omap3-beagle-xm.dtb
Why can't we use some other address? It is pointed out in the data sheet of beagle board xm that DRAM address in beagle board starts from 0x80000000 so why not choose any address?
Why can't we load up uImage at some address and after 128MB load up dtb as suggested in https://www.kernel.org/doc/Documentation/arm/Booting documentation.
Quoting from the link: A safe location is just above the 128MiB boundary from start of RAM.
Header is 0x40, so kernel ends up in 0x80008000, a 4k page boundry. 0x80008000 is just convention and if you want you can change the address but you need to modify kernel code accordingly.
http://processors.wiki.ti.com/index.php/HOWTO_Change_the_Linux_Kernel_Start_Address

ARM start address

Hi I’m newbie to ARM and am using a SAM3S4A ARM processor, with the IAR compiler.
Understanding that the flash code is from 0x00400000 – 0x0043FFFF and that the processor start at address zero (0x00000000), how does the PC jump to 0x00400000 as the VTOR register is zero at default.
From what I could understand from the document, ARM proc goes to 0x0 on reset. The 4K address space at 0x00000000 can be mapped to either ROM or FLASH using GPNVM register. So at reset ARM starts executing code either from ROM or FLASH. (ROM contains some proprietary bootloader and you can have your own OS/Bootloader at Flash). Once control reaches the code you have written to flash, you can setup a new Vector Table and update VTOR so that new exceptions are routed there.

booting from a disk/cd/usb

How can I boot my small console from a disk/cd/usb, with the following configuration:
The media that I want to use will be completely raw i.e no filesystem on it.
When I insert the media in my system or assume that its already inserted, I want to make it boot my own small OS.
The procedure that I want to use is that when my system starts, it boots from the disk/cd/usb, and starts my OS. For now imagine that the OS is going to be a hello world program. I actually want to see how the real world OS implement themselves.
A bootloader must be 512 bytes. No less no more.
And it must end with the standard PC boot signature: 0xAA55.
Also note a PC boots in 16 bits mode.
You need to load your kernel or secondstage bootloader from that code into memory, and then jump to that code (and maybe switch the CPU to 32 bits protected mode).
For instance (nasm):
BITS 16
; Your assembly code here (510 bytes max)...
jmp $
; Fills the remaining space with 0
times 510 - ( $ - $$ ) db 0
; Boot signature
dw 0xAA55
Thas the job of a boot loader. The bootloader should be present in the first 512 bytes of a HardDisk. This location is called MBR(Master boot record)
When bios loads it checks if the media contains the MBR. it verifies the MBR signature 0xAA55 which should be present as the last 2 bytes of MBR.
Then the Bios loads the BootLoader into RAM at address 0x7C00
Then the boot loader is the one who actually loads the kernal into memory, by reading the filesystem.
usually you cannot fit in all the code in 512 bytes, so there will be a secondory boot loader.
secondary bootloader will be loaded by your primary bootloader.
secondary boot loader loads IDT and GDT (Interupt vector table and Global descriptor table). Enables A20 gate to move into protected mode.
secondary boot loader loads the 32 bit kernel from disk into memory, then jumps to the kernel code
For more information you can download Linux kernel v0.01 (First version). Look how it is done. to my surprise the code to read the File system + the code to move into protected mode is fit into 512 bytes of code.

Resources