u-boot transplantation (10)---code modification---support nor flash

Publisher:chenfengy818Latest update time:2023-07-03 Source: elecfansKeywords:u-boot  nor  flash Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Problem location

  

  After the development board restarted, it printed 2 reminders and an error. Ignore the cache reminders for now and look at the reminders under flash and nand. Bad CRC, Using default enviroment. We can locate Using default enviroment.

The code location is as follows:  

  Env_common.c (common) 

  

  The parameter passed in should be !badCRC. Locate the function set_default_env again to see where this function is called:

  

  

  

  

  

  Basically, the files are in the common folder, including calls in common and dataflash, nand, sf, and ubi. I don’t know which one it is for now, but I need to see where this function is called in u-boot.dis and then locate it.

  From u-boot.dis, we can know that the set_default_env function is called in several functions:


    • env_import:Env_common.c (common) 

    • env_relocate:Env_common.c (common)

    • do_env_default:Cmd_nvedit.c (common) 

2. Code analysis

  Search Flash: View results:

  

  The one that matches this is in the board_r.c file.

  Locate the initr_flash function in board_r.c(common).  

  This function is defined in the init_sequence_r linked list in the board_init_r function of the second stage code:

  

2.1 initr_flash

  The code of the initr_flash function is interpreted as follows:

 1 #if !defined(CONFIG_SYS_NO_FLASH) //Execute this function if the macro CONFIG_SYS_NO_FLASH is not defined

 2 static int initr_flash(void)

 3 {

 4 ulong flash_size = 0; //Define the variable that stores the flash space size

 5 bd_t *bd = gd->bd; //Define the board information structure

 6 

 7 puts("Flash: "); //Output string Flash: 

 8 

 9 if (board_flash_wp_on()) //This is an empty function, returns a value of 0, and directly executes the statement following else

10 printf("Uninitialized - Write Protect Onn");

11 else

12 flash_size = flash_init(); //flash initialization

13 

14 print_size(flash_size, ""); //Print the size of flash_size

15 #ifdef CONFIG_SYS_FLASH_CHECKSUM //This macro will not be executed if a piece of code in include/configs/jz2440.h is not defined

16/*

17 * Compute and print flash CRC if flashchecksum is set to 'y'

18*

19 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX

20*/

21 if (getenv_yesno("flashchecksum") == 1) {

22 printf(" CRC: %08X", crc32(0,

23 (const unsigned char *) CONFIG_SYS_FLASH_BASE,

24 flash_size));

25}

26 #endif /* CONFIG_SYS_FLASH_CHECKSUM */

27 putc('n'); //Newline

28 

29 /* update start of FLASH memory */

30 /* CONFIG_SYS_FLASH_BASE is defined in include/configs/jz2440.h

31 * #define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1

32 * #define PHYS_FLASH_1 0x00000000 // Flash Bank #0 

33 * The size of the macro defined here is 0, then the base address of our CONFIG_SYS_FLASH_BASE page is 0

34 */

35 #ifdef CONFIG_SYS_FLASH_BASE        

36 bd->bi_flashstart = CONFIG_SYS_FLASH_BASE; //bd->bi_flashstart = 0 Start execution from address 0

37 #endif

38 /* size of FLASH memory (final value) */

39 bd->bi_flashsize = flash_size; //flash size

40 

41 #if defined(CONFIG_SYS_UPDATE_FLASH_SIZE)

42 /* Make an update of the Memctrl. */

43 update_flash_size(flash_size); //Update flash size

44 #endif

45 

46 

47 #if defined(CONFIG_OXC) || defined(CONFIG_RMU) //Not defined, not executed

48 /* flash mapped at end of memory map */

49 bd->bi_flashoffset = CONFIG_SYS_TEXT_BASE + flash_size;

50 /* #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE

51 * It can be seen from here that CONFIG_SYS_MONITOR_BASE is equal to CONFIG_SYS_FLASH_BASE,

52 * then execute the statement in the macro

53 */

54 #elif CONFIG_SYS_MONITOR_BASE == CONFIG_SYS_FLASH_BASE

55 bd->bi_flashoffset = monitor_flash_len; /* reserved area for monitor */

56 #endif

57 return 0;

58 }

59 #endif


  The statement marked in red is the statement we are executing. It can be seen that the flash space size is printed out after the flash is initialized.


  Locate in flash_init


2.2 flash_init  

  File path: Cfi_flash.c (driversmtd)


  First remove unnecessary macros and streamline the code.


 1 unsigned long flash_init (void)

 2 {

 3 unsigned long size = 0;

 4 int i;

 5 

 6 /* Init: no FLASHes known */

 7 /* #define CONFIG_SYS_MAX_FLASH_BANKS 1 */

 8 /* Defined in include/configs/jz2440.h, it is 1 */

 9 for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {

10 flash_info[i].flash_id = FLASH_UNKNOWN;

11 

12 /* Optionally write flash configuration register */

13 cfi_flash_set_config_reg(cfi_flash_bank_addr(i),

14 cfi_flash_config_reg(i));

15 /* Detect flash

16 * flash_detect_legacy is the old detection strategy

17 */

18 if (!flash_detect_legacy(cfi_flash_bank_addr(i), i))

19 flash_get_size(cfi_flash_bank_addr(i), i);

20 size += flash_info[i].size;

21 if (flash_info[i].flash_id == FLASH_UNKNOWN) {

twenty two }

twenty three }

twenty four 

25 flash_protect_default(); //Default protection of flash

26 return (size);

27}


  In line 18, you see the flash detection. What is detected here is the information and size of the flash. You can go in and look at the source code


2.2.1 flash_detect_legacy

  Source code location: Cfi_flash.c (driversmtd) 


  1 #ifdef CONFIG_FLASH_CFI_LEGACY // defined in include/configs/jz2440.h

  2 /* Read flash product information*/

  3 static void flash_read_jedec_ids (flash_info_t * info)

  4 {

  5 info->manufacturer_id = 0;

  6 info->device_id = 0;

  7 info->device_id2 = 0;

  8 

  9 switch (info->vendor) {

 10 case CFI_CMDSET_INTEL_PROG_REGIONS:

 11 case CFI_CMDSET_INTEL_STANDARD:

 12 case CFI_CMDSET_INTEL_EXTENDED:

 13 cmdset_intel_read_jedec_ids(info);

 14 break;

 15 case CFI_CMDSET_AMD_STANDARD:

 16 case CFI_CMDSET_AMD_EXTENDED:

 17 cmdset_amd_read_jedec_ids(info);

 18 break;

 19 default:

 20 break;

 twenty one }

 twenty two }

 twenty three 

 twenty four /*----------------------------------------------- --------------------------

 25 * Call board code to request info about non-CFI flash.

 26 * board_flash_get_legacy needs to fill in at least:

 27 * info->portwidth, info->chipwidth and info->interface for Jedec probing.

 28 */

 29 static int flash_detect_legacy(phys_addr_t base, int banknum)

 30 {

 31 flash_info_t *info = &flash_info[banknum];

 32 

 33 /* Get the old flash information, the return value is 0 

 34 * info->portwidth = FLASH_CFI_16BIT; 0x02

 35 * info->chipwidth = FLASH_CFI_BY16; 0x02

 36 * info->interface = FLASH_CFI_X16; 0x01

 37 */

 38 if (board_flash_get_legacy(base, banknum, info)) {

 39 /* board code may have filled info completely. If not, we

 40 use JEDEC ID probing. */

 41 if (!info->vendor) {

 42 int modes[] = {

 43 CFI_CMDSET_AMD_STANDARD,

 44 CFI_CMDSET_INTEL_STANDARD

 45};

 46 int i;

 47 

 48 for (i = 0; i < ARRAY_SIZE(modes); i++) {

 49 info->vendor = modes[i];

 50 /* Mapping physical address*/

 51 info->start[0] =

 52 (ulong)map_physmem(base,

 53 info->portwidth,

 54 MAP_NOCACHE);

 55 /* The statement in if is not executed, info->portwidth = FLASH_CFI_16BIT has been set previously;*/

 56 if (info->portwidth == FLASH_CFI_8BIT

 57 && info->interface == FLASH_CFI_X8X16) {

 58 info->addr_unlock1 = 0x2AAA;

 59 info->addr_unlock2 = 0x5555;

 60 } else {/* Execute the statement in else and send 0x5555 0x2aaa command*/

 61 info->addr_unlock1 = 0x5555;

 62 info->addr_unlock2 = 0x2AAA;

 63}

 64 flash_read_jedec_ids(info);

 65 debug("JEDEC PROBE: ID %x %x %xn",

 66 info->manufacturer_id,

 67 info->device_id,

 68 info->device_id2);

 69 /* Adapt to flash */

 70 if (jedec_flash_match(info, info->start[0]))

 71 break;

 72 else

 73 unmap_physmem((void *)info->start[0],

 74 info->portwidth);

 75 }

 76 }

 77 

 78 switch(info->vendor) {

 79 case CFI_CMDSET_INTEL_PROG_REGIONS:

 80 case CFI_CMDSET_INTEL_STANDARD:

 81 case CFI_CMDSET_INTEL_EXTENDED:

 82 info->cmd_reset = FLASH_CMD_RESET;

 83 break;

 84 case CFI_CMDSET_AMD_STANDARD:

 85 case CFI_CMDSET_AMD_EXTENDED:

 86 case CFI_CMDSET_AMD_LEGACY:

 87 info->cmd_reset = AMD_CMD_RESET;

 88 break;

 89 }

 90 info->flash_id = FLASH_MAN_CFI;

 91 return 1;

 92 }

 93 return 0; /* use CFI */

 94}

 95 #else

 96 static inline int flash_detect_legacy(phys_addr_t base, int banknum)

 97 {

 98 return 0; /* use CFI */

 99 }

100 #endif

  I don’t know whether to execute it here. You can try to debug it. To debug, you must first turn on the debug macro. Add the debug macro at the top of include/common.h. #define DEBUG Then recompile the flash information printed on startup as follows:

  

  Two JEDEC PROBEs are printed here, one is printed in flash_detect_legacy, and I don’t know what they are.

  Check the ID of norflash. The model of norflash is MX29LV160DBTI.

  The COMMAND OPERATIONS of the chip manual has the following lines:

  

  

  The picture above illustrates how to read the ID. The yellow part is the address. That is, if you issue aa at the 555 address, issue the 55 command at the 2AA address, and issue the 90 command at the 555 address, you can read the manufacturer ID c2 at the 00 address.

  2249 corresponds to our device ID number. It seems that nor flash has been identified.

  JEDEC PROBE is in the debug print function of flash_detect_legacy (Cfi_flash.c (driversmtd)), and then executes jedec_flash_match(info, info->start[0]) to match.

  In jedec_flash_match, it will match the jedec_table array. If there is, it will return 1, if not, it will return 0.

2.2.2 jedec_flash_match

 1 int jedec_flash_match(flash_info_t *info, ulong base)

 2 {

 3 int ret = 0;

 4 int i;

 5 ulong mask = 0xFFFF;

 6 if (info->chipwidth == 1)

 7 mask = 0xFF;

 8 

 9 for (i = 0; i < ARRAY_SIZE(jedec_table); i++) {

10 if ((jedec_table[i].mfr_id & mask) == (info->manufacturer_id & mask) &&

11 (jedec_table[i].dev_id & mask) == (info->device_id & mask)) {

12 fill_info(info, &jedec_table[i], base);

13 ret = 1;

14 break;

15}

16}

17 return ret;

18}

  Check the jedec_table (Jedec_flash.c (driversmtd)) to see if there are c2 2249 0 items. If it is not found after searching, you need to add the device information.

  The manufacturer ID is added (Flash.h (include)), which already exists in the header file.   

   

  search:

  

  The ID of MX_MANUFACT is referenced in two places.

  The top one needs to define the macro CONFIG_SYS_FLASH_LEGACY_512Kx8 before it can be referenced

[1] [2]
Keywords:u-boot  nor  flash Reference address:u-boot transplantation (10)---code modification---support nor flash

Previous article:u-boot transplant (12)---code modification---support DM9000 network card
Next article:u-boot transplantation (9)---Code modification---NAND

Recommended ReadingLatest update time:2024-11-15 10:17

U-boot porting on mini2440-S3C2440 (3) - Phase 1: Exploring the boot code
1. This article takes the mini2440 development board as an example: u-boot is a two-stage Bootloader. The first stage files are CPU/arm920t/start.S and board/mini2440/lowlevel_init.S. The former is platform-related and the latter is development board-related. U-boot first stage code: 1. Hardware device initialization
[Microcontroller]
The difference between NAND boot and NOR boot of u-boot
The differences between NAND startup and NOR startup are mainly divided into the following parts: 1. The main difference between NAND flash and NOR flash 2. The principle of NAND startup and NOR startup of s3c2440 3. What does uboot do when nand starts and nor starts 1. There are two types of
[Microcontroller]
The difference between NAND boot and NOR boot of u-boot
U-BOOT transplantation solution based on S3C2410 development board
introduction As embedded systems become more and more complex, their demand for large-capacity data storage becomes more and more urgent. However, the requirements of low power consumption, small size and low cost of embedded devices prevent hard disks from being widely used. NAND flash memory devices have developed r
[Microcontroller]
U-BOOT transplantation solution based on S3C2410 development board
S3C6410 transplant u-boot (I)
step 1 1. First download u-boot ( ftp://ftp.denx.de/pub/u-boot ) wget  ftp://ftp.denx.de/pub/u-boot/u-boot-latest.tar.bz2 2. Unzip to the path you specify tar -jxvf u-boot-latest.tar.bz2 -C /opt Step 2 1. Enter the u-boot- release date folder  cd /opt/u-boot-2011.06/ cd board/samsung/ 2. Create the smdk6410 folder
[Microcontroller]
Porting U-boot to mini2440 from scratch (Part 3) - CPU initialization
After the preparation in the first two sections, we can now start to work on the u-boot code. U-boot version: 2020/5/2 Compilation environment: Ubuntu 16.04 arm-none-eabi-gcc version 4.9.3 20150529 (prerelease) (15:4.9.3+svn231177-1) Operating environment: mini2440 (s3c2440, arm920t) Code repository: git@github.com:Ji
[Microcontroller]
Tutorial on using STM8L's own bootloader
The microcontroller model used by the author is: STM8L151C8T6, with 64kFlash Download addresses for files that may be used in this tutorial: Official firmware and instruction manual: https://www.stmcu.com.cn/Index/search?search_keywords=UM0560 Baidu network disk link: https://pan.baidu.com/s/1XyBWJIhHsuwWgwGNuHa
[Microcontroller]
Tutorial on using STM8L's own bootloader
Learning based on stm32f103zet6 nor flash
Sometimes, we need to save a small amount of data, but it is inconvenient to use an external ROM. At this time, we naturally think about whether the chip has its own flash memory. As far as I know, the internal STM32 should be NOR flash, because if it is NAND flash, the speed will definitely not keep up. However, if y
[Microcontroller]
What is the difference between FLASH and EEPROM during microcontroller development? How to choose?
In the past, when I was working on projects, I sometimes used Flash and sometimes used EEPROM, which made me a little confused. Then I searched some information on the Internet. After reading it, I still couldn't understand it thoroughly. It wasn't until I did many projects that I fully understood it. Flash and EEPROM
[Microcontroller]
Latest Microcontroller Articles
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号