linux nand flash驱动编写
<p>很长一段时间,nand flash都是嵌入式的标配产品。nand flash价格便宜,存储量大,适用于很多的场景。现在很普及的ssd,上面的存储模块其实也是由一块一块nand flash构成的。对于linux嵌入式来说,开始uboot的加载是硬件完成的,中期的kernel加载是由uboot中的nand flash驱动完成的,而后期的rootfs加载,这就要靠kernel自己来完成了。当然,这次还是以三星s3c芯片为例进行说明。</p>
<p>
1、nand flash驱动在什么地方,可以从drviers/mtd/Makefile来看</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterplain" id="highlighter_544272">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="plain plain">obj-y += chips/ lpddr/ maps/ devices/ nand/ onenand/ tests/</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
2、nand在mtd下面,是作为一个单独目录保存的,这时应该查看nand下的Kconfig</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterplain" id="highlighter_947995">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
<div class="line number11 index10 alt2">
11</div>
<div class="line number12 index11 alt1">
12</div>
<div class="line number13 index12 alt2">
13</div>
<div class="line number14 index13 alt1">
14</div>
<div class="line number15 index14 alt2">
15</div>
<div class="line number16 index15 alt1">
16</div>
<div class="line number17 index16 alt2">
17</div>
<div class="line number18 index17 alt1">
18</div>
<div class="line number19 index18 alt2">
19</div>
<div class="line number20 index19 alt1">
20</div>
<div class="line number21 index20 alt2">
21</div>
<div class="line number22 index21 alt1">
22</div>
<div class="line number23 index22 alt2">
23</div>
<div class="line number24 index23 alt1">
24</div>
<div class="line number25 index24 alt2">
25</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="plain plain">config MTD_NAND_S3C2410 </code>
</div>
<div class="line number2 index1 alt1">
<code class="plain spaces"> </code><code class="plain plain">tristate "NAND Flash support for Samsung S3C SoCs" </code>
</div>
<div class="line number3 index2 alt2">
<code class="plain spaces"> </code><code class="plain plain">depends on ARCH_S3C24XX || ARCH_S3C64XX </code>
</div>
<div class="line number4 index3 alt1">
<code class="plain spaces"> </code><code class="plain plain">help </code>
</div>
<div class="line number5 index4 alt2">
<code class="plain spaces"> </code><code class="plain plain">This enables the NAND flash controller on the S3C24xx and S3C64xx </code>
</div>
<div class="line number6 index5 alt1">
<code class="plain spaces"> </code><code class="plain plain">SoCs </code>
</div>
<div class="line number7 index6 alt2">
<code class="plain spaces"> </code>
</div>
<div class="line number8 index7 alt1">
<code class="plain spaces"> </code><code class="plain plain">No board specific support is done by this driver, each board </code>
</div>
<div class="line number9 index8 alt2">
<code class="plain spaces"> </code><code class="plain plain">must advertise a platform_device for the driver to attach. </code>
</div>
<div class="line number10 index9 alt1">
<code class="plain spaces"> </code>
</div>
<div class="line number11 index10 alt2">
<code class="plain plain">config MTD_NAND_S3C2410_DEBUG </code>
</div>
<div class="line number12 index11 alt1">
<code class="plain spaces"> </code><code class="plain plain">bool "Samsung S3C NAND driver debug" </code>
</div>
<div class="line number13 index12 alt2">
<code class="plain spaces"> </code><code class="plain plain">depends on MTD_NAND_S3C2410 </code>
</div>
<div class="line number14 index13 alt1">
<code class="plain spaces"> </code><code class="plain plain">help </code>
</div>
<div class="line number15 index14 alt2">
<code class="plain spaces"> </code><code class="plain plain">Enable debugging of the S3C NAND driver </code>
</div>
<div class="line number16 index15 alt1">
<code class="plain spaces"> </code>
</div>
<div class="line number17 index16 alt2">
<code class="plain plain">config MTD_NAND_S3C2410_CLKSTOP </code>
</div>
<div class="line number18 index17 alt1">
<code class="plain spaces"> </code><code class="plain plain">bool "Samsung S3C NAND IDLE clock stop" </code>
</div>
<div class="line number19 index18 alt2">
<code class="plain spaces"> </code><code class="plain plain">depends on MTD_NAND_S3C2410 </code>
</div>
<div class="line number20 index19 alt1">
<code class="plain spaces"> </code><code class="plain plain">default n </code>
</div>
<div class="line number21 index20 alt2">
<code class="plain spaces"> </code><code class="plain plain">help </code>
</div>
<div class="line number22 index21 alt1">
<code class="plain spaces"> </code><code class="plain plain">Stop the clock to the NAND controller when there is no chip </code>
</div>
<div class="line number23 index22 alt2">
<code class="plain spaces"> </code><code class="plain plain">selected to save power. This will mean there is a small delay </code>
</div>
<div class="line number24 index23 alt1">
<code class="plain spaces"> </code><code class="plain plain">when the is NAND chip selected or released, but will save </code>
</div>
<div class="line number25 index24 alt2">
<code class="plain spaces"> </code><code class="plain plain">approximately 5mA of power when there is nothing happening.</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
3、不难发现,MTD_NAND_S3C2410才是那个真正的macro,尝试在Makefile找文件</p>
<div class="jb51code">
<div>
<div class="syntaxhighlighterplain" id="highlighter_817727">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="plain plain">obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
4、查看s3c2410.c文件,看看基本结构构成</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightercpp" id="highlighter_685265">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
<div class="line number11 index10 alt2">
11</div>
<div class="line number12 index11 alt1">
12</div>
<div class="line number13 index12 alt2">
13</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="cpp keyword bold">static</code> <code class="cpp keyword bold">struct</code> <code class="cpp plain">platform_driver s3c24xx_nand_driver = { </code>
</div>
<div class="line number2 index1 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">.probe = s3c24xx_nand_probe, </code>
</div>
<div class="line number3 index2 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">.</code><code class="cpp functions bold">remove</code> <code class="cpp plain">= s3c24xx_nand_remove, </code>
</div>
<div class="line number4 index3 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">.suspend = s3c24xx_nand_suspend, </code>
</div>
<div class="line number5 index4 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">.resume = s3c24xx_nand_resume, </code>
</div>
<div class="line number6 index5 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">.id_table = s3c24xx_driver_ids, </code>
</div>
<div class="line number7 index6 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">.driver = { </code>
</div>
<div class="line number8 index7 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">.name = </code><code class="cpp string">"s3c24xx-nand"</code><code class="cpp plain">, </code>
</div>
<div class="line number9 index8 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">.of_match_table = s3c24xx_nand_dt_ids, </code>
</div>
<div class="line number10 index9 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">}, </code>
</div>
<div class="line number11 index10 alt2">
<code class="cpp plain">}; </code>
</div>
<div class="line number12 index11 alt1">
<code class="cpp spaces"> </code>
</div>
<div class="line number13 index12 alt2">
<code class="cpp plain">module_platform_driver(s3c24xx_nand_driver);</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
5、继续分析s3c24xx_nand_probe函数</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightercpp" id="highlighter_216971">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="cpp plain">s3c2410_nand_init_chip(info, nmtd, sets);</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
6、之所以从中摘出了s3c2410_nand_init_chip这个函数,是因为里面进行了函数注册</p>
<p>
类似的函数还有s3c2410_nand_update_chip函数</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightercpp" id="highlighter_618722">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
<div class="line number11 index10 alt2">
11</div>
<div class="line number12 index11 alt1">
12</div>
<div class="line number13 index12 alt2">
13</div>
<div class="line number14 index13 alt1">
14</div>
<div class="line number15 index14 alt2">
15</div>
<div class="line number16 index15 alt1">
16</div>
<div class="line number17 index16 alt2">
17</div>
<div class="line number18 index17 alt1">
18</div>
<div class="line number19 index18 alt2">
19</div>
<div class="line number20 index19 alt1">
20</div>
<div class="line number21 index20 alt2">
21</div>
<div class="line number22 index21 alt1">
22</div>
<div class="line number23 index22 alt2">
23</div>
<div class="line number24 index23 alt1">
24</div>
<div class="line number25 index24 alt2">
25</div>
<div class="line number26 index25 alt1">
26</div>
<div class="line number27 index26 alt2">
27</div>
<div class="line number28 index27 alt1">
28</div>
<div class="line number29 index28 alt2">
29</div>
<div class="line number30 index29 alt1">
30</div>
<div class="line number31 index30 alt2">
31</div>
<div class="line number32 index31 alt1">
32</div>
<div class="line number33 index32 alt2">
33</div>
<div class="line number34 index33 alt1">
34</div>
<div class="line number35 index34 alt2">
35</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="cpp plain">chip->write_buf = s3c2410_nand_write_buf; </code>
</div>
<div class="line number2 index1 alt1">
<code class="cpp plain">chip->read_buf = s3c2410_nand_read_buf; </code>
</div>
<div class="line number3 index2 alt2">
<code class="cpp plain">chip->select_chip = s3c2410_nand_select_chip; </code>
</div>
<div class="line number4 index3 alt1">
<code class="cpp plain">chip->chip_delay = 50; </code>
</div>
<div class="line number5 index4 alt2">
<code class="cpp plain">nand_set_controller_data(chip, nmtd); </code>
</div>
<div class="line number6 index5 alt1">
<code class="cpp plain">chip->options = set->options; </code>
</div>
<div class="line number7 index6 alt2">
<code class="cpp plain">chip->controller = &info->controller; </code>
</div>
<div class="line number8 index7 alt1">
<code class="cpp keyword bold">switch</code> <code class="cpp plain">(info->cpu_type) { </code>
</div>
<div class="line number9 index8 alt2">
<code class="cpp keyword bold">case</code> <code class="cpp plain">TYPE_S3C2410: </code>
</div>
<div class="line number10 index9 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">chip->IO_ADDR_W = regs + S3C2410_NFDATA; </code>
</div>
<div class="line number11 index10 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">info->sel_reg = regs + S3C2410_NFCONF; </code>
</div>
<div class="line number12 index11 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">info->sel_bit = S3C2410_NFCONF_nFCE; </code>
</div>
<div class="line number13 index12 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">chip->cmd_ctrl = s3c2410_nand_hwcontrol; </code>
</div>
<div class="line number14 index13 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">chip->dev_ready = s3c2410_nand_devready; </code>
</div>
<div class="line number15 index14 alt2">
<code class="cpp spaces"> </code><code class="cpp keyword bold">break</code><code class="cpp plain">; </code>
</div>
<div class="line number16 index15 alt1">
<code class="cpp spaces"> </code>
</div>
<div class="line number17 index16 alt2">
<code class="cpp keyword bold">case</code> <code class="cpp plain">TYPE_S3C2440: </code>
</div>
<div class="line number18 index17 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">chip->IO_ADDR_W = regs + S3C2440_NFDATA; </code>
</div>
<div class="line number19 index18 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">info->sel_reg = regs + S3C2440_NFCONT; </code>
</div>
<div class="line number20 index19 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">info->sel_bit = S3C2440_NFCONT_nFCE; </code>
</div>
<div class="line number21 index20 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">chip->cmd_ctrl = s3c2440_nand_hwcontrol; </code>
</div>
<div class="line number22 index21 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">chip->dev_ready = s3c2440_nand_devready; </code>
</div>
<div class="line number23 index22 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">chip->read_buf = s3c2440_nand_read_buf; </code>
</div>
<div class="line number24 index23 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">chip->write_buf = s3c2440_nand_write_buf; </code>
</div>
<div class="line number25 index24 alt2">
<code class="cpp spaces"> </code><code class="cpp keyword bold">break</code><code class="cpp plain">; </code>
</div>
<div class="line number26 index25 alt1">
<code class="cpp keyword bold">case</code> <code class="cpp plain">TYPE_S3C2412: </code>
</div>
<div class="line number27 index26 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">chip->IO_ADDR_W = regs + S3C2440_NFDATA; </code>
</div>
<div class="line number28 index27 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">info->sel_reg = regs + S3C2440_NFCONT; </code>
</div>
<div class="line number29 index28 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">info->sel_bit = S3C2412_NFCONT_nFCE0; </code>
</div>
<div class="line number30 index29 alt1">
<code class="cpp spaces"> </code><code class="cpp plain">chip->cmd_ctrl = s3c2440_nand_hwcontrol; </code>
</div>
<div class="line number31 index30 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">chip->dev_ready = s3c2412_nand_devready; </code>
</div>
<div class="line number32 index31 alt1">
<code class="cpp spaces"> </code><code class="cpp keyword bold">if</code> <code class="cpp plain">(readl(regs + S3C2410_NFCONF) & S3C2412_NFCONF_NANDBOOT) </code>
</div>
<div class="line number33 index32 alt2">
<code class="cpp spaces"> </code><code class="cpp plain">dev_info(info->device, </code><code class="cpp string">"System booted from NAND\n"</code><code class="cpp plain">); </code>
</div>
<div class="line number34 index33 alt1">
<code class="cpp spaces"> </code><code class="cpp keyword bold">break</code><code class="cpp plain">; </code>
</div>
<div class="line number35 index34 alt2">
<code class="cpp plain">} </code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div class="codetool" id="codetool">
<div class="code_n">
<textarea></textarea>
</div>
</div>
</div>
<p>
7、抓住了函数接口,就找到了基本逻辑。</p>
<p>
对于框架来说,它不关心你的代码如何实现。只要你按照它的接口写,就能让上层正常获得数据。platform、usb、pci这都是一种接口形式,具体实现还要按照各个具体功能模块来实现才行。</p>
<p>
8、为什么我们都用s3c芯片进行举例</p>
<p>
因为它用的场景最多,学习资料最全,对于新手来说,这会少很多麻烦。</p>
<p>
9、这个驱动依赖的kernel版本是什么</p>
<p>
这里最有的代码都是按照最新4.16的版本进行分析的,大家可以直接查看这里的地址。</p>
<p>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。</p>
<p>
原文链接:https://blog.csdn.net/feixiaoxing/article/details/79855970</p>
頁:
[1]