Chinaunix首页 | 论坛 | 博客
  • 博客访问: 805533
  • 博文数量: 281
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2770
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-02 19:45
个人简介

邮箱:zhuimengcanyang@163.com 痴爱嵌入式技术的蜗牛

文章分类
文章存档

2020年(1)

2018年(1)

2017年(56)

2016年(72)

2015年(151)

分类: 嵌入式

2016-12-11 20:56:00

1. 编译出现问题:
    fs/yaffs2/libyaffs2.o: In function `yaffs_StartUp':
    /work/system/u-boot-2012.04.01/fs/yaffs2/yaffscfg.c:210: undefined reference to `nand_info'
    make: *** [u-boot] Error 1

参考解决办法:
    http://blog.csdn.net/sinat_24088685/article/details/51723681?locationNum=4&fps=1
    http://blog.csdn.net/comwise/article/details/14111125
    屏蔽后,要重新输入命令:
    make distclean
    make smdk2440_config && make


2. 查找"pie"的文件:
    $ grep "\-pie" * -nR
    arch/arm/config.mk:75:LDFLAGS_u-boot += -pie
    
    "\"表示后面的“-”是起作用的。
    
3. 生成反汇编文件:
    arm-linux-objdump -D u-boot > u-boot.dis


5. 初始化SDRAM时,为什么用:
    adr r1, sdram_config     /* sdram_config的当前地址 */
    而不用:
    ldr r1, =sdram_config    

回答:
    这是因为:用ldr伪指令,可能会将sdram_config的值保存在内存的某个地址,而需要去读该内存地址来获取sdram_config的值。
    而这个时候,内存控制器正在设置,所以不可能成功。

6. 问题:
    为什么重定位的时候BSS段不拷贝过去?如果在SDRAM中调用这些BSS段定义的变量或者地址,不是需要在SDRAM进行地址的转换吗?
    就跟新的u-boot的做法一样,需要地址转换啊。
    比如,在bss段中有个变量的地址是0x100,那如果在SDRAM中引用这个变量不是需要地址转换吗?这样不是必须得拷贝这个变量过去吗??

回答:
    在自己移植的bootloader程序中,链接地址为内存的某个固定地址。
    清除BSS段,其实就相当于清除了内存中BSS段的部分。
    在设置好了内存控制器之后,才清除BSS段,这个时候BSS段链接地址的内存是可以读写的。
    所以是可以清除BSS段。
    
    而新的u-boot是因为链接地址是从0地址开始,所以必须将u-boot的BSS的段也的拷贝到内存当中,并且修改相应的地址。
    

    
====================================
移植u-boot之修改代码支持norFlash-3.3
参考博客:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=22072065&id=5121157
3.3.1 发现错误:
    从NOR FLASH启动U-BOOT:
    U-Boot 2012.04.01 (Jul 13 2015 - 20:33:34)

    CPUID: 32440001
    FCLK:      400 MHz
    HCLK:      100 MHz
    PCLK:       50 MHz
    DRAM:  64 MiB
    WARNING: Caches not enabled
    Flash: *** failed ***
    ### ERROR ### Please RESET the board ###
    
    在source insight中搜索"Flash:":
        Board.c (arch\arm\lib):    puts("Flash: ");
    分析流程:
        第二阶段启动代码:
        void board_init_r(gd_t *id, ulong dest_addr)
            puts("Flash: ");
            flash_size = flash_init();
            if (flash_size > 0) {
                ......
            } else {
                puts(failed);  
                hang(); // 程序死循环在这个地方,说明没有probe出NOR FLASH.
                    puts("### ERROR ### Please RESET the board ###\n");
                    for (;;);
            }
            
    分析NOR flash的probe函数:
        flash_init        \drivers\mtd\cfi_flash.c
            flash_info[0].flash_id = FLASH_UNKNOWN;
            
            if (!flash_detect_legacy(cfi_flash_bank_addr(i), i))    //老式的方法来检查NOR FLASH.
                        board_flash_get_legacy(base, banknum, info)
                        flash_read_jedec_ids(info);
                        jedec_flash_match(info, info->start[0])
                            // 在匹配比较函数中,构造了一个jedec_table[]数组结构,在该结构中存储了一系列的NOR FLASH的信息
                            // 如果找到有一个子项的制造商ID和设备ID匹配,则将该结构体填充,并返回,表示找到匹配的NOR flash。
                            for (i = 0; i < ARRAY_SIZE(jedec_table); i++) {
                                if ((jedec_table[i].mfr_id & mask) == (info->manufacturer_id & mask) &&
                                    (jedec_table[i].dev_id & mask) == (info->device_id & mask)) {
                                    fill_info(info, &jedec_table[i], base);
                                    ret = 1;
                                    break;
                                }
                            }
                // 下面的代码不执行        
                flash_get_size(cfi_flash_bank_addr(i), i);
                
    修改:
        所以主要看这个表jedec_table[],把我们开发板上用到的NOR FLASH信息添加到该表中。
            static const struct amd_flash_info jedec_table[]         
                
    NOR FLASH:
        可以像内存一样去读某个地址的数据,但是读的厂商ID和设备ID,需要先向NOR发送解锁命令
        阅读手册:
        a. 如果读取 Manifacture ID,步骤为:(16位总线宽度)
        (1)向地址为 555 的地方发送数据为 AA
        (2)向地址为 2AA 的地方发送数据为 55
        (3)向地址为 555 的地方发送数据为 90
        (4)读取地址为x00 的地方,返回的为:C2H,为厂家ID。
        前面两个命令:0xaa, 0x55就是解锁命令。后面的0x90表示读取厂家ID命令,最后表示真正的读取命令。
        
        但是写操作,需要满足一些复杂的时序。
        
    NOR flash型号:MX29LV160DB - 2M
    添加信息:
        {
            .mfr_id     = (u16)MX_MANUFACT,          // 厂家ID
            .dev_id     = 0x2249,                    // 这是设备ID,看手册知道
            .name       = "MXIC MX29LV160DB",        // 名字无所谓
            .uaddr      = {                          // nor flash看到的解锁地址,注意:在硬件连线上是板子的A1接到nor的A0口线上的。
            
                // [0] = MTD_UADDR_0x0555_0x02AA     // [0]下标为"0",表示数据位宽为8位
                [1] = MTD_UADDR_0x0555_0x02AA        // [1]下标为"1",表示数据位宽为16位,因为我们的板子是16位宽度来和NOR FLASH通讯   
        },
        .DevSize    = SIZE_2MiB,                // NOR FLASH总的大小为:2MB,博客上记录有误。
        .CmdSet     = P_ID_AMD_STD,             // 指令集
 
        // 擦除区域个数是指不同分区结构的个数。比如MT29LV160DB 有16K X1, 8KX2, 32KX1, 64K X 31,所以有四个不同的擦除区域结构
        //.NumEraseRegions= 1,
        //.regions    = {
        //     ERASEINFO(0x10000, 8),
            修改为:
            
        .NumEraseRegions= 4,        // 根据手册来进行配置
        .regions    = {
            ERASEINFO(16*1024,  1),     
            ERASEINFO(8*1024,   2),  
            ERASEINFO(32*1024*, 1),  
            ERASEINFO(64*1024, 31),  
        }
    },

    
3.3.2 NOR FLASH测试:
    u-boot本身的大小(不包括BSS段)大概512k左右,从nor flash上的零地址处开始存放,这里擦除512k(512k = 80000)之后nor进行试验。
    注意:当链接地址改到SDRAM中后,在NOR flash中是不需要存储BSS段的,只是在编译u-boot.bin时,会根据链接文件生成BSS
    段的起始地址和结束地址,这样就可以在跳转到SDRAM运行之前,先清除BSS段。
    
=====================================
移植u-boot之修改代码支持NandFlash-3.4
    在前面的章节,板子支持NAND FLASH启动,但是并不代表可以对NAND FLASH进行读写等操作。
    所以要修改代码,进行对nand flash的支持。
    
注意:
    从NOR启动,是可以看到NAND的大小的;
    而从NAND启动,是没法知道NOR的大小,这是因为从NAND启动时,0地址对于的是内部的SRAM,无法访问到NOR FLASH.
    

====================
问题:
修改时钟,初始化串口,编译出现问题:
/work/system/u-boot-2012.04.01/fs/yaffs2/yaffscfg.c:210: undefined reference to `nand_info'
make: *** [u-boot] Error 1    

回答:
参考网站:http://blog.csdn.net/sinat_24088685/article/details/51723681?locationNum=4&fps=1
找到配置的宏;
$ vi fs/yaffs2/Makefile
    COBJS-$(CONFIG_YAFFS2) := \
            yaffscfg.o yaffs_ecc.o yaffsfs.o yaffs_guts.o yaffs_packedtags1.o \
            yaffs_tagscompat.o yaffs_packedtags2.o yaffs_tagsvalidity.o \
            yaffs_nand.o yaffs_checkptrw.o yaffs_qsort.o yaffs_mtdif.o \
            yaffs_mtdif2.o
在配置文件:\include\configs\smdk2440.h
注销宏定义:CONFIG_YAFFS2
重新编译,注意要先:
$ make distclean
然后重新配置,编译:
$ make smdk2440_config
$ make


====================================
移植u-boot之修改代码支持norFlash-3.3

测试还未做。

支持NOR,测试:
flinfo
protect off all
erase 80000 8ffff
cp.b 30000000 80000 10000
md.b 30000000
md.b 80000   
cmp.b 30000000 80000 10000
比较发现有一处不相同:
byte at 0x30000b78 (0x01) != byte at 0x00080b78 (0x09)
Total of 2936 bytes were the same

在高地址处,拷贝数据进行比较;
erase 80000 8ffff         
cp.b 32000000 80000 10000
cmp.b 32000000 80000 10000
比较发现完全相同:Total of 65536 bytes were the same

分析原因:


利用超级终端的loady模式下载u-boot.bin文件到nor flash中
1. 查看loady命令:help loady
2. loady 32000000
    然后将u-boot.bin文件通过超级终端发送到SDRAM中
3. protect off all
    解除NOR的软件保护
4. erase 0 7ffff
    擦除NOR的前512K空间大小,用来装载uboot.bin文件
5. cp.b 32000000 0 80000
    从SDRAM的地址32000000处拷贝512K的大小到NOR中。
    
    
=======================================
移植u-boot之修改代码支持NAND FLASH -3.4
NAND检测流程分析:
void board_init_r(gd_t *id, ulong dest_addr)
    puts("NAND:  ");
    nand_init();        /* go init the NAND */
        nand_init_chip(1);
            struct mtd_info *mtd = &nand_info[i];
            struct nand_chip *nand = &nand_chip[i];
            ulong base_addr = base_address[i];
            int maxchips = CONFIG_SYS_NAND_MAX_CHIPS;
            
            mtd->priv = nand;
            nand->IO_ADDR_R = nand->IO_ADDR_W = (void  __iomem *)base_addr;
            
            board_nand_init
                //
                struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
                struct s3c2410_nand *nand_reg = s3c2410_get_base_nand();    
                
                
#define CONFIG_SYS_NAND_BASE_LIST 0x4E000000
nand_info_t nand_info[1];
static struct nand_chip nand_chip[1];
static ulong base_address[1] = CONFIG_SYS_NAND_BASE_LIST = 0x4E000000; // 0x4E000000就是NAND FLASH的配置寄存器地址
    
    
======================================
移植u-boot之修改代码支持DM9000网卡-3.5
初始化流程:
    void board_init_r(gd_t *id, ulong dest_addr)
        eth_initialize(gd->bd);
            board_eth_init(bd_t *bis)
                // 源码中只是初始化了CS8900网卡芯片
                rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
                // 改为:初始化DM9000
                rc = dm9000_initialize(bis);



============================================                
移植u-boot之修改代码之裁剪和修改默认参数-4.1

输入help命令,可以查看uboot现在支持的命令:
SMDK2410 # help
?       - alias for 'help'
base    - print or set address offset
bdinfo  - print Board Info structure
boot    - boot default, i.e., run 'bootcmd'
bootd   - boot default, i.e., run 'bootcmd'
bootelf - Boot from an ELF image in memory
bootm   - boot application image from memory
bootp   - boot image via network using BOOTP/TFTP protocol
bootvx  - Boot vxWorks from an ELF image
chpart  - change active partition
cmp     - memory compare
coninfo - print console devices and information
cp      - memory copy
crc32   - checksum calculation
date    - get/set/reset date & time
dcache  - enable or disable data cache
dhcp    - boot image via network using DHCP/TFTP protocol
echo    - echo args to console
editenv - edit environment variable
env     - environment handling commands
erase   - erase FLASH memory
exit    - exit script
ext2load- load binary file from a Ext2 filesystem
ext2ls  - list files in a directory (default /)
false   - do nothing, unsuccessfully
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls   - list files in a directory (default /)
flinfo  - print FLASH memory information
go      - start application at address 'addr'
help    - print command description/usage
icache  - enable or disable instruction cache
iminfo  - print header information for application image
imls    - list all images found in flash
imxtract- extract a part of a multi-image
itest   - return true/false on integer compare
loadb   - load binary file over serial line (kermit mode)
loads   - load S-Record file over serial line
loady   - load binary file over serial line (ymodem mode)
loop    - infinite loop on address range
md      - memory display
mm      - memory modify (auto-incrementing address)
mtdparts- define flash/nand partitions
mtest   - simple RAM read/write test
mw      - memory write (fill)
nand    - NAND sub-system
nboot   - boot from NAND device
nfs     - boot image via network using NFS protocol
nm      - memory modify (constant address)
ping    - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
protect - enable or disable FLASH write protection
reginfo - print register information
reset   - Perform RESET of the CPU
run     - run commands in an environment variable
saveenv - save environment variables to persistent storage
setenv  - set environment variables
showvar - print local hushshell variables
sleep   - delay execution for some time
source  - run script from memory
test    - minimal test like /bin/sh
tftpboot- boot image via network using TFTP protocol
true    - do nothing, successfully
ubi     - ubi commands
ubifsload- load file from an UBIFS filesystem
ubifsls - list files in a directory
ubifsmount- mount UBIFS volume
ubifsumount- unmount UBIFS volume
usb     - USB sub-system
usbboot - boot from USB device
version - print monitor, compiler and linker version

可以查看源代码:发现这些命令都是以U_BOOT_CMD定义的结构体,
这个结构体在文件:\include\command.h中定义
#define U_BOOT_CMD_MKENT_COMPLETE(name,maxargs,rep,cmd,usage,help,comp) \
    {#name, maxargs, rep, cmd, usage, _CMD_HELP(help) _CMD_COMPLETE(comp)}

#define U_BOOT_CMD_MKENT(name,maxargs,rep,cmd,usage,help) \
    U_BOOT_CMD_MKENT_COMPLETE(name,maxargs,rep,cmd,usage,help,NULL)

#define U_BOOT_CMD_COMPLETE(name,maxargs,rep,cmd,usage,help,comp) \
    cmd_tbl_t __u_boot_cmd_##name Struct_Section = \
        U_BOOT_CMD_MKENT_COMPLETE(name,maxargs,rep,cmd,usage,help,comp)

#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
    U_BOOT_CMD_COMPLETE(name,maxargs,rep,cmd,usage,help,NULL)

比如命令: do_flinfo
U_BOOT_CMD(
    flinfo,    2,    1,    do_flinfo,
    "print FLASH memory information",
    "\n    - print information for all FLASH memory banks\n"
    "flinfo N\n    - print information for FLASH memory bank # N"
);
其他的命令都是类似的方式,在源码中进行了定义。

在配置文件中,进行命令的裁剪,因为不是每个命令都需要,裁剪后可以减小编译出来的u-boot.bin文件的大小。
配置文件: ./include/configs/smdk2440.h

利用uboot工具的tftp功能更新u-boot.bin到NOR中,必须NOR启动,才能更新NOR。
否则如果是从NAND启动,根本就检测不到NOR,也就没法将编译好的uboot镜像文件更新到NOR中。
set ipaddr 192.168.1.50
set ethaddr 00:0c:29:2f:4e:70
set serverip 192.168.1.100

更新uboot到NOR:
tftp 30000000 u-boot_new.bin; protect off all; erase 0 3ffff; cp.b 30000000 0 40000
tftp 30000000 u-boot_1.1.6.bin; protect off all; erase 0 3ffff; cp.b 30000000 0 40000


更新kernel
tftp 30000000 uImage; nand erase.part kernel; nand write 30000000 kernel

修改启动参数:
set bootcmd 'nand read 30000000 kernel; bootm 30000000'
save

易用性修改:

#define MTDPARTS_DEFAULT    "mtdparts=jz2440-0:256k(u-boot),"    \
                            "128k(params),"                      \
                            "2m(kernel),"                        \
                            "-(rootfs)"   /* "-" 表示剩余的部分 */
                            
打印分区信息:
device nand0 , # parts = 4
 #: name                size            offset          mask_flags
 0: u-boot              0x00040000      0x00000000      0
 1: params              0x00020000      0x00040000      0
 2: kernel              0x00200000      0x00060000      0
 3: rootfs              0x0fda0000      0x00260000      0

active partition: nand0,0 - (u-boot) 0x00040000 @ 0x00000000

defaults:
mtdids  : nand0=jz2440-0
mtdparts: mtdparts=jz2440-0:256k(u-boot),128k(params),2m(kernel),-(rootfs)

===========================================
移植u-boot之支持烧写yaffs映象及制作补丁-4.2

下载jffs2文件系统;
tftp 30000000 fs_mini_mdev.jffs2; nand erase.part rootfs; nand write.jffs2 30000000 0x00260000 5b89a8

修改启动参数,挂接jffs2文件系统:
set bootargs console=ttySAC0 root=/dev/mtdblock3 rootfstype=jffs2; save


烧写yaffs:
tftp 30000000 fs_mini_mdev.yaffs2; nand erase.part rootfs; nand write.yaffs 30000000 260000  889bc0

tftp 30000000 fs_mini.yaffs2; nand erase.part rootfs; nand write.yaffs 30000000 260000 8607c0
修改启动参数,挂接yaffs文件系统:
set bootargs console=ttySAC0,115200 root=/dev/mtdblock3

setenv bootargs console=ttySAC0 noinitrd root=/dev/mtdblock3 init=/linuxrc
save

阅读(1032) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~