u-boot-2009.08 transplantation on mini2440 (Part 2) --- Adding NOR flash function

Publisher:konglingdeyuanLatest update time:2016-12-04 Source: eefocusKeywords:u-boot  mini2440  nor Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Migration environment

1. Host environment: CentOS 5.5 under VMare, 1G memory.

2. Integrated development environment: Eclipse IDE

3. Compilation environment: arm-linux-gcc v4.4.3, arm-none-eabi-gcc v4.5.1.

4. Development board: mini2440, 2M nor flash, 128M nand flash.

5.u-boot version: u-boot-2009.08

6. References:

http://blogold.chinaunix.net/u3/101649/showart.php?id=2105215

http://blog.chinaunix.net/space.php?uid=23787856&do=blog&id=115382

http://blogimg.chinaunix.net/blog/upfile2/100811115954.pdf

Usually, in embedded bootloader, there are two ways to boot the kernel: boot from Nor Flash and boot from Nand Flash. U-boot boots from Nor Flash by default. From the test results in the previous section, we can find several problems: First, the Nor Flash of my development board is 2M, but it is 512kB here; second, the warning message Warning - bad CRC, using default environment appears. Isn't u-boot booted from Nor Flash by default? Why are there these error messages? This is because we have not added support for our own Nor Flash. U-boot defaults to other types of Nor Flash, and our Nor Flash model is SST39VF1601. In addition, how can I change the SMDK2410 in front of the command line prompt to my own definition? Let's solve these problems one by one.

2.1, modify the u-boot source code to fully support Nor Flash.

【1】Add support for 2M Nor Flash (model SST39VF1601) on our mini2440 development board

Although the S3C2440 and S3C2410 have the same Nor Flash connection, the SBC2410 uses AMD's Nor Flash chip, while the mini2440 uses SST's Nor Flash. The block size, timing, and instruction code used by these two chips when writing are different, so they must be modified according to the chip's data sheet. For the main differences, please see the comparison of the data sheets:
SST39VF1601:

u-boot-2009.08 transplantation on mini2440 (Part 2) - singleboy - singleboy's blog

 Am29LV160:

u-boot-2009.08 transplantation on mini2440 (Part 2) - singleboy - singleboy's blog

 

In u-boot, the operations on Nor Flash are initialization, erasing and writing, so we mainly modify the three functions flash_init, flash_erase and write_hword that are closely related to the hardware.

Use gedit to open board/samsung/mini2440/flash.c, locate around line 31, and modify it as follows:

#define FLASH_BANK_SIZE PHYS_FLASH_SIZE
//#define MAIN_SECT_SIZE 0x10000 /* 64 KB */
#define MAIN_SECT_SIZE 0x1000 //Defined as 4k, just the size of a sector

flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];

... ...

Nor Flash Hardware Connection

u-boot-2009.08 transplantation on mini2440 (Part 2) - singleboy - singleboy's blog

 

From the schematic diagram, we can see that NorFlash is usually placed in Bank0. So CONFIG_SYS_BASE=0, but after turning on the mmu, baseaddr=the new address mapped to address 0. The reason why 0x555<<1 is that LADDR1 is connected to A0. That is, 0x555 means the 0x555th word (16bit) in the chip.

#define CMD_UNLOCK_BYPASS 0x00000020

#if defined(CONFIG_SST_VF1601)
#define MEM_FLASH_ADDR1  (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000005555 << 1)))
#define MEM_FLASH_ADDR2  (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AAA << 1)))
#else
#define MEM_FLASH_ADDR1  (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 << 1)))
#define MEM_FLASH_ADDR2  (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA << 1)))
#endif

#define BIT_ERASE_DONE  0x00000080

The modified or added code in the flash_init function is as follows:

ulong flash_init (void)
{
 int i, j;
 ulong size = 0;

for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
  ulong flashbase = 0;

... ...

#elif defined(CONFIG_AMD_LV800)
            (AMD_MANUFACT & FLASH_VENDMASK) |
            (AMD_ID_LV800B & FLASH_TYPEMASK);
#elif defined(CONFIG_SST_39VF1601)   
            (SST_MANUFACT & FLASH_VENDMASK) |
            (SST_ID_xF1601 & FLASH_TYPEMASK);
#else
#error "Unknown flash configured"
#endif

... ...

for (j = 0; j < flash_info[i].sector_count; j++) {
#ifndef CONFIG_SST_VF1601
   if (j <= 3) {
    /* 1st one is 16 KB */

... ...
#else
    flash_info[i].start[j] =
     flashbase + (j) * MAIN_SECT_SIZE;
#endif


 }
  size += flash_info[i].size;
 }

  ... ...

    return size;

}

The modified or added code in the flash_print_info function is as follows:

void flash_print_info (flash_info_t * info)
{
     int i;

    switch (info->flash_id & FLASH_VENDMASK) {
              case (AMD_MANUFACT & FLASH_VENDMASK):
              printf ("AMD: ");
              break;
              case (SST_MANUFACT & FLASH_VENDMASK):
              printf ("SST: ");
              break;

              default:
              printf ("Unknown Vendor ");
              break;
    }

    switch (info->flash_id & FLASH_TYPEMASK) {
               case (AMD_ID_LV400B & FLASH_TYPEMASK):
               printf ("1x Amd29LV400BB (4Mbit)\n");
               break;
               case (AMD_ID_LV800B & FLASH_TYPEMASK):
               printf ("1x Amd29LV800BB (8Mbit)\n");
               break;
               case (SST_ID_xF1601 & FLASH_TYPEMASK):
               printf ("1x SST39VF1610 (16Mbit)\n");
               break;


               default:
               printf ("Unknown Chip Type\n");
               goto Done;
               break;


    }

   ... ...

    Done:;
}

The modified or added code in the flash_erase function is as follows:

int flash_erase (flash_info_t * info, int s_first, int s_last)
{
    ushort result;
    int iflag, cflag, prot, sect;
    int rc = ERR_OK;
    int chip;

     .... ....

    if ((s_first < 0) || (s_first > s_last)) {
    return ERR_INVAL;
    }

 if ((s_first < 0) || (s_first > s_last)) {
  return ERR_INVAL;
 }

#ifdef CONFIG_SST_VF1601
 if ((info->flash_id & FLASH_VENDMASK) !=
     (SST_MANUFACT & FLASH_VENDMASK)) {
  return ERR_UNKNOWN_FLASH_VENDOR;
 }
#else

 if ((info->flash_id & FLASH_VENDMASK) !=
     (AMD_MANUFACT & FLASH_VENDMASK)) {
  return ERR_UNKNOWN_FLASH_VENDOR;
 }
#endif
 prot = 0;

... ...

   if (info->protect[sect] == 0) { /* not protected */


   vu_short *addr = (vu_short *) (info->start[sect]);

   MEM_FLASH_ADDR1 = CMD_UNLOCK1;
   MEM_FLASH_ADDR2 = CMD_UNLOCK2;
   MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;

   MEM_FLASH_ADDR1 = CMD_UNLOCK1;
   MEM_FLASH_ADDR2 = CMD_UNLOCK2;
   *addr = CMD_ERASE_CONFIRM;

   /* wait until flash is ready */

#if 0

  chip = 0;

   do {

... ...

    printf ("ok.\n");
   } else { /* it was protected */

        printf ("protected!\n");
   }
}
#endif
   while(1){
          unsigned short i;
          i = *((volatile unsigned short *)addr) & 0x40;
          if(i != (*((volatile unsigned short *)addr) & 0x40))
               continue;
          if((*((volatile unsigned short *)addr)) & 0x80)
               break;
    }
    printf ("ok.\n");
   } else { /* it was protected */
   printf ("protected!\n");
  }
}

The modified or added code in the write_hword function is as follows:

tatic int write_hword (flash_info_t * info, ulong dest, ushort data)
{
    vu_short *addr = (vu_short *) dest;
    ushort result;
    int rc = ERR_OK;
    int cflag, iflag;
    int chip;

    ... ...

    MEM_FLASH_ADDR1 = CMD_UNLOCK1;
    MEM_FLASH_ADDR2 = CMD_UNLOCK2;
    //MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;
    MEM_FLASH_ADDR1 = CMD_PROGRAM; 
    //*addr = CMD_PROGRAM;
    *addr = data;

    /* arm simple, non interrupt dependent timer */
    reset_timer_masked ();

    /* wait until flash is ready */

#if 0 

 chip = 0;
   do {
   result = *addr;

... ...

    } while (!chip);

    *addr = CMD_READ_ARRAY;

    if (chip == ERR || *addr != data)
        rc = ERR_PROG_ERROR;
#endif

  while(1){
         unsigned short i = *(volatile unsigned short *)addr & 0x40;
         if(i != (*(volatile unsigned short *)addr & 0x40))   //D6 == D6
             continue;
         if((*(volatile unsigned short *)addr & 0x80) == (data & 0x80)){
             rc = ERR_OK;
         break;     //D7 == D7
          }
        }
   if (iflag)
     enable_interrupts ();

   if (cflag)
     icache_enable ();

    return rc;
}

After modification, save.

【2】Modify the lowlevel_init.S file

In order to match the memory configuration of mini2440 (Nor Flash and SDRAM connected on the bus), you need to modify the lowlevel_init.S file. This is related to the number of bits of the connected Nor Flash. As for the parameters of SDRAM, you can check it from the chip manual. It is said that someone has upgraded its 64MB memory to 128MB, and its parameters are modified here. If you need, you can see MINI2440: Auto probe for SDRAM size. The following 64MB memory parameter modification:

Open /board/samsung/mini2440/lowlevel_init.S, locate line 123, and modify it as follows:

/* REFRESH parameter */
#define REFEN   0x1 /* Refresh enable */
#define TREFMD   0x0 /* CBR(CAS before RAS)/Auto refresh */
//#define Trp   0x0 /* 2clk */
#define Trc    0x3 /* 7clk */
#define Tchr   0x2 /* 3clk */
#if defined(CONFIG_S3C2440)
#define Trp    0x2 /* 4clk */
#define REFCNT   1012
#else
#define Trp    0x0 /* 2clk */
#define REFCNT   1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
#endif
/**************************************/

There is a small bug in this lowlevel_init.S, which makes it impossible to use OpenJTAG to download to memory and run directly. The fix is ​​as follows:

lowlevel_init:
 /* memory control configuration */
 /* make r0 relative the current location so that it */
 /* reads SMRDATA out of FLASH rather than memory ! */
 ldr     r0, =SMRDATA
 //ldr r1, _TEXT_BASE
 ldr r1, =lowlevel_init
 sub r0, r0, r1
 adr r3, lowlevel_init /* r3 <- current position of code */
 add r0, r0, r3
 ldr r1, =BWSCON /* Bus Width Status Controller */
 add     r2, r0, #13*4

After modification, save.

【3】Modify the command line prompt in the development board terminal

Use gedit to open the include/configs/mini2440.h header file and locate line 116. The "SMDK2410 # " is the prompt displayed by the development board in the terminal. Now change it to "[u-boot@MINI2440]# ", as shown below

/*
 * Miscellaneous configurable options
 */
#define CONFIG_SYS_LONGHELP    /* undef to save memory  */
#define CONFIG_SYS_PROMPT  "[u-boot@MINI2440]# " /* Monitor Command Prompt */

【4】Modify some definitions of Nor Flash parameters

Then locate around line 157, comment out the following two types of Nor Flash settings, because they are not the models we use, and then add new definitions as shown below

/*-----------------------------------------------------------------------
 * FLASH and environment organization
 */

#if 0 //Comment out the following two types of Nor Flash settings, because they are not the models we use
#define CONFIG_AMD_LV400 1 /* uncomment this if you have a LV400 flash */
#define CONFIG_AMD_LV800 1 /* uncomment this if you have a LV800 flash */
#endif
#define CONFIG_SST_39VF1601 1 //Add mini2440 development board Nor Flash settings


 ... ...

#ifdef CONFIG_AMD_LV400
#define PHYS_FLASH_SIZE  0x00080000 /* 512KB */
#define CONFIG_SYS_MAX_FLASH_SECT (11) /* max number of sectors on one chip */
#define CONFIG_ENV_ADDR  (CONFIG_SYS_FLASH_BASE + 0x070000) /* addr of environment */
#endif
#ifdef CONFIG_SST_VF1601
#define PHYS_FLASH_SIZE  0x00200000 /* 2MB */
#define CONFIG_SYS_MAX_FLASH_SECT (32) /* max number of sectors on one chip */
#define CONFIG_ENV_ADDR  (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET) /* addr of environment */
#endif

 The macro CFG_ENV_ADDR defines the address where the uboot variables are stored, which is converted to 1MB-64KB=960KB. The actual size of the compiled uboot is only about 120KB. It can be concluded that even if the newly compiled uboot is burned into Nor flash, it will not affect the previously set uboot variables.

After modification, save.

【5】u-boot compilation time

The compilation time of u-boot is around line 384 of /Makefile:

$(VERSION_FILE):
  @( printf '#define U_BOOT_VERSION "U-Boot %s%s"\n' "$(U_BOOT_VERSION)" \
   '$(shell $(TOPDIR)/tools/setlocalversion $(TOPDIR))' ) > $@.tmp
  @cmp -s $@ $@.tmp && rm -f $@.tmp || mv -f $@.tmp $@

$(TIMESTAMP_FILE):
  @date +'#define U_BOOT_DATE "%b %d %C%y"' > $@
  @date +'#define U_BOOT_TIME "%T"' >> $@

The version + compile time macro displayed on the terminal or LCD is referenced near line 74 of /lib_arm/board.c.

Open line 74 of /lib_arm/board.c, locate line 74, and modify it as follows:

#ifndef CONFIG_IDENT_STRING
#define CONFIG_IDENT_STRING ""
#endif

/*const char version_string[] = \
  U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")"CONFIG_IDENT_STRING; */
const char version_string[] = U_BOOT_VERSION;

This will block the display of compile time.

2.2, recompile and run the test

[root@localhost u-boot-2009.08]# make clean
Generating include/autoconf.mk
[root@localhost u-boot-2009.08]# make
... ...

arm-linux-objcopy -O srec u-boot u-boot.srec
arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
[root@localhost u-boot-2009.08]#After 
the compilation is completed, copy the u-boot.bin file in the root directory u-boot-2009.08 to the /tftpboot directory. Execute the following command in the terminal connected to the development board:

##### FriendlyARM BIOS 2.0 for 2440 #####
[x] format NAND FLASH for Linux
[v] Download vivi
[k] Download linux kernel
[y] Download root_yaffs image
[a] Absolute User Application
[n] Download Nboot for WinCE
[l] Download WinCE boot-logo
[w] Download WinCE NK.bin
[d] Download & Run
[z] Download zImage into RAM
[g] Boot linux from RAM
[f] Format the nand flash
[b] Boot the system
[s] Set the boot parameters
[u] Backup NAND Flash to HOST through USB(upload)
[r] Restore NAND Flash from HOST through USB
[q] Goto shell of vivi
Enter your selection: d
Clear the free memory
USB host is connected. Waiting a download.

Now, Downloading [ADDRESS:31000000h,TOTAL:99674]
RECEIVED FILE SIZE:   99674 (97KB/S, 1S)
Downloaded file at 0x30000000, size = 99664 bytes


U-Boot 2009.08 ( 5鏈?05 2011 - 22:39:33)

DRAM: 64 MB
Flash: 2 MB
In: serial
Out: serial
Err: serial
[u-boot@MINI2440]#

From the running results, we can see that the size of Nor Flash can be detected correctly, and the name in front of the command line has been changed from the original SMDK2410 to the self-defined [u-boot@MINI2440]#, but there will be a bad CRC warning message. In fact, this is not a problem. It is just that the environment variables have not been set to Nor Flash. We can execute the u-boot: saveenv command. As shown below:

[u-boot@MINI2440]# saveenv
Saving Environment to Flash...
Un-Protected 16 sectors
Erasing Flash...Erasing sector 64 ... ok.
Erasing sector 65 ... ok.
Erasing sector 66 ... ok.
Erasing sector 67 ... ok.
Erasing sector 68 ... ok.
Erasing sector 69 ... ok.
Erasing sector 70 ... ok.
Erasing sector 71 ... ok.
Erasing sector 72 ... ok.
Erasing sector 73 ... ok.
Erasing sector 74 ... ok.
Erasing sector 75 ... ok.
Erasing sector 76 ... ok.
Erasing sector 77 ... ok.
Erasing sector 78 ... ok.
Erasing sector 79 ... ok.
Erased 16 sectors
Writing to Flash... done
Protected 16 sectors
[u-boot@MINI2440]#

Because DRAM is running the current u-boot, its download command has not been implemented yet. You need to power on the development board again and then re-download u-boot.bin to DRAM to run it.

Enter your selection: d
Clear the free memory
USB host is connected. Waiting a download.

Now, Downloading [ADDRESS:31000000h,TOTAL:99682]
RECEIVED FILE SIZE:   99682 (97KB/S, 1S)
Downloaded file at 0x30000000, size = 99672 bytes


U-Boot 2009.08 ( 5鏈?05 2011 - 22:50:40)

DRAM: 64 MB
Flash: 2 MB
In: serial
Out: serial
Err: serial
[u-boot@MINI2440]#

It can be observed that no warning message will appear. At this time, u-boot has fully supported the Nor Flash on our development board.

Next we will enter the third stage of u-boot, adding nand flash support to u-boot-2009.08.


Keywords:u-boot  mini2440  nor Reference address:u-boot-2009.08 transplantation on mini2440 (Part 2) --- Adding NOR flash function

Previous article:Linux-2.6.32.2 kernel porting on mini2440 (Part 4) --- Root file system creation (2)
Next article:ARM Learning Notes (I) "S3C2440A Clock Initialization"

Recommended ReadingLatest update time:2024-11-16 09:34

S3C2440 bare metal ------Nor Flash programming_identification
1. Write a menu program First, we write a test menu program to obtain norFlash information and read and write NorFlash. The code is as follows: void nor_flash_test(void) { char c;   while (1) { /* Print menu for us to choose test content*/ printf(" Scan nor flashnr"); printf(" Erase nor flashnr"); prin
[Microcontroller]
S3C2440 bare metal ------Nor Flash programming_identification
Chapter 6: Tiny4412 U-BOOT transplantation six Nand Flash source code analysis
1. U-Boot reference source code  The initialization code of NandFlash is placed in board/samsung/tiny4412/lowlevel_init.S. This code is not provided in Samsung SMDK4212, so we need to write it ourselves. We add a function called nand_asm_init. Of course, since the operation of Nand Flash has certain rules, we can find
[Microcontroller]
Chapter 6: Tiny4412 U-BOOT transplantation six Nand Flash source code analysis
3. Mini2440 button control LED
First look at the schematic diagram to know the KEY pins: Now we know the pins of the buttons. Based on the pins of the LED in the previous article, we can understand that pressing a button will modify the value of a register. When the CPU detects the button modification, it will output the level to the LED data re
[Microcontroller]
3. Mini2440 button control LED
Nordic SoC enables LeDai C16 smartwatch to have lower power consumption
Nordic Semiconductor has announced that Shenzhen-based technology developer Mo Young Ltd. has selected Nordic’s nRF52840 Bluetooth 5.2/Bluetooth Low Energy (Bluetooth LE) advanced multiprotocol System-on-Chip (SoC) to provide the core processing and wireless connectivity for Le Dai Technology Co., Ltd.’s Le Dai C16 sm
[Internet of Things]
Nordic SoC enables LeDai C16 smartwatch to have lower power consumption
OnePlus Nord CE 2 Lite 5G will be released on April 28, along with Nord headphones
The whistleblower @stufflistings said that OnePlus' new OnePlus Nord CE 2 Lite 5G and OnePlus Nord Buds true wireless earphones will be released in India on April 28, and OnePlus 10R, OnePlus Ace and other models will be launched later.   IT Home reported that OnePlus Nord CE 2 Lite 5G had previously appeared on th
[Mobile phone portable]
OnePlus Nord CE 2 Lite 5G will be released on April 28, along with Nord headphones
OK6410A development board (three) 21 u-boot-2021.01 boot analysis U-boot image running part standalone
First build a standalone environment Then verify initr_jumptable Building a standalone environment In fact, it is a process of loading and executing Load available tftp // Of course, you can also use fatload or other methods. The reason why tftp is used is that in this case tftp is the fastest verification method Ex
[Microcontroller]
u-boot for tiny210v2
Version:Ver0.0 Based on this version of u-boot port: https://gitorious.org/opencsbc/u-boot/archive-tarball/mini210_linaro-2012.11-stable Introduction post: http://www.arm9home.net/read.php?tid-27897.html I transplanted it based on the above version of u-boot. Version:Ver0.1 Compiled bin file: Source code download ad
[Microcontroller]
u-boot for tiny210v2
Application of NOR_FLASH in MCU Development
 In MCU development, NOR_FLASH is commonly used in sizes of 4M and 8M: 4M FLASH can be represented in the program as follows: Ptr 0x220000 8M FLASH can be represented in the program as follows: Ptr 0x400000 (the maximum read value is 0x3fffff) With this relationship, we can use the method of calculating the ch
[Microcontroller]
Application of NOR_FLASH in MCU Development
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号