In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly explains "what is the initialization process of nand in u-boot". The content of the explanation is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn how the initialization process of nand in u-boot is.
For soc on-chip nand controllers, hardware initialization should include the following aspects:
1. Clock settings used by the nand module
2. Now that a chip is connected, the related pins need to be initialized to support nand.
3. Configuration of nand control registers, such as interrupt, DMA mode, etc.
Here are some simple ideas. Let's take a look at the code flow in u-boot.
I. process analysis
Assuming that the nand driver is defined, the following code will be called when the power is on
.
# if defined (CONFIG_CMD_NAND)
Puts ("NAND:")
Nand_init (); / * go init the NAND * /
# endif
.
This code is in the file\ u-boot-sunxi-sunxi\ arch\ arm\ lib\ board.c
It can be seen that if you want to use the nand driver, you have to define the macro CONFIG_CMD_NAND
A function nand_init () is called in the file\ u-boot-sunxi-sunxi\ drivers\ mtd\ nand\ nand.c:
Void nand_init (void)
{
# ifdef CONFIG_SYS_NAND_SELF_INIT
Board_nand_init ()
# else
Int i
For (I = 0; I)
< CONFIG_SYS_MAX_NAND_DEVICE; i++) nand_init_chip(i); #endif printf("%lu MiB\n", total_nand_size / 1024); #ifdef CONFIG_SYS_NAND_SELECT_DEVICE /* * Select the chip in the board/cpu specific driver */ board_nand_select_device(nand_info[nand_curr_device].priv, nand_curr_device); #endif } 这个函数用了一个宏CONFIG_SYS_MAX_NAND_DEVICE,很明显,表示板子上有几颗nand芯片, cubieboard当然是一颗,这个宏需要自己定义,值为1 一般来说,这个函数都将调用nand_init_chip(),在来看看这个函数,也在这个文件内: static void nand_init_chip(int i) { struct mtd_info *mtd = &nand_info; struct nand_chip *nand = &nand_chip; ulong base_addr = base_address; int maxchips = CONFIG_SYS_NAND_MAX_CHIPS; if (maxchips < 1) // 防止错误的数据 maxchips = 1; mtd->Priv = nand
Nand- > IO_ADDR_R = nand- > IO_ADDR_W = (void _ iomem *) base_addr
If (board_nand_init (nand)) / / hardware initialization
Return
If (nand_scan (mtd, maxchips)) / / API function initialization
Return
Nand_register (I); / / device registration
}
This function calls three functions to complete the initialization
The board_nand_init () function is the initialization associated with the board, which is the code you need to implement.
The nand_scan () function, which I understand is the initialization of the interface, initializes some of the functions used by the MTD module to the code implemented by the user.
Nand_register () registers the driver, this code does not need the user to implement
Here's a code detail.
Mtd- > priv = nand
The private data of the mtd module is the nand structure. Initializing the nand structure during initialization can transfer the operation to the mtd layer.
I'll analyze this later.
Let's take a look at these three functions. Board_nand_init () does not exist, but needs to be implemented by the user.
For example, create your own driver code file sunxi_nand.c in\ u-boot-sunxi-sunxi\ drivers\ mtd\ nand\
You need to define this function inside.
Int board_nand_init (struct nand_chip * nand)
This function has two parts:
1. These are the three aspects mentioned at the beginning
Clock settings used by the nand module
Several related pins need to be initialized to support nand functionality
Configuration of nand control registers, such as interrupt, DMA mode, etc.
2. Initialization of related structure data
There are other parts of the code that need to be implemented within the sunxi_nand.c, which should be determined according to the actual CPU
At this point, we need to talk about programming patterns. Nand drivers are also written in an object-oriented way, and the function of board_nand_init is to instantiate a nand class.
A structure is operated here.
Struct nand_chip {
Void _ _ iomem * IO_ADDR_R
Void _ _ iomem * IO_ADDR_W
Uint8_t (* read_byte) (struct mtd_info * mtd)
U16 (* read_word) (struct mtd_info * mtd)
Void (* write_buf) (struct mtd_info * mtd, const uint8_t * buf, int len)
Void (* read_buf) (struct mtd_info * mtd, uint8_t * buf, int len)
Int (* verify_buf) (struct mtd_info * mtd, const uint8_t * buf, int len)
Void (* select_chip) (struct mtd_info * mtd, int chip)
Int (* block_bad) (struct mtd_info * mtd, loff_t ofs, int getchip)
Int (* block_markbad) (struct mtd_info * mtd, loff_t ofs)
Void (* cmd_ctrl) (struct mtd_info * mtd, int dat, unsigned int ctrl)
Int (* init_size) (struct mtd_info * mtd, struct nand_chip * this)
U8 * id_data)
Int (* dev_ready) (struct mtd_info * mtd)
Void (* cmdfunc) (struct mtd_info * mtd, unsigned command, int column)
Int page_addr)
Int (* waitfunc) (struct mtd_info * mtd, struct nand_chip * this)
Void (* erase_cmd) (struct mtd_info * mtd, int page)
Int (* scan_bbt) (struct mtd_info * mtd)
Int (* errstat) (struct mtd_info * mtd, struct nand_chip * this, int state)
Int status, int page)
Int (* write_page) (struct mtd_info * mtd, struct nand_chip * chip)
Const uint8_t * buf, int page, int cached, int raw)
Int chip_delay
Unsigned int options
Int page_shift
Int phys_erase_shift
Int bbt_erase_shift
Int chip_shift
Int numchips
Uint64_t chipsize
Int pagemask
Int pagebuf
Int subpagesize
Uint8_t cellinfo
Int badblockpos
Int badblockbits
Int onfi_version
# ifdef CONFIG_SYS_NAND_ONFI_DETECTION
Struct nand_onfi_params onfi_params
# endif
Int state
Uint8_t * oob_poi
Struct nand_hw_control * controller
Struct nand_ecclayout * ecclayout
Struct nand_ecc_ctrl ecc
Struct nand_buffers * buffers
Struct nand_hw_control hwcontrol
Struct mtd_oob_ops ops
Uint8_t * bbt
Struct nand_bbt_descr * bbt_td
Struct nand_bbt_descr * bbt_md
Struct nand_bbt_descr * badblock_pattern
Void * priv
}
This structure is a "class". All nand can be implemented in this way, and users only need to implement some of these "methods".
These "methods" have been implemented by default and have been written in the file\ u-boot-sunxi-sunxi\ drivers\ mtd\ nand\ nand_base.c.
For example, the older chip s3c2440Magi s3c6410 can directly use these library functions, do not need to write separately, unfortunately, cubieboard A10 is not included in this list.
For A10, within the board_nand_init function, the following initialization is necessary:
.
/ * initialize nand_chip data structure * /
Nand- > IO_ADDR_R = (void *) & nand_reg- > io_data; / / read and write registers. This initialization needs to be considered. No data is bitter.
Nand- > IO_ADDR_W = (void *) & nand_reg- > io_data
Nand- > select_chip = sunxi_select_chip; / / fragment selection function, which must be implemented by any CPU
/ * hwcontrol always must be implemented * /
Nand- > dev_ready = sunxi_dev_ready; / / read chip ready state
Nand- > cmdfunc = sunxi_nand_command; / / command operation function, with this there is no need for nand- > cmd_ctrl
# ifdef CONFIG_SUNXI_NAND_HWECC
Nand- > ecc.hwctl = sunxi_nand_enable_hwecc; / / none of these error controls have been implemented, leave the interface first, wait for further improvement, and use the default implementation
Nand- > ecc.calculate = sunxi_nand_calculate_ecc
Nand- > ecc.correct = sunxi_nand_correct_data
Nand- > ecc.mode = NAND_ECC_HW
Nand- > ecc.size = CONFIG_SYS_NAND_ECCSIZE
Nand- > ecc.bytes = CONFIG_SYS_NAND_ECCBYTES
# else
Nand- > ecc.mode = NAND_ECC_SOFT
# endif
# ifdef CONFIG_SUNXI_NAND_BBT
Nand- > options = NAND_USE_FLASH_BBT
# else
Nand- > options = 0; / * 8bit * / / the operating bit width of flash. Check the 8-bit data of the chip.
# endif
Nand- > priv = nand_cs + chip_n++; / / this is equivalent to the private data of C++. I have saved the number of the chip. There is only one piece of nand, which is 0.
....
Here the nand pointer is the details mentioned above.
Mtd- > priv = nand
This is after a considerable part of the mtd content has also been initialized.
Let's take a look at the nand_scan () function,\ u-boot-sunxi-sunxi\ drivers\ mtd\ nand\ nand_base.c
Int nand_scan (struct mtd_info * mtd, int maxchips)
{
Int ret
Ret = nand_scan_ident (mtd, maxchips, NULL)
If (! ret)
Ret = nand_scan_tail (mtd)
Return ret
}
After analyzing the call relationship of this function, we can see that according to the previous initialization, we can read the information of nand, that is, id, vendor, name, page size, capacity, and so on.
Initialize the unimplemented parts of the user, and the code is in the following form, as an example:
/ * check for proper chip_delay setup, set 20us if not * /
If (! chip- > chip_delay)
Chip- > chip_delay = 20; / / if no chip delay is defined, the default is 20ns, which depends on the specific chip manual.
/ * check, if a user supplied command function given * /
If (chip- > cmdfunc = = NULL)
Chip- > cmdfunc = nand_command; / / if chip- > cmdfunc is not implemented, the default command operation function is used
/ / while the default unsuitable A10 cmdfunc function defines nand- > cmdfunc = sunxi_nand_command.
/ / so this will not be initialized again
/ * check, if a user supplied wait function given * /
If (chip- > waitfunc = = NULL)
Chip- > waitfunc = nand_wait; / / this is not defined and the default function nand_wait will be used
A lot of calls like this, of course, the user can also completely implement all the functions themselves, but if there is a suitable one, it is not necessary to stand on the shoulders of others, can see further
Thank you for your reading, these are the contents of "how is the initialization process of nand in u-boot". After the study of this article, I believe you have a deeper understanding of how the initialization process of nand in u-boot is, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.