以下内容源于朱有鹏嵌入式课程的学习,如有侵权,请告知删除。
参考资料:http://www.cnblogs.com/biaohc/p/6460902.html
总结的思维导图下载地址:https://pan.baidu.com/s/1nvilb6L
由于我们使用210的cpu,因此选择三星的210开发板的配置。
1、删除无关的文件
在开始移植之前我们首先要把不相关的cpu、board、lib目录删除:
(1)board目录下:把不相关的开发板的文件全部删除只保留:board->samsung->common文件夹以及board->samsung->smdkc110文件夹;
- 每个文件夹代表一个开发板。
(2)cpu目录下:只保留s5pc11x文件夹,其他全部删除;
(3)include目录下:asm-开头的文件只保留asm-arm;asm-arm目录下arch-开头的文件只保留s5pc11x;
(4)include/configs目录下:只保留smdkv210single.h文件;每一个开发板对应一个.h文件。
(5) lib_ 开头的文件夹保留lib_arm、lib_generic 。
然后在用sourceinsight生成project。
2、直接编译三星移植版uboot尝试运行
(1)在uboot根目录下进行配置make smdkv210single_config(对应include/configs/smdkv210single.h头文件),然后make,生成uboot.bin文件。
(2)把生成的uboot.bin文件烧录到sd卡中。
- 首先注意的是烧写时要在uboot根目录下,烧写命令:./sd_fusing.sh /dev/sdb;
- 注意sd_fusing脚本中,烧写的内容是不是uboot.bin、uboot.bin的路径对不对,..在此表示 ~/uboot/;
- 利用file mkbl1查看mkbl1是不是32bit的,如果不是,则需要在sd_fusing目录下执行make clean,然后再make。
- sd_fusing.sh文件中,/mkbl1 ../u-boot.bin SD-bl1-8k.bin 8192表示将uboot的前8k复制到SD-bl1-8k.bin文件中;
- 执行此sd_fusing.sh脚本即可把bl1、uboot.bin烧录到sd卡中。
(3)启动开发板,发现电源置锁,只有一句SD checksum Error,没有打印出ok。
- 分析:uboot中串口最早的输出“OK”,在lowlevel_init.S中初始化串口时打印出来的;串口无输出"O"说明在打印"O"之前代码已经死掉了;开发板供电锁存在lowlevel_init.S中,开发板供电锁存成功说明这个代码之前的部分是没问题的。
- 结论:错误发生在开发板供电锁存代码和串口初始化打印"O"代码。
- 在lowlevel_ini t函数中,PMIC_InitIp函数是用来管理电源的。由于210开发板没有用到这个功能,所以程序卡在此函数中。只要把此函数注释掉即可。
3、uboot的版本号和时钟配置
输出如下:
(1)开始打印U-BOOT的版本号,由display_banner 这个函数中实现。
- 想要修改“for SMDKV210”这个信息,只需在smdkv210single.h中修改这个宏定义CFG_PROMPT即可。如下
(2)时钟信息是对的。
- 时钟信息是在print_cpuinfo这个函数中打印出来的。
- 时钟部分的代码在lowlevel_init.S中的bl system_clock_init调用的函数中。
- 函数的代码部分是没任何问题的,不需要改动。
- 如果时钟部分要更改,关键是去更改头文件中的宏定义。
- 三星移植时已经把210常用的各种时钟配置全都计算好用宏开关来控制了。只要打开相应的宏开关就能将系统配置为各种不同的频率。
(3)下面的信息是在checkboard函数中打印的
- 如果要修改这个信息,可以在这个函数中修改。
- 在board\samsung\smdkc110.c文件中
4、DDR的配置
下面所显示的信息是错误的
首先,看一下原来的DRAM中的配置信息(在smdkv210single.h中进行配置):
可知,这里有两块DRAM,大小均为512M(故总显示为1GB),但实际我们x210开发板只有512MB。
因此修改如下:#define SDRAM_BANK_SIZE 0x10000000 /* 256 MB */
其次,DRAM0和DRAM1的地址,分别为0x20000000~0x2FFFFFFF(256MB),0x40000000~0x4FFFFFFF(256MB)。
我们希望起始内存的地址为0x3000_0000~0x4FFF_FFFF,因此需要DDR地址另外配置。
步骤1:更改寄存器的值(可看做硬件配置部分的修改)
(1)根据裸机中DDR初始化部分的课程,和uboot中DDR初始化部分的代码的课程,得出结论
- DDR的初始化代码部分是在lowlevel_init.S中写的,是不动的,代码部分就是对相应寄存器做相应值的初始化;
- 要动的是值,而uboot为了具有可移植性把值都宏定义在include/configs/xxx.h中了。
- 因此我们只需要去这个配置头文件中更改配置值即可。
(2)#define DMC0_MEMCONFIG_00x20E01323 改为:#define DMC0_MEMCONFIG_00x30E01323
- 实际发现还是运行不了,需要改为 #define DMC0_MEMCONFIG_00x30F01323
步骤2:软件配置值更改
- 寄存器的值改了后相当于是硬件配置部分做了更改。但是uboot中DDR相关的一些,还在原来位置,所以要去更改。
- 在include\configs\smdkv210single.h中,将#defineMEMORY_BASE_ADDRESS0x20000000 改为 #define MEMORY_BASE_ADDRESS0x30000000。
步骤3:虚拟地址映射表中相应修改
(1)uboot中开启了MMU对内存进行了段式映射,有一张内存映射表。
(2)修改发生在lowlevel_init.S中的mmu_table标签这块内容里。
(2)经过实际分析,发现这个内存映射只是把20000000开始的256MB映射到C0000000开头的256MB。我们更改方法是将2改成3。
步骤4:修改虚拟地址到物理地址的映射函数
- 修改uboot/board/samsung/smdkc110/smdkc110.c中的virt_to_phy_smdkc110,将其中的20000000改为30000000即可。
5、SD卡版本号问题
(1)从打印出来的错误信息中挑选一个关键词,然后去源代码中搜索这个关键词,通过这种搜索的方法定位问题。通过搜索将问题定位在drivers/mmc/mmc.c的818行。
(2)在下面这个函数中,读取版本号如果版本号>5的话打印下面信息,我们直接把5修改为8。
- 这个函数是在读取SD/iNand的ext_csd寄存器的值。通过浏览代码结合出错地方,可以判断出:从sd卡中读取ext_csd寄存器是成功的,并且从读取结果中拿到了SD卡的版本号信息。然后代码对版本号进行了判断,并且如果版本号大于5就会报错并且函数错误退出。这就是问题所正。
- 当前板子上有一个iNand接在SD0上,有一个外置SD卡接在SD2上,那uboot中初始化的是iNand而不是SD卡。
- 也就是说uboot中实际用的是SD0而不是SD2。因为find_mmc_device(0),这里的0指的是SD0,可以改为1。
- 使用外置SD卡时,这个版本号的问题不会出现。从这里可以推测出SD卡和iNand的区别,SD卡版本低,iNand的版本比较高。
6、网卡驱动的移植
A、背景知识
- 此驱动源于linux kernel源代码,可以在uboot中直接使用,无需更改。
- linux驱动设计中,数据和代码是分开的。
- 这里的代码主要指uboot/drivers/net/dm9000x.c和dm9000x.h。
- 而数据是由硬件开发板中的接法决定的,数据由一定的数据结构来提供。
-
移植DM9000驱动时,dm9000x.c和h不需要改动,要动的是头文件的数据。
B、网卡移植的关键:初始化
C、移植步骤
见博客http://blog.csdn.net/oqqhutu12345678/article/details/72547924
- 而我们接在bank1上的,因此我们需要操作的bit位是bit4-bit7。
- 这个地址的值取决于硬件接到哪个bank,这个bank的基地址是SoC自己定义好的。
- 譬如我们这里接到了bank1上,bank1的基地址是0x88000000(但实际写的是0x88000300)。
- DM9000_IO表示访问芯片IO的基地址,直接就是CONFIG_DM9000_BASE;
- DM9000_DATA表示我们访问数据时的基地址,因为DM9000芯片的CMD引脚接到了ADDR2,因此这里要+4(0b100,对应ADDR2)