步驟html
焊flash芯片(若是大於16M,須要改燒錄工具的源碼)
焊引腳,爲了串口看數據
焊接flash芯片,須要注意1號腳的位置,flash芯片在開發板背面,1號腳位置是靠近麥克風的那邊linux
如下爲編譯相關步驟,參考鏈接,注意,下載的源碼,選用spi flash模式git
ubootgithub
git clone -b v3s-spi-experimental https://github.com/Lichee-Pi/u-boot.git make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig Architecture select,選ARM Device Drivers SPI Flash Support 勾選本身flash的廠家名稱,這裏選Macronix SPI flash support 若是使用的是16MB以上的flash,須要勾選flash bank支持選項,不然最多隻能讀到16MB
code include/configs/sun8i.h,在include xxx以前添加
#define CONFIG_BOOTCOMMAND "sf probe 0; " \ "sf read 0x41800000 0x100000 0x10000; " \ "sf read 0x41000000 0x110000 0x400000; " \ "bootz 0x41000000 - 0x41800000" #define CONFIG_BOOTARGS "console=ttyS0,115200 earlyprintk panic=5 rootwait " \ "mtdparts=spi32766.0:1M(uboot)ro,64k(dtb)ro,4M(kernel)ro,-(rootfs) root=31:03 rw rootfstype=jffs2"
編譯函數
time make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- 2>&1 | tee build.log
下載linux內核源碼工具
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- licheepi_zero_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
選中測試
Device Drivers <*>Memory Technology Device (MTD) support <*> Command line partition table parsing 該項目用來解析uboot傳遞過來的flash分區信息。 <*> SPI-NOR device Support File systems <*> Miscellaneous filesystems <*> Journalling Flash File System v2 (JFFS2) support
code arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts
&spi0 { status ="okay"; mx25l25635e:mx25l25635e@0 { compatible = "jedec,spi-nor"; reg = <0x0>; spi-max-frequency = <50000000>; #address-cells = <1>; #size-cells = <1>; }; };
編譯ui
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- dtbs 東西在在 arch/arm/boot/zImage
rootfs,之前弄過,直接用mkfs.jffs2生成文件系統了spa
sudo mkfs.jffs2 -s 0x100 -e 0x10000 -p 0x1AF0000 -d ~/downloads/rootfs/ -o ../jffs2.img
打包鏡像code
dd if=/dev/zero of=flashimg.bin bs=1M count=32 dd if=$HOME/dev/embedded/lichee/zero/SPI_Flash/u-boot/u-boot-sunxi-with-spl.bin of=flashimg.bin bs=1K conv=notrunc dd if=$HOME/dev/embedded/lichee/zero/SPI_Flash/linux-zero-4.13.y/arch/arm/boot/dts/sun8i-v3s-licheepi-zero-dock.dtb of=flashimg.bin bs=1K seek=1024 conv=notrunc dd if=$HOME/dev/embedded/lichee/zero/SPI_Flash/linux-zero-4.13.y/arch/arm/boot/zImage of=flashimg.bin bs=1K seek=1088 conv=notrunc dd if=$HOME/dev/embedded/lichee/zero/SPI_Flash/jffs2.img of=flashimg.bin bs=1K seek=5184 conv=notrunc
燒錄固件
git clone -b spi-rebase https://github.com/Icenowy/sunxi-tools.git
修復超過16M的寫入問題
code fel-spiflash.c,搜索
#define CMD_WRITE_ENABLE 0x06 和 aw_fel_spiflash_write_helper函數
改爲以下部分
#define CMD_WRITE_ENABLE 0x06 #define SPI_FLASH_16MB_BOUN 0x1000000 # define CMD_BANKADDR_BRWR 0x17 //only SPANSION flash use it # define CMD_BANKADDR_BRRD 0x16 # define CMD_EXTNADDR_WREAR 0xC5 # define CMD_EXTNADDR_RDEAR 0xC8 size_t bank_curr = 0; void aw_fel_spiflash_write_helper(feldev_handle *dev, uint32_t offset, void *buf, size_t len, size_t erase_size, uint8_t erase_cmd, size_t program_size, uint8_t program_cmd) { uint8_t *buf8 = (uint8_t *)buf; size_t max_chunk_size = dev->soc_info->scratch_addr - dev->soc_info->spl_addr; size_t cmd_idx, bank_sel; if (max_chunk_size > 0x1000) max_chunk_size = 0x1000; uint8_t *cmdbuf = malloc(max_chunk_size); cmd_idx = 0; prepare_spi_batch_data_transfer(dev, dev->soc_info->spl_addr); //add bank support { cmd_idx = 0; bank_sel = offset /SPI_FLASH_16MB_BOUN; if (bank_sel == bank_curr) goto bar_end; /* Emit write enable command */ cmdbuf[cmd_idx++] = 0; cmdbuf[cmd_idx++] = 1; cmdbuf[cmd_idx++] = CMD_WRITE_ENABLE; /* Emit write bank */ cmdbuf[cmd_idx++] = 0; cmdbuf[cmd_idx++] = 2; cmdbuf[cmd_idx++] = CMD_EXTNADDR_WREAR; cmdbuf[cmd_idx++] = offset >> 24; /* Emit wait for completion */ cmdbuf[cmd_idx++] = 0xFF; cmdbuf[cmd_idx++] = 0xFF; /* Emit the end marker */ cmdbuf[cmd_idx++] = 0; cmdbuf[cmd_idx++] = 0; aw_fel_write(dev, cmdbuf, dev->soc_info->spl_addr, cmd_idx); aw_fel_remotefunc_execute(dev, NULL); bar_end: bank_curr = bank_sel; } cmd_idx = 0; prepare_spi_batch_data_transfer(dev, dev->soc_info->spl_addr); while (len > 0) { while (len > 0 && max_chunk_size - cmd_idx > program_size + 64) { if (offset % erase_size == 0) { /* Emit write enable command */ cmdbuf[cmd_idx++] = 0; cmdbuf[cmd_idx++] = 1; cmdbuf[cmd_idx++] = CMD_WRITE_ENABLE; /* Emit erase command */ cmdbuf[cmd_idx++] = 0; cmdbuf[cmd_idx++] = 4; cmdbuf[cmd_idx++] = erase_cmd; cmdbuf[cmd_idx++] = offset >> 16; cmdbuf[cmd_idx++] = offset >> 8; cmdbuf[cmd_idx++] = offset; /* Emit wait for completion */ cmdbuf[cmd_idx++] = 0xFF; cmdbuf[cmd_idx++] = 0xFF; } /* Emit write enable command */ cmdbuf[cmd_idx++] = 0; cmdbuf[cmd_idx++] = 1; cmdbuf[cmd_idx++] = CMD_WRITE_ENABLE; /* Emit page program command */ size_t write_count = program_size; if (write_count > len) write_count = len; cmdbuf[cmd_idx++] = (4 + write_count) >> 8; cmdbuf[cmd_idx++] = 4 + write_count; cmdbuf[cmd_idx++] = program_cmd; cmdbuf[cmd_idx++] = offset >> 16; cmdbuf[cmd_idx++] = offset >> 8; cmdbuf[cmd_idx++] = offset; memcpy(cmdbuf + cmd_idx, buf8, write_count); cmd_idx += write_count; buf8 += write_count; len -= write_count; offset += write_count; /* Emit wait for completion */ cmdbuf[cmd_idx++] = 0xFF; cmdbuf[cmd_idx++] = 0xFF; } /* Emit the end marker */ cmdbuf[cmd_idx++] = 0; cmdbuf[cmd_idx++] = 0; /* Flush */ aw_fel_write(dev, cmdbuf, dev->soc_info->spl_addr, cmd_idx); aw_fel_remotefunc_execute(dev, NULL); cmd_idx = 0; } free(cmdbuf); }
make
燒錄
測試是否發現flash設備 sunxi-fel version sunxi-fel -p spiflash-write 0 ~/dev/embedded/lichee/zero/SPI_Flash/flashimg.bin
從新上電之後,是否是就看到串口有輸出啦