⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 u-bootsourcecode.txt

📁 digging u-boot source code (s3c44b0 ) arm7上的 u-boot分析!
💻 TXT
📖 第 1 页 / 共 3 页
字号:
#define LOCKTIME (0x01c00000+0x18000c)
#define PLLCON (0x01c00000+0x180000)
#define CLKCON (0x01c00000+0x180004)
#define WTCON (0x01c00000+0x130000)
cpu_init_crit:
        /* 关闭看门狗 */
        ldr         r0, =WTCON
        ldr        r1, =0x0
        str        r1, [r0]
        /** 清除所有中断位,设置INTMRs实现。*/
        ldr        r1,=INTMSK
        ldr        r0, =0x03fffeff
        str        r0, [r1]
        ldr        r1, =INTCON
        ldr        r0, =0x05
        str        r0, [r1]
        /* 设置时钟控制寄存器 */
        ldr        r1, =LOCKTIME
        ldrb        r0, =800
        strb        r0, [r1]
        /* 设置锁相环,控制CPU运行速度。 */
        ldr        r1, =PLLCON
#if CONFIG_S3C44B0_CLOCK_SPEED==66
        ldr        r0, =0x34031         /* 66MHz (Quartz=11MHz) */
#elif CONFIG_S3C44B0_CLOCK_SPEED==75
        ldr        r0, =0x610c1 /*B2: Xtal=20mhz Fclk=75MHz  */
#else
# error CONFIG_S3C44B0_CLOCK_SPEED undefined
#endif
        str        r0, [r1]
        ldr        r1,=CLKCON
        ldr        r0, =0x7ff8
        str        r0, [r1]
        /* 调用子函数返回 */
        mov        pc, lr
/*************************************************/
/*        实际的中断向量表        */
/*************************************************/
real_vectors:
        b        reset
        b        undefined_instruction
        b        software_interrupt
        b        prefetch_abort
        b        data_abort
        b        not_used
        b        irq
        b        fiq
/*************************************************/
undefined_instruction:
        mov        r6, #3
        b        reset
software_interrupt:
        mov        r6, #4
        b        reset
prefetch_abort:
        mov        r6, #5
        b        reset
data_abort:
        mov        r6, #6
        b        reset
not_used:
        /* we *should* never reach this */
        mov        r6, #7
        b        reset
irq:
        mov        r6, #8
        b        reset
fiq:
        mov        r6, #9
        b        reset
把引导的汇编看完,已经准备C的运行环境,下面就开始学习C的源程序,从start.S文件里到跳文件lib_arm\board.c里运
行.
/*引导程序从汇编start.S里跳到这里执行。蔡军生 2005/07/19*/
void start_armboot (void)
{
        /* 声明一个全局指针,它是指向一个数据结构,用于保存参数。
        并且它占用r8寄存器,用它来保存内存地址,达到全局使用目的。
        */
        DECLARE_GLOBAL_DATA_PTR;
        ulong size;
        init_fnc_t **init_fnc_ptr;
        char *s;
#if defined(CONFIG_VFD) defined(CONFIG_LCD) unsigned long addr;
#endif
        /* gd指针可写,因为已经分配一个寄存器给它作为变量。
        这里就相当于把后面算出来的地址保存到r8寄存器.
        */
        gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
       /* 下面一句是阻止3.4以上版本的GCC进行代码优化,把后面的代码删除掉。 */
        __asm__ __volatile__("": : :"memory");
        /* 清空gd指向的结构 */
        memset ((void*)gd, 0, sizeof (gd_t));
        /*  */
        gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
        memset (gd->bd, 0, sizeof (bd_t));
        monitor_flash_len = _bss_start - _armboot_start;
这一段准备好保存参数的全局变量区.
后面就是一系列的初始化和获取正确的参数.
/* 用循环调用所有初始化函数 */
        for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) 
        {
               if ((*init_fnc_ptr)() != 0) 
               {
                      /* 当每个函数初始化失败时,就会挂机在这里。 */
                        hang();
                }
        }
上次说到在函数指针数组里,不断地调用所有初始化函数进行初始化,下面就来仔细地分析一下,它们到底是做什么
的,做什么样的初始化,怎么样为后面做好运行的准备工作。看到第一个初始化函数,就是CPU初始化(cpu_init),
这个函数是在cpu\s3c44b0\cpu.c里,它的作用就是进行S3C44B0初始化工作。看到这个函数内容如下:
/* CPU初始化。蔡军生 2005/07/23*/
int cpu_init (void)
{
        /* 清空缓冲区 */
        icache_enable();
        return 0;
}
它在里面调用了函数icache_enable(),它就是用来初始化S3C44B0的缓冲区,并且启用CPU缓冲区。因为CPU在加电之
后,它的初始化值是不启用内部的8K缓冲区的,必须由程序进行设置。接着看看那个调用的函数又是怎么样初始化内
部缓存区的呢?
/* CPU内存的缓冲初始化。蔡军生 2005/07/23*/
void icache_enable (void)
{
        ulong reg;
        /* 清空内存的缓冲区.  */
       s3c44b0_flush_cache();
        /* 初始化缓冲区,设置非缓冲区的起始地址和结束地址。第一个寄存器指明下面的地址不要缓存,低16位是起始地址,高16位是结束地址。并且空间大小都是以4K为界。0x0000:0000 - 0x0C00:0000*/
        NCACHBE0 = 0xC0000000;
        NCACHBE1 = 0x00000000;
        /* 设置SYSCFG寄存器启用8K缓冲区。 */
  reg = SYSCFG;
  reg = 0x00000006; /* 8kB */
        SYSCFG = reg;
}
在这个函数里,第一个先调用函数是进行缓冲区清0的工作,它有一些特别的地方,如下:
/* CPU的内部缓冲初始化。蔡军生 2005/07/23*/
static void s3c44b0_flush_cache(void)
{
        volatile int i;
       /* 清空缓冲区,每次要按4个32位来读写,所以要加16. */
       for( i = 0x10002000; i < 0x10004800; i += 16 )
        {
                *((int *)i)=0x0;
        }
}
它用一个for循环进行内部的缓冲区初始化,由于S3C44B0决定每次读写都是按16字节进行的。因此,这里的i就是不断
地加16个字节。不过,这里为什么不清除0x10000000到0x10001fff区域呢?这个我也没有搞清楚,等我有空试试清除
有没有问题!
到现在为止,缓冲区已经清空,就要设置那些内存区域是不要进行缓存的。因为不是所有内存都需要进行缓冲的,比
如读取外面的IO,就不需要进行缓冲;读取FLASH也不需要。因此,设置第一个非缓冲区的起始地址为NCACHBE0 = 
0xC0000000,这个值里的低16位是起始地址0x0000,它的32位地址就是从0x00000000开始。它的高16位是结束地址
0Xc000,它的32位地址就是从0Xc0000000结束。最后就是通过设置SYSCFG寄存器的[2:1]位的值为11,就启用了8K内存
数据和指令缓冲区。到这里为止,就已经设置好CPU的缓冲区初始化和启用。
由于前几次,把编译好的UBOOT写到FLASH老是运行不了。那么怎么办呢?思考了很久,也查看了源程序,还是没有发
现问题。也许那个UBOOT的源程序太大,有很多的编译开关,还有很多驱动程序选择,所以一头雾水,不知怎么办好。
到了这个时候,只有从头开始跟踪了。就是尽可能地跟踪程序运行到那里。因而依次地进行下面的检查:
1. 检查设置的倍频是否对。
2. 检查程序写到FLASH的数据是否对。
3. 检查设置RAM是否对。
4. 检查设置串口的波特率是否对。
一般进行四部份检查就找出大体的问题。我首先查了一下,我的开发板上的晶振是10MHz输入,那么我要倍频到60MHz
,所以就要计算它的倍频系数。当然最快的办法,就是用三星提供的PLLSET.EXE工具,五秒钟就搞定了。经过检查,
发现我的倍频系数不对,所以重新设置倍频系数。一般设置过倍频系后,都要调整串口波特率、SDRAM的刷新频率。设
置好倍频系数后,接着,就要计算串口的波特率,这个三星的S3C44B0的手册有计算公式。比如9600,就是拿60MHz进
行分频得到的。
这次设置好后这些东西之后,就把UBOOT编译后,再写到FLASH运行,还是不行。偶都在痛苦中,为什么还不行呢。后
来我想想,把UBOOT的编译地址改到0x00000000运行,就是在FLASH运行,不拷贝到SDRAM中运行。结果是可以运行一段
,串口有东西输出来,我的设置的LED也可以显示。蜂鸣器也不响。说明这个串口的设置已经对,那么系统的倍频也对
了。但UBOOT的堆栈我没有改,所以只能跑到没有使用到堆栈的代码。接着,我还需要改回到0x0C100000的基地址运行
。经过用ADS中的AXD调试,单步跟踪。又是一件痛苦的事情,发现AXD只能单步跟踪,设置断点,或者其它调试都不行
,如果在后面设置了断点,选择运行,发现到断点,还停不下来的。
呵呵。。。。。。。调试就是这样的,不是样样都顺手。既然只能单步运行,就老老实实地单步调试了,经过30多分
钟的单步运行,F8都已经按得手软。最后才跟踪到出错的地址,发现内存设置不对。主要是SDRAM的设置不对,查看了
加载地址的出错了。发现了这个加载地址出错,偶也没有更好的办法解决之前,就只好把算好的值,依次地用ldr加载
到r1-r13,共13个寄存器里。接着让AXD全速运行,程序就可运行了。原来出错就是没有把SDRAM的参数加载正确,让
我调试了三天。
通过一个多小时的调试,串口可以显示了,UBOOT的很多命令也可运行了。但还没有调通USB口,也没有网络接口。后
面的工作,就是先调通网络接口。我的开发板用的网络芯片是RTL8019AS,这个我也没有怎么看过,得好好找点资料,
了解了解这个IC,然后找一份LINUX的RTL8019的驱动程序出来看看,再决定怎么样调通RTL8019,由于RTL8019要用到
中断,就要先检查S3C44B0设置,否则到最后都没有办法调试。
通过开发板的调试,与SKYEYE相比,主要的区别是在SDRAM的频率,串口的频率,还有中断的功能,都有很大的不同。
因此,在SKYEYE上能运行的,在开发板,就不一定可以运行,就是这个原因

 

 
below get from http://www.linuxfans.org/nuke//modules.php?name=News&file=article&sid=2765

基于Atmel at91rm9200的armlinux的bootloader启动代码分析

 
1.4 u-boot源代码目录结构

board:开发板相关的源码,不同的板子对应一个子目录,内部放着主板相关代码。

at91rm9200dk/at91rm9200.c, config.mk, Makefile, flash.c ,u-boot.lds等都和具体开发板的硬件和地址分配有关。

common:与体系结构无关的代码文件,实现了u-boot所有命令,
其中内置了一个shell脚本解释器(hush.c, a prototype Bourne shell grammar parser), busybox中也使用了它.


cpu:与cpu相关代码文件,其中的所有子目录都是以u-boot所支持的cpu命名.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -