S3C6410之uboot回炉再造(7)C环境的入口

发布者:SparklingMoon最新更新时间:2024-09-02 来源: cnblogs关键字:S3C6410  uboot 手机看文章 扫描二维码
随时随地手机看文章

  上一部分讲到 uboot 跳转到 start_armboot 处执行(中间插了一篇 异常中断处理)。


  这次主要是记录 start_armboot 的实现。


  文件为 /lib_arm/board.c


  1、参数声明


  1 void start_armboot (void)

  2 {

  3     init_fnc_t **init_fnc_ptr;        //这里实际上是创建数组指针

           //指向的数组为 start_armboot 之前的 init_sequence 数组

  4     char *s;

  5 #if defined(CONFIG_VFD) || defined(CONFIG_LCD)

  6     unsigned long addr;

  7 #endif


  2、两个结构体与内存屏障


  8 

  9     /* Pointer is writable since we allocated a register for it */

 10     gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));

 11     /* compiler optimization barrier needed for GCC >= 3.4 */

 12     __asm__ __volatile__('': : :'memory');

  这里有两个结构体要展开


  1)uboot所调用的配置信息,文件为/include/asm-arm/Global_data.h


typedef    struct    global_data {

    bd_t        *bd;      

    unsigned long    flags;

    unsigned long    baudrate;

    unsigned long    have_console;    /* serial_init() was called */

    unsigned long    env_addr;    /* Address  of Environment struct */

    unsigned long    env_valid;    /* Checksum of Environment valid? */

    unsigned long    fb_base;    /* base address of frame buffer */

#ifdef CONFIG_VFD

    unsigned char    vfd_type;    /* display type */

#endif

#ifdef CONFIG_FSL_ESDHC

    unsigned long    sdhc_clk;

#endif

#if 0

    unsigned long    cpu_clk;    /* CPU clock in Hz!        */

    unsigned long    bus_clk;

    phys_size_t    ram_size;    /* RAM size */

    unsigned long    reset_status;    /* reset status register at boot */

#endif

    void        **jt;        /* jump table */

} gd_t;


  2)板子所调用的板级配置信息,文件为/include/asm-arm/U-boot.h


typedef struct bd_info {

    int            bi_baudrate;    /* serial console baudrate */

    unsigned long    bi_ip_addr;    /* IP Address */

    struct environment_s           *bi_env;

    ulong            bi_arch_number;    /* unique id for this board */

    ulong            bi_boot_params;    /* where this board expects params */

    struct                /* RAM configuration */

    {

    ulong start;

    ulong size;

    }            bi_dram[CONFIG_NR_DRAM_BANKS];

} bd_t;


  这里的 gd 实际指向了一个地址,地址位置可以看下图


  注意,这里为小端模式


  _bss_start    

     |

  TEXT/DATA       

        |        // = 0x100000 + 0x4000

CONFIG_SYS_MALLOC_LEN 

        |        // = sizeof(gd_t)

      gd_t            // gd 实际指向的地址

        |        // = sizeof(bd_t)

    bd_t       // gd_t 的第一部分就是 bd_t

     |

_armboot_start     // 定义在 start.S 中

     |

    STACK      // IRQ_STACK_START FIQ_STACK_START


  然后是内存屏障


 12     __asm__ __volatile__('': : :'memory');

  简单理解起来就是:禁止编译器优化此处的汇编代码


  这样做,可以有效防止 编译器将当前的寄存器的值 直接替换在代码中。


  这行代码大量地使用在内存屏障函数中,例如 mb()函数组。


  更详细的介绍可以参详


http://blog.sina.com.cn/s/blog_7e741b830100wz1f.html

 

  3、分配空间


 13 

 14     memset ((void*)gd, 0, sizeof (gd_t));      //清空 gd 的对应空间

 15     gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));   //设置 bd 指向地址

 16     memset (gd->bd, 0, sizeof (bd_t));        //清空 bd 的对应空间

 17 

 18     gd->flags |= GD_FLG_RELOC;  

      // #define GD_FLG_RELOC 0x00001 /* Code was relocated to RAM*/

 19 

 20     monitor_flash_len = _bss_start - _armboot_start;


  4、初始化


 21 

 22     for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {

 23         if ((*init_fnc_ptr)() != 0) {

 24             hang ();

 25         }

 26     }


  这里的 hang 其实是死循环,函数如下


void hang (void)

{

    puts ('### ERROR ### Please RESET the board ###n');

    for (;;);

}

  意味着如果有初始化函数不存在,或者初始化失败(返回不为0),则出错。


  5、清空 code 区


 27 

 28     /* armboot_start is defined in the board-specific linker script */

 29     mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN,

 30             CONFIG_SYS_MALLOC_LEN);

  此处有


void mem_malloc_init(ulong start, ulong size)

{

    mem_malloc_start = start;

    mem_malloc_end = start + size;

    mem_malloc_brk = start;


    memset((void *)mem_malloc_start, 0, size);

}


  6、之后有大量的可配置项,这些可配置项的内部实现都很简单清晰,所以仅列出标题了


 32 #ifndef CONFIG_SYS_NO_FLASH

 37 #ifdef CONFIG_VFD

 50 #ifdef CONFIG_LCD

 75 #ifdef CONFIG_HAS_DATAFLASH

 

  7、变量搬移


 79 

 80     /* initialize environment */

 81     env_relocate ();

  具体实现在 /common/Env_common.c 中


  8、可配置项


 83 #ifdef CONFIG_VFD

 88 #ifdef CONFIG_SERIAL_MULTI

 

  9、这一段代码量较长、不继续深入


  主要功能看代码自注


复制代码

 91 

 92     /* IP Address */

 93     gd->bd->bi_ip_addr = getenv_IPaddr ('ipaddr');

 94 

 95     stdio_init ();    /* get the devices list going. */

 96 

 97     jumptable_init ();


  10、可配置项


 99 #if defined(CONFIG_API)

 


  11、控制台初始化


104     console_init_r ();    /* fully init console as a device */

 


  12、可配置项


106 #if defined(CONFIG_ARCH_MISC_INIT)

110 #if defined(CONFIG_MISC_INIT_R)

 

  13、使能中断


114 

115     /* enable exceptions */

116     enable_interrupts ();

 

  14、可配置项


119 #ifdef CONFIG_DRIVER_TI_EMAC

129 #if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)

 

  16、


137 

138     /* Initialize from environment */

139     if ((s = getenv ('loadaddr')) != NULL) {

140         load_addr = simple_strtoul (s, NULL, 16);

141     }

 

  17、可配置项


142 #if defined(CONFIG_CMD_NET)

148 #ifdef BOARD_LATE_INIT

152 #ifdef CONFIG_GENERIC_MMC

157 #ifdef CONFIG_BITBANGMII

160 #if defined(CONFIG_CMD_NET)

161 #if defined(CONFIG_NET_MULTI)


  18、网卡设置


164     eth_initialize(gd->bd);

 

  19、可配置项


165 #if defined(CONFIG_RESET_PHY_R)

 


  20、进入主循环


170     /* main_loop() can return to retry autoboot, if so just run it again. */

171     for (;;) {

172         main_loop ();

173     }

174 

175     /* NOTREACHED - no way out of command loop except booting */


  文件路径为 /common/Main.c


关键字:S3C6410  uboot 引用地址:S3C6410之uboot回炉再造(7)C环境的入口

上一篇:S3C6410移植u-boot-2010.3(1)成功编译的开始
下一篇:S3C6410之uboot回炉再造(6)异常中断处理

推荐阅读最新更新时间:2026-02-28 15:13

搭建 S3C6410开发板的测试环境
S3C6410 是由三星公司推出的低功耗、高性价比的 SC ( reduced instruction set computer,精简指令集计算机〉处理器,它基于 ARMII 内核( ARMl76JZF-S),可广泛应用于移动电话和通用处理等领域。 (1)安装串口调试工具minicom 1.检测当前系统是否支持USB转串口 # Ismod I grep usbserial 2.安装 minicom # apt-get install minicom 3.配置minicom # minicom -s 4.测试minicom # minicom (2)使用E b o o t擦除N a n d F l a s h 1.用串口线或USB
[单片机]
s3c6410 uboot初步移植
对uboot主要是修改: 1、更改交叉编译器   CROSS_COMPILE ?= arm-linx- 2、对board项进行修改 3、include项修改 4、CPU项修改 5、根目录下Makefile修改 6、arm架构修改 7、nand_spl修改 此次 移植过程很成功,未报错,但是生成的*.bin文件在板子上运行未见效果。
[单片机]
S3C6410之uboot回炉再造(3)lowlevle_init.S
  这一篇粗略讲一下lowlevel_init.S内部的模块。   1、_TEXT_BASE 1 #include config.h 2 #include version.h 3 4 #include asm/arch/s3c6400.h 5 6 #ifdef CONFIG_SERIAL1 7 #define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART0_OFFSET) 8 #elif defined(CONFIG_SERIAL2) 9 #define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE
[单片机]
S3C6410使用---10为SD卡与NAND FLASH的uboot加上menu菜单
用ok6410进行烧写时,每次都需要敲一大堆命令,又费时又费力. 记得以前用TQ2440时,u-boot启动时会有一个菜单,只按一个数字键就把内核烧好了,非常方便. 现在这张SD卡功能就很全面了,不仅能够直接从SD卡启动,而且还可以烧写nand flash中的u-boot zImage rootfs,呵呵. 下面就把这个功能加到ok6410的u-boot 中去. 一、修改SD卡的u-boot1.1.6 1. common/main.c中 void main_loop (void) { ....... if (bootdelay = 0 && s && !abortboot (bootdelay)) {
[单片机]
Linux 下使用s3c6410的post处理器的进行硬件缩放
在嵌入式下,在移植软件时经常会碰到这样的问题,就是显示分辩率的变化.一般软件往往针对桌面机的环境编译没有太多问题,但是在嵌入式环境下,受限的LCD显示有着很大的问题. 这种情况下,一种方法是修改代码,让其在嵌入式的LCD上显示.另外一种是使用软件进行显示缩放. 这两个方法只在部分条件有效,而且修改的工作量极大,更多情况是无法修改,比如SDL下的Dosbox是针对 640*480,修改源码的分辩率成 480*272 后,基本屏幕显示完全错位.软件无法正常运行. 这里有一种思路是使用s3c6410的post process.它是一个硬件进行图像和视频缩放的的模块.用POST后,只需要简单调整frame buffer显示库代码,即可
[单片机]
s3c6410 完全由SD卡启动Linux流程
1. s3c6410 SD启动原理 s3c6410 支持Nand Flash本地启动Linux,包括内核,根文件系统,bootloader均写入在Nand Flash.这样可以独立运行. 很多情况下,Nand Flash的某种原因无法写入内核和Rootfs.而使用tftp下载内核,用NFS启动根文件系统比较慢.s3c6410 支持 SD卡启动,经过改造u-boot可以从SD卡引导内核,这样而Linux 又可以从SD卡的装载ext3根文件系统.这样可以制作一个完整的SD卡启动卡. 这样bootloader(u-boot)可以写入SD卡,引导扇区. bootloader的第一阶段把自己装入在内存高端地址看后,可以用两
[单片机]
玩转S3C6410之一 交叉工具链制作(gcc4.5.1-armv6-vfp)
软件平台:ubuntu 11.10(按照本人博客中“玩转Ubuntu-11.10”系列的文章进行安装) 主机编译器: gcc 4.6.1 硬件平台:tiny6410 1、准备环境 必备工具包:bison、flex、texinfo、automake、libtool、cvs、patch、libncurses5-dev、aria2、curl、g++、svn、gawk、cvsd、subversion (有些文章有写要安装gcj,在我的Ubuntu11.10安装不了,提示说它被其它的软件包引用了,可能是我之前装的其他工具已经包含gcj了把) 我们可以通过以下一条命令来获得它们,但需要ubuntu11.10接入
[单片机]
(ARM11 S3C6410)关于裸机串口与定时器
调试MCU经常需要用串口。 裸机前后台系统,基本就是基于定时器中断。 init.s 启动代码 Mode_USR EQU 0x10 Mode_FIQ EQU 0x11 Mode_IRQ EQU 0x12 Mode_SVC EQU 0x13 Mode_ABT EQU 0x17 Mode_UND EQU 0x1B Mode_SYS EQU 0x1F UND_Stack_Size EQU 0x00000400 SVC_Stack_Size EQU 0x00001000 ABT_Stack_Size EQU 0x00000400 FIQ_Sta
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved