JZ2440的uboot-2009-11移植<2>_串口输出

整理下自己之前的移植uboot时记录的笔记!这个章节是对uboot的第一阶段的代码进行优化和代码的修改,使其可以正确的启动串口。

修改启动代码

  • 在上个章节,当我们编译完成之后会发现在根目录下面会有一个u-boot.lds的文件,这是链接文件,这个文件就在 u-boot-2016.09/arch/arm/cpu/u-boot.lds

  • 进去之后发现,板子启动执行的第一个文件是start.S,代码流程

    第一阶段启动代码修改

    • 设置cpu为SVC32 模式

    • 关闭看门狗

    • 屏蔽中断,这个地方我们需要添加对2440的支持,

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10

      #if defined(CONFIG_S3C2410)
      ldr r1, =0x3ff
      ldr r0, =INTSUBMSK
      str r1, [r0]
      添加:
      #elif defined(CONFIG_S3C2440)
      ldr r1, =0x7fff
      ldr r0, =INTSUBMSK
      str r1, [r0]
    • 设置系统时钟,查看S3C2440的数据手册可以,FCLK:HCLK:PCLK=1:4:8,FCLK=405Mhz

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      修改如下:
      ldr r0, =CLKDIVN
      mov r1, #5
      str r1, [r0]
      /**配置为异步模式**/
      mrc p15, 0, r1, c1, c0, 0
      orr r1, r1, #0xc0000000
      mcr p15, 0, r1, c1, c0, 0
      #define S3C2440_MPLL_400MHZ ((0x7f<<12)|(0x02<<4)|(0x01))/*
      ldr r0, =0x4c000004
      ldr r1, =S3C2440_MPLL_400MHZ
      str r1, [r0]
    • 跳转到cpu_init_crit,关闭MMU,关闭I/D caches ,再进入lowlevel_init

    • lowlevel_init,这个是配置Memory控制器。 在u-boot-2016.09/board/samsung/myff2440/lowlevel_init.S

      1
      2
      3
      4
      5
      上面我们修改了系统时钟的分频系数,所以此时的存储器控制器的SDRAM的刷新周期也需要更改,查数据手册,可知

      #define REFCNT 1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*6.) */
      修改为:
      #define REFCNT 1269 /* period=7.8us, HCLK=100Mhz, (2048+1-7.8*100) */

    • 然后进入 _main分支,也就是对第二阶段板子外设的设置, 位于uboot2016.9\ubootproject\u-boot-2016.09\arch\arm\lib\crt0.S

    系统时钟移植

    添加s3c2440配置的宏

    1
    2
    3
    4
    5
    6
    7
    进入include/configs/myff2440.h
    将:
    #define CONFIG_S3C2440 /* specifically a SAMSUNG S3C2410 SoC */
    #define CONFIG_MYFF2440 /* on a SAMSUNG SMDK2410 Board */
    修改为:
    #define CONFIG_S3C2440 /* specifically a SAMSUNG S3C2410 SoC */
    #define CONFIG_MYFF2440 /* on a SAMSUNG SMDK2410 Board */

    修改分频系数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    进入uboot2016.9\ubootproject\u-boot-2016.09\board\samsung\myff2440\Myff2440.c
    将:
    #define FCLK_SPEED 1

    #if (FCLK_SPEED == 0) /* Fout = 203MHz, Fin = 12MHz for Audio */
    #define M_MDIV 0xC3
    #define M_PDIV 0x4
    #define M_SDIV 0x1
    #elif (FCLK_SPEED == 1) /* Fout = 202.8MHz */
    #define M_MDIV 0xA1
    #define M_PDIV 0x3
    #define M_SDIV 0x1
    #endif
    修改为:
    #define FCLK_SPEED 1

    #if (FCLK_SPEED == 0) /* Fout = 203MHz, Fin = 12MHz for Audio */
    #define M_MDIV 0xC3
    #define M_PDIV 0x4
    #define M_SDIV 0x1
    #elif (FCLK_SPEED == 1) /* Fout = 405.8MHz */
    #define M_MDIV 0x7f /*查数据手册可知,为了是FCLK=405MHZ,这三个分频值依次是0x7f、0x2、0x1*/
    #define M_PDIV 0x2
    #define M_SDIV 0x1
    #endif

    修改获取时钟函数

    在:u-boot-2016.09\arch\arm\cpu\arm920t\s3c24x0\Speed.c

    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      将:
      static ulong get_PLLCLK(int pllreg)
      {
      struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
      ulong r, m, p, s;

      if (pllreg == MPLL)
      r = readl(&clk_power->mpllcon);
      else if (pllreg == UPLL)
      r = readl(&clk_power->upllcon);
      else
      hang();
      m = ((r & 0xFF000) >> 12) + 8;
      p = ((r & 0x003F0) >> 4) + 2;
      s = r & 0x3;
      return (CONFIG_SYS_CLK_FREQ * m) / (p << s);
      }
      修改为:
      static ulong get_PLLCLK(int pllreg)
      {
      struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
      ulong r, m, p, s;
      if (pllreg == MPLL)
      r = readl(&clk_power->mpllcon);
      else if (pllreg == UPLL)
      r = readl(&clk_power->upllcon);
      else
      hang();
      m = ((r & 0xFF000) >> 12) + 8;
      p = ((r & 0x003F0) >> 4) + 2;
      s = r & 0x3;
      #if defined(CONFIG_S3C2440)
      if (pllreg == MPLL)
      return 2 * m * (CONFIG_SYS_CLK_FREQ / (p << s));
      #endif
      return (CONFIG_SYS_CLK_FREQ * m) / (p << s);
      }
    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      将:
      ulong get_HCLK(void)
      {
      struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
      return (readl(&clk_power->clkdivn) & 2) ? get_FCLK() / 2 : get_FCLK();
      }
      修改为:
      ulong get_HCLK(void)
      {
      struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
      #ifdef CONFIG_S3C2440
      switch (readl(&clk_power->clkdivn) & 0x6) {
      default:
      case 0:
      return get_FCLK();
      case 2:
      return get_FCLK() / 2;
      case 4:
      return (readl(&clk_power->camdivn) & (1 << 9)) ?
      get_FCLK() / 8 : get_FCLK() / 4;
      case 6:
      return (readl(&clk_power->camdivn) & (1 << 8)) ?
      get_FCLK() / 6 : get_FCLK() / 3;
      }
      #else
      return (readl(&clk_power->clkdivn) & 2) ? get_FCLK() / 2 : get_FCLK();
      #endif
      }

    添加摄像头分频寄存器CAMDIVN

    因为我们在修改get_HCLK函数时,用到了camera寄存器所以我们需要添加相关的宏。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    在:u-boot-2016.09\arch\arm\include\asm\arch-s3c24x0\S3c24x0.h
    将:
    struct s3c24x0_clock_power {
    u32 locktime;
    u32 mpllcon;
    u32 upllcon;
    u32 clkcon;
    u32 clkslow;
    u32 clkdivn;
    };
    修改为:
    struct s3c24x0_clock_power {
    u32 locktime;
    u32 mpllcon;
    u32 upllcon;
    u32 clkcon;
    u32 clkslow;
    u32 clkdivn;
    #if defined(CONFIG_S3C2440)
    u32 camdivn;
    #endif
    };

    支持CONFIG_S3C2440/CONFIG_MYFF2440的宏配置

    在前面我们修改板级支持的头文件中,我们修改了两个宏下面我们需要将系统中的CONFIG_S3C2410替换成CONFIG_S3C2440,将CONFIG_SMDK2410替换成CONFIG_MYFF2440

    在ubuntu的根目录下,执行

    1
    find .|xargs grep -ri "CONFIG_S3C2410" -l

    会列出包含CONFIG_S3C2410的文件,将其替换,

    同理执行:

    1
    find .|xargs grep -ri "CONFIG_SMDK2410" -l

    也将其替换

    编译调试

    经过上面这几个步骤我们执行如下命令:

    在u-boot-2009.11的顶层目录,

    1
    make MyFF2440_config&&make

    不出意外的话,就可以顺利生成u-boot.bin文件,烧进板子里面nor 启动,串口就能正常输出

    注意

    我们在注释的时候尽量使用“/**/”符号,不要用“//”,因为有些交叉编译器不识别单行注释

-------------本文结束感谢您的阅读-------------