• 从三星官方uboot开始移植


    移植前的准备

    下载 android_uboot_smdkv210.tar.bz2 这个文件 

    开始移植

    本人使用的开发板是九鼎的 x210,在三星 uboot 的主 Makefile 中找到了类似的 smdkv210 的相关配置,因为这些配置都差不多,就随便选择了 smdkv210single_config
    在 make smdkv210single_config; make 执行之后进行 SD 卡烧录
    在烧录后发现,串口没有信息输出,但是开发板供电锁存成功
    开发板供电锁存是在 lowlevel_init.S 中进行的
    可以判定 lowlevel_init.S 中有问题,需要进行修改

    启动第一阶段

    在 lowlevel_init.S 中发现了一段代码对开发板上不存在的 PMIC 的初始化,在注释后串口成功打印 ‘OK’
     
    1 /* init PMIC chip */
    2  // bl PMIC_InitIp
    uboot 开始进入启动第二阶段,通过串口输出信息可以看出,虽然 uboot 启动成功,但是很多配置信息是错误的

    时钟配置

    系统时钟是通过 lowlevel_init.S 中的 system_clock_init 进行的
    由于三星在移植 uboot 时已经设置好系统时钟了,相关的时钟配置也都以宏的方式定义在 smdkv210single.h 文件中了
    所以时钟这一块不用自己操心

    ddr 配置

    在 uboot 启动信息中发现串口输出的信息中,DRAM 大小和开发板的不符合
    1 DRAM:    1 G
    smdkv210single.h 文件中找到 ddr 的相关的配置(471)
    将 ddr 的地址更改为 0x30000000 (改了可以让两个 ddr 的地址连续),更改 ddr 的大小
    1 #define CONFIG_NR_DRAM_BANKS    2          /* we have 2 bank of DRAM */
    2 //#define SDRAM_BANK_SIZE         0x20000000    /* 512 MB */
    3 #define SDRAM_BANK_SIZE         0x10000000    /* 256MB */
    4 #define PHYS_SDRAM_1            MEMORY_BASE_ADDRESS /* SDRAM Bank #1 */
    5 #define PHYS_SDRAM_1_SIZE       SDRAM_BANK_SIZE
    6 //#define PHYS_SDRAM_2            (MEMORY_BASE_ADDRESS + SDRAM_BANK_SIZE) /* SDRAM Bank #2 */
    7 #define PHYS_SDRAM_2          0x40000000
    8 #define PHYS_SDRAM_2_SIZE       SDRAM_BANK_SIZE
    #define MEMORY_BASE_ADDRESS 0x30000000 (71)
    然后是修改 ddr 的初始化参数(smdkv210single.h   411)
    1 // #define DMC0_MEMCONFIG_0 0x20E01323 // MemConfig0 256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
    2 #define DMC0_MEMCONFIG_0 0x30F01323 // MemConfig0 256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed

    ddr 的相关寄存器配置可以参考 S5PV210_UM_REV1.1.pdf
    从图中可以看到,

     [31:24] 控制 AXI 基地址,因为我们设置 ddr 的基地址为 0x30000000 ,所以这里设置为 0x30。

    [23:16] 控制 AXI 基地址掩码,置1时有效,可以使基地址范围变为 0x3000_0000 ~ 0x37FF_FFFF,所以这里设置为 0xF0

    修改虚拟地址到物理地址的映射
    修改 board/samsung/smdkc110/smdkc110.c 的 virt_to_phy_smdkc110 函数  (187)
    1 ulong virt_to_phy_smdkc110(ulong addr)
    2 {
    3     if ((0xc0000000 <= addr) && (addr < 0xd0000000))
    4         // return (addr - 0xc0000000 + 0x20000000);
    5         return (addr - 0xc0000000 + 0x30000000);
    6     ...
    7 }

    smdkv210single.h   522)

    1 #ifdef CONFIG_ENABLE_MMU
    2 #define CFG_UBOOT_BASE        0xc3e00000
    3 #else
    4 #define CFG_UBOOT_BASE        0x33e00000
    5 #endif

    SD/MMC 配置
    在 uboot 打印信息中看不到 SD/MMC 的大小,报下面的错误
     
    1 unrecognised EXT_CSD structure version 7
    通过报错信息的搜索,可以将问题定位到 drivers/mmc/mmc.c 中  (817)
    1 if (ext_csd_struct > 8) {
    2         printf("unrecognised EXT_CSD structure "
    3             "version %d
    ", ext_csd_struct);
    4         err = -1;
    5         goto out;
    6     }

    将原先的判断 version 的版本改大点就可以了

    控制台串口更换为串口0  (smdkv210single.h   148)

    1 #define CONFIG_SERIAL3          1    /* we use UART2 on SMDKC110 */
    2 //#define CONFIG_SERIAL1          1    /* we use UART0 on SMDKC110 */

     

    修改默认网络地址设置  (smdkv210single.h   216)

    1 #define CONFIG_ETHADDR        00:40:5c:26:0a:5b
    2 #define CONFIG_NETMASK          255.255.255.0
    3 #define CONFIG_IPADDR        192.168.1.20
    4 #define CONFIG_SERVERIP        192.168.1.141
    5 #define CONFIG_GATEWAYIP    192.168.1.1
    使用mmc write 0 30000000 11# 32
     

    修改行提示符  (smdkv210single.h   249)

    1 #define CFG_PROMPT              "ZYJ210 # "   /* Monitor Command Prompt       */

    网卡芯片配置

    开发板使用的网卡芯片为 DM9000 ,通过总线结构与开发板 SOC 相连,通过 SOC 的 SROM 控制器进行控制
    这样的好处是可以直接通过地址访问网卡芯片内部的寄存器。访问方式是通过网卡芯片的基地址加上网卡芯片内部寄存器的偏移地址完成的

    通过原理图观察可以知道 DM9000 与 SOC 之间通信的总线是 16 位的。 DM9000 的 CMD 引脚接到了 SOC 的 ADDR2 上, DM9000 数据命令总线复用,通过 CMD 进行判断是数据还是命令
    CS 片选引脚接到了 SOC 的 CSn1 上,代表者使用的是 SROM bank1,因此 DM9000 的总线基地址为 0x88000000
    我们需要做的配置也就是初始化网卡而已,驱动都是统一的

    定位到板级初始化代码 board/samsung/smdkc110/smdkc110.c 中
    dm9000_pre_init 进行了 DM9000 的初始化
     
     1 static void dm9000_pre_init(void)
     2 {
     3     unsigned int tmp;
     4 
     5 #if defined(DM9000_16BIT_DATA)//工作在16模式下
     6     //SROM_BW_REG &= ~(0xf << 20);//
     7     //SROM_BW_REG |= (0<<23) | (0<<22) | (0<<21) | (1<<20);
     8 
     9       SROM_BW_REG &= ~(0xf << 4);//修改
    10     SROM_BW_REG |= (1<<7) | (1<<6) | (1<<5) | (1<<4);
    11 
    12 #else    
    13     SROM_BW_REG &= ~(0xf << 20);
    14     SROM_BW_REG |= (0<<19) | (0<<18) | (0<<16);
    15 #endif
    16     //SROM_BC5_REG = ((0<<28)|(1<<24)|(5<<16)|(1<<12)|(4<<8)|(6<<4)|(0<<0));
    17     SROM_BC1_REG = ((0<<28)|(1<<24)|(5<<16)|(1<<12)|(4<<8)|(6<<4)|(0<<0));
    18 
    19     tmp = MP01CON_REG;
    20     tmp &=~(0xf<<20);
    21     tmp |=(2<<20);
    22     MP01CON_REG = tmp;
    23 }
    上面的代码就是按照板上具体情况配置,下面两个图是上面修改的寄存器的信息

    基地址的配置
     1 #ifdef CONFIG_DRIVER_DM9000
     2 //#define CONFIG_DM9000_BASE        (0xA8000000)
     3 #define CONFIG_DM9000_BASE        (0x88000300)
     4 #define DM9000_IO            (CONFIG_DM9000_BASE)
     5 #if defined(DM9000_16BIT_DATA)
     6 //#define DM9000_DATA            (CONFIG_DM9000_BASE+2)
     7 #define DM9000_DATA            (CONFIG_DM9000_BASE+4)//4代表0100,正好代表ADDR2
     8 #else
     9 #define DM9000_DATA            (CONFIG_DM9000_BASE+1)
    10 #endif
     
    上面也有提到,不同的 SROM BANK ,它们的基地址都是不同的,这里需要配置
    之所以这里的基地址需要增加一个 0x300 的偏移,看到朱有鹏老师说可能是新版的 DM9000C 内部寄存器存在 0x300 的偏移
    移植到此结束
     

    ————————————————
    版权声明:本文为CSDN博主「greedyhao」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

    原文链接:https://blog.csdn.net/juhou/article/details/93376812
  • 相关阅读:
    vue之下拉菜单Dropdown的使用
    elinput输入框的readonly属性
    通过CollectionUtils工具类判断集合是否为空,通过StringUtils工具类判断字符串是否为空
    前端与后端之间参数的传递与接收和@RequestBody,@Requestparam,@Param三个注解的使用
    为什么数据库能查出两条id相同的数据
    js中函数调用时,对参数个数和类型没有要求
    避免创建不需要的对象,消除过期对象的引用
    避免使用终结方法
    避免使用终结方法
    快速排序
  • 原文地址:https://www.cnblogs.com/zyj23/p/12340481.html
Copyright © 2020-2023  润新知