u-boot下spi norflash驅動大雜繪

一、總述

http://blackfin.uclinux.org/doku.php?id=bootloaders:u-boot:serial-flash

在一般的情況是我們會把bootloader存放到我們的spiflash中去,現在就有一些的CPU可以支持從spiflash中啓動,這時我們在uboot要完成針對你的spiflash的驅動,下面我就個人在最近的工作中的一些心得總結一下。

二、uboot下spi flash命令

1)probe
uboot> sf probe 2
SF: Got idcode 20 20 15
2048 KiB M25P16 at 0:2 is now current device
上面的命令就是去probe指定bus下的spi flash設備,有了這個同時probe成功,纔可以去write/read你的spilfahs.
2)read
uboot> sf read 0x2000000 0x300 0x1000
uboot> md.b 0x2000000
02000000: 4a e1 c0 ff 10 62 0a e1 04 0a 40 e1 c2 ff 10 93    J....b....@.....
02000010: 22 6c 10 93 48 60 c2 6f 10 97 4a e1 e0 ff 20 e1    "l..H`.o..J... .
02000020: fd 01 0a e1 04 20 88 4f 10 93 c6 6c 27 01 30 05    ..... .O...l'.0.
02000030: 10 00 00 00 4a e1 e0 ff 40 e1 fa 03 0a e1 0c 20    ....J...@......
3)erase
uboot> sf erase 0x30000 0x10000
4)write
uboot> sf write 0x20000000 0x0 0x100000

5)同樣可以設備env來引導kernel,如下
uboot> set sfboot 'sf probe 2; sf read 0x2000000 0x300 0x100000; bootm 0x2000000'
uboot> set bootcmd run sfboot
uboot> save
通過上面這個,我們就可以引導一個存在spiflash中的kernel

三、代碼分析

我們當執行sf命令時,執行的函數如下:
common/cmd_sf.c
490 static int do_spi_flash(cmd_tbl_t *cmdtp, int flag, int argc,
491                         char * const argv[])
492 {
493         const char *cmd;
494         int ret;
495 
496         /* need at least two arguments */
497         if (argc < 2)//如果參數小於2測,顯示使作幫助
498                 goto usage;
499 
500         cmd = argv[1];
501         --argc;
502         ++argv;
503 
504         if (strcmp(cmd, "probe") == 0) {//執行probe時的分支
505                 ret = do_spi_flash_probe(argc, argv);
506                 goto done;
507         }
508 
509         /* The remaining commands require a selected device */
510         if (!flash) {
511                 puts("No SPI flash selected. Please run `sf probe'\n");
512                 return 1;
513         }
514 
515         if (strcmp(cmd, "read") == 0 || strcmp(cmd, "write") == 0 ||  //read/write的分枝
516             strcmp(cmd, "update") == 0)
517                 ret = do_spi_flash_read_write(argc, argv);
518         else if (strcmp(cmd, "erase") == 0)
519                 ret = do_spi_flash_erase(argc, argv);
520 #ifdef CONFIG_CMD_SF_TEST
521         else if (!strcmp(cmd, "test"))
522                 ret = do_spi_flash_test(argc, argv);
523 #endif
524         else
525                 ret = -1;
526 
527 done:
528         if (ret != -1)
529                 return ret;
530 
531 usage:
532         return CMD_RET_USAGE;}

89 static int do_spi_flash_probe(int argc, char * const argv[])
 90 {
 91         unsigned int bus = CONFIG_SF_DEFAULT_BUS;
 92         unsigned int cs = CONFIG_SF_DEFAULT_CS;
 93         unsigned int speed = CONFIG_SF_DEFAULT_SPEED;
 94         unsigned int mode = CONFIG_SF_DEFAULT_MODE;
 95         char *endp;
 96         struct spi_flash *new;
 97 
 98         if (argc >= 2) {
 99                 cs = simple_strtoul(argv[1], &endp, 0);
100                 if (*argv[1] == 0 || (*endp != 0 && *endp != ':'))
101                         return -1;
102                 if (*endp == ':') {
103                         if (endp[1] == 0)
104                                 return -1;
105 
106                         bus = cs;
107                         cs = simple_strtoul(endp + 1, &endp, 0);
108                         if (*endp != 0)
109                                 return -1;
110                 }
111         }
112 
113         if (argc >= 3) {
114                 speed = simple_strtoul(argv[2], &endp, 0);
115                 if (*argv[2] == 0 || *endp != 0)
116                         return -1;
117         }
118         if (argc >= 4) {
119                 mode = simple_strtoul(argv[3], &endp, 16);
120                 if (*argv[3] == 0 || *endp != 0)
121                         return -1;
122         }
123 
124         new = spi_flash_probe(bus, cs, speed, mode);//根據外面傳入的but/CS來probe你的spi flash
125         if (!new) {
126                 printf("Failed to initialize SPI flash at %u:%u\n", bus, cs);
127                 return 1;
128         }
129 
130         if (flash)
131                 spi_flash_free(flash);
132         flash = new;
133 
134         return 0;
135 }


.....................................................待續
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章