uboot移植——使用三星官方的uboot进行移植

时间:2022-05-21 16:34:58

以下内容源于朱有鹏嵌入式课程的学习,如有侵权,请告知删除。

参考资料:http://www.cnblogs.com/biaohc/p/6460902.html



总结的思维导图下载地址:https://pan.baidu.com/s/1nvilb6L

uboot移植——使用三星官方的uboot进行移植


uboot移植——使用三星官方的uboot进行移植



由于我们使用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开发板没有用到这个功能,所以程序卡在此函数中。只要把此函数注释掉即可。

uboot移植——使用三星官方的uboot进行移植 



3、uboot的版本号和时钟配置

输出如下:

uboot移植——使用三星官方的uboot进行移植

(1)开始打印U-BOOT的版本号,由display_banner 这个函数中实现。

  • 想要修改“for SMDKV210”这个信息,只需在smdkv210single.h中修改这个宏定义CFG_PROMPT即可。如下

uboot移植——使用三星官方的uboot进行移植


(2)时钟信息是对的。

  • 时钟信息是在print_cpuinfo这个函数中打印出来的。
  • 时钟部分的代码在lowlevel_init.S中的bl system_clock_init调用的函数中。
  • 函数的代码部分是没任何问题的,不需要改动。
  • 如果时钟部分要更改,关键是去更改头文件中的宏定义。
  • 三星移植时已经把210常用的各种时钟配置全都计算好用宏开关来控制了。只要打开相应的宏开关就能将系统配置为各种不同的频率。

(3)下面的信息是在checkboard函数中打印的

  • 如果要修改这个信息,可以在这个函数中修改。
  • 在board\samsung\smdkc110.c文件中

uboot移植——使用三星官方的uboot进行移植

uboot移植——使用三星官方的uboot进行移植


4、DDR的配置

下面所显示的信息是错误的

uboot移植——使用三星官方的uboot进行移植

首先,看一下原来的DRAM中的配置信息(在smdkv210single.h中进行配置):

uboot移植——使用三星官方的uboot进行移植

可知,这里有两块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:更改寄存器的值(可看做硬件配置部分的修改)

uboot移植——使用三星官方的uboot进行移植


(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移植——使用三星官方的uboot进行移植

  • 寄存器的值改了后相当于是硬件配置部分做了更改。但是uboot中DDR相关的一些,还在原来位置,所以要去更改。
  • 在include\configs\smdkv210single.h中,将#defineMEMORY_BASE_ADDRESS0x20000000 改为 #define    MEMORY_BASE_ADDRESS0x30000000


步骤3:虚拟地址映射表中相应修改

uboot移植——使用三星官方的uboot进行移植

(1)uboot中开启了MMU对内存进行了段式映射,有一张内存映射表。

(2)修改发生在lowlevel_init.S中的mmu_table标签这块内容里。

(2)经过实际分析,发现这个内存映射只是把20000000开始的256MB映射到C0000000开头的256MB。我们更改方法是将2改成3。


步骤4:修改虚拟地址到物理地址的映射函数

uboot移植——使用三星官方的uboot进行移植

  • 修改uboot/board/samsung/smdkc110/smdkc110.c中的virt_to_phy_smdkc110,将其中的20000000改为30000000即可。


5、SD卡版本号问题

uboot移植——使用三星官方的uboot进行移植

(1)从打印出来的错误信息中挑选一个关键词,然后去源代码中搜索这个关键词,通过这种搜索的方法定位问题。通过搜索将问题定位在drivers/mmc/mmc.c的818行。

(2)在下面这个函数中,读取版本号如果版本号>5的话打印下面信息,我们直接把5修改为8

uboot移植——使用三星官方的uboot进行移植

  • 这个函数是在读取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、背景知识

(1)uboot中提供了很多网卡芯片的驱动程序,所以uboot中是移植而不是编写。
(2)网卡驱动在uboot/drivers/net/dm9000x.c和dm9000x.h
  • 此驱动源于linux kernel源代码,可以在uboot中直接使用,无需更改。
(3)驱动本身具有可移植性
  • linux驱动设计中,数据和代码是分开的。
  • 这里的代码主要指uboot/drivers/net/dm9000x.c和dm9000x.h。
  • 而数据是由硬件开发板中的接法决定的,数据由一定的数据结构来提供。
  • 移植DM9000驱动时,dm9000x.c和h不需要改动,要动的是头文件的数据。

B、网卡移植的关键:初始化

(1)uboot在第二阶段init_sequences中进行了一系列的初始化,其中就有网卡芯片的初始化。
(2)只要将网卡芯片正确的初始化了,则网卡芯片就能工作(意思是网卡驱动dm9000x.c和dm9000x.h依赖于这里的初始化)。
(3)dm9000初始化的代码在start_armboot最开始初始化的一堆函数数组中的board_init函数中,其中调用的是dm9000_pre_init这个函数。

C、移植步骤

见博客http://blog.csdn.net/oqqhutu12345678/article/details/72547924


步骤1:三个寄存器的修改
uboot移植——使用三星官方的uboot进行移植

(1)从三星版本的代码中可以看出,它操作的是bit20-bit23,对照数据手册中寄存器定义,可以看出三星的开发板DM9000是接在Bank5上的。
  • 而我们接在bank1上的,因此我们需要操作的bit位是bit4-bit7。
(2)三个寄存器的修改,主要是因为三星的开发板DM9000接在bank5,而我们接在了bank1上,因此要做一些修改。


步骤2:基地址的配置(在smdkv210single.h中)
uboot移植——使用三星官方的uboot进行移植

(1)CONFIG_DM9000_BASE是DM9000网卡通过SROM bank映射到SoC中地址空间中的地址。
  • 这个地址的值取决于硬件接到哪个bank,这个bank的基地址是SoC自己定义好的。
  • 譬如我们这里接到了bank1上,bank1的基地址是0x88000000(但实际写的是0x88000300)。
(2)
  • DM9000_IO表示访问芯片IO的基地址,直接就是CONFIG_DM9000_BASE;
  • DM9000_DATA表示我们访问数据时的基地址,因为DM9000芯片的CMD引脚接到了ADDR2,因此这里要+4(0b100,对应ADDR2)
(3)0x300跟DM9000网卡芯片型号版本有关,是DM9000网卡本身的问题,其内部寄存器就有一个0x300的一个偏移量。