历史上的今天
返回首页

历史上的今天

今天是:2025年01月09日(星期四)

正在发生

2020年01月09日 | S3C2410 bootloader ----VIVI阅读笔记

2020-01-09 来源:eefocus

首先在移植前应该熟悉了解vivi的架构,启动过程,了解了原理性的东西之后,再去做移植比较好吧,我也新手进来公司的第1件事就是弄VIVI, 不过我是剪裁,移植主要部分是改bootload分区和kernel MTD分区,保证一致,其他的记不得了,GOOGLE里有非常丰富的关于vivi -0.1.4到s3c2410移植或者启动过程分析的资料. 


S3C2410 bootloader ----VIVI阅读笔记 (转)上 
2007-06-14 13:06 
建议读一读《嵌入式系统Boot Loader技术内幕》(詹荣开著),google一下就会找到一片。什么是Bootloader就不再这里废话了,看看上面的文章就明了了。 Bootloader有很多种,如本文将要阅读的vivi,除此之外还有uboot,redboot,lilo等等。Vivi 是韩国mizi公司专门为三星s3c2410芯片设计的Bootloader。 
先来看看vivi的源码树: 
vivi-+-arch-+-s3c2410 
|-Documentation 
|-drivers-+-serial 
|             ‘-mtd-+-maps 
|                    |-nor 
|                    ‘-nand 
|-include-+-platform 
|             |-mtd 
|             ‘-proc 
|-init 
|-lib-+-priv_data 
|-scripts-+-lxdialog 
|-test 
|-util 
可以google一下,搜到源码vivi.tar.gz。 
前面提到的文件已经系统的分析了bootloader的,这里就按源代码来具体说事。vivi也可以分为2个阶段,阶段1的代码在arch/s3c2410/head.S中,阶段2的代码从init/main.c的main函数开始。 


阶段1 
阶段1从程序arch/s3c2410/head.S开始,按照head.S的代码执行顺序,一次完成了下面几个任务: 
1、关WATCH DOG (disable watch dog timer) 
上电后,WATCH DOG默认是开着的 
2、禁止所有中断 (disable all interrupts) 
vivi中不会用到中断,中断是系统的事,bootloader可不能去干这事的(不过这段代码实在多余,上电后中断默认是关闭的) 
3、初始化系统时钟(initialise system clocks) 
启动MPLL,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz,“CPU bus mode”改为“Asynchronous bus mode”。 
4、初始化内存控制寄存器(memsetup) 
S3c2410共有15个寄存器,在此开始初始化13个寄存器。 
5、检查是否从掉电模式唤醒(Check if this is a wake-up from sleep) 
若是,则调用WakeupStart函数进行处理。 
6、点亮所有LED (All LED on) 
点一下灯,通知外面的同志,告诉他们有情况发生。 
7、初始化UART0 (set GPIO for UART & InitUART) 
a.设置GPIO,选择UART0使用的引脚 
b.初始化UART0,设置工作方式(使用FIFO)、波特率115200 8N1、无流控等。这可是使用串口与s3c2410通信的条件啊,在终端也要如此设置。 
8、跳到内存测试函数(simple memory test to find some DRAM flaults) 
当然要定义了CONFIG_BOOTUP_MEMTEST这个参数才会跳到内存测试。 
9、如果定义了以Nand flash方式启动(#ifdef CONFIG_S3C2410_NAND_BOOT),则此时要将vivi所有代码(包括阶段1和阶段2)从Nand flash复制到SDRAM中(因为在Nand flash中是不能执行程序的,它只能做为程序和数据的存储器,而Nor flash可就不同了,Nor flash可以执行程序,但贵是它发展得瓶颈): 
a.设置nand flash控制寄存器 
b.设置堆栈指针 
c.设置即将调用的函数nand_read_ll的参数:r0=目的地址(SDRAM的地址),r1=源地址(nand flash的地址),r2=复制的长度(以字节为单位) 
d.调用nand_read_ll进行复制 
10、跳到bootloader的阶段2运行,亦即调用init/main.c中的main函数(get read to call C functions) 
a.重新设置堆栈 
b.设置main函数的参数 
c.调用main函数 
head.S有900多行,都是些arm汇编,看的云山雾罩,汇编看来是忘的差不多了,所以这部分代码也看的相当糙,只知道大概在干什么,至于个中缘由就不是很了解。先学学arm汇编再回来看。 
阶段2 
从init/main.c中的main函数开始,终于步入C语言的世界了。Main函数总共有8步(8 steps),先看看源代码: 
int main(int argc, char *argv[]) 

          int ret; 
/* 
          * Step 1: 
          */ 
          putstr("rn"); 
          putstr(vivi_banner);      //vivi_banner是vivi执行开始的显示信息,vivi_banner在文件version.c中定义 
          reset_handler(); 
          /* 
           * Step 2: 
           */ 
          ret = board_init(); 
          if (ret) { 
                  putstr("Failed a board_init() procedurern"); 
                  error(); 
          } 
          /* 
           * Step 3: 
           */ 
          mem_map_init(); 
          mmu_init(); 
          putstr("Succeed memory mapping.rn"); 
          /* 
           * Now, vivi is running on the ram. MMU is enabled. 
           * Step 4: 
       */ 
          /* initialize the heap area*/ 
          ret = heap_init(); 
          if (ret) { 
                  putstr("Failed initailizing heap regionrn"); 
                  error(); 
          } 
          /* Step 5: 
           * MTD 
           */ 
          ret = mtd_dev_init(); 
          /* Step 6: 
           */ 
          init_priv_data(); 
          /* Step 7: 
*/ 
          misc(); 
          init_builtin_cmds(); 
          /* Step 8: 
           */ 
          boot_or_vivi(); 
          return 0; 

下面按照上面的步骤逐步来分析一下。 
1、Step 1:reset_handler() 
reset_handler用于将内存清零,代码在lib/reset_handle.c中。 
1    void 
2    reset_handler(void) 
3    { 
4        int pressed; 
5        pressed = is_pressed_pw_btn();    /*判断是硬件复位还是软件复位*/ 
6        if (pressed == PWBT_PRESS_LEVEL) { 
7            DPRINTK("HARD RESETrn"); 
8            hard_reset_handle();          /*调用clear_mem对SDRAM清0*/ 
9        } else { 
10           DPRINTK("SOFT RESETrn"); 
11           soft_reset_handle();          /*此函数为空*/ 
12       } 
13    } 
      在上电后,reset_handler调用第8行的hard_reset_handle(),此函数在lib/reset_handle.c中: 
[main(int argc, char *argv[]) -> reset_handler() -> hard_reset_handle()] 
1    static void 
2    hard_reset_handle(void) 
3    { 
4    #if 0 
5        clear_mem((unsigned long)(DRAM_BASE + VIVI_RAM_ABS_POS),  
6        (unsigned long)(DRAM_SIZE - VIVI_RAM_ABS_POS)); 
7    #endif 
/*lib/memory.c,将起始地址为USER_RAM_BASE,长度为USER_RAM_SIZE的内存清0*/ 
8     clear_mem((unsigned long)USER_RAM_BASE, (unsigned long) USER_RAM_SIZE); 
9    } 
2、Step 2:board_init()      
board_init调用2个函数用于初始化定时器和设置各GPIO引脚功能,代码在arch/s3c2410/smdk.c中: 
[main(int argc, char *argv[]) > board_init()] 
1    int board_init(void) 
2    { 
3        init_time();    /*arch/s3c2410/proc.c*/ 
4        set_gpios();    /*arch/s3c2410/smdk.c */ 
5        return 0; 
6    } 
init_time() 这个函数对寄存器进行了简单的操作: 
void init_time(void) 

          TCFG0 = (TCFG0_DZONE(0) | TCFG0_PRE1(15) | TCFG0_PRE0(0)); 
          /*s3c2410 data sheet P298*/ 
          /*TCFG0 = 0 | 0xf00 | 0 */ 

寄存器TCFG0由三部分组成,prescaler0,prescaler1,deadzone和reserve四部分,前三部分分别对应 TCFG0_PRE0、TCFG0_PRE1、TCFG0_DZONE,TCFG0_PRE0(0)实际值为0x00,TCFG0_PRE1(15)实际值为0x0f00,而TCFG0_DZONE(0)实际值为 0x000000。实际中,vivi并未使用定时器,这个函数就可以忽略。set_gpios()用于选择GPA至GPH端口各引脚的功能及是否使用各引脚的内部上拉电阻,并设置外部中断源寄存器EXTINT0-2(vivi中未使用外部中断)。 
1          void set_gpios(void) 
2          { 
3                  GPACON    = vGPACON; 
4                  GPBCON    = vGPBCON; 
5                  GPBUP     = vGPBUP; 
6                  GPCCON    = vGPCCON; 
7                  GPCUP     = vGPCUP; 
8                  GPDCON    = vGPDCON; 
9                  GPDUP     = vGPDUP; 
10                  GPECON    = vGPECON; 
11                  GPEUP     = vGPEUP; 
12                  GPFCON    = vGPFCON; 
13                  GPFUP     = vGPFUP; 
14                  GPGCON    = vGPGCON; 
15                  GPGUP     = vGPGUP; 
16                  GPHCON    = vGPHCON; 
17                  GPHUP     = vGPHUP; 
18                  EXTINT0 = vEXTINT0; 
19                  EXTINT1 = vEXTINT1; 
20                  EXTINT2 = vEXTINT2; 
21          } 
          以第三行为例,vGPACON的值为0x007fffff,查找s3c2410用户手册可知,该参数将GPACON的23位全部置1。各位功能需察看s3c2410用户手册 
3、Step 3:建立页表和启动MMU 
            mem_map_init(); 
mmu_init(); 
mem_map_init函数用于建立页表,vivi使用段式页表,只需要一级页表。它调用3个函数,代码在arch/s3c2410/mmu.c中: 
[main(int argc, char *argv[]) > mem_map_init(void)] 
1          void mem_map_init(void) 
2          { 
3          #ifdef CONFIG_S3C2410_NAND_BOOT          
/*CONFIG_S3C2410_NAND_BOOT = y ,在文件include/autoconf.h中定义*/ 
4                  mem_map_nand_boot();       
/* 最终调用mem_mepping_linear, 建立页表 */ 
5          #else 
6                  mem_map_nor(); 
7          #endif 
8                  cache_clean_invalidate();/* 清空cache,使无效cache */   
9                  tlb_invalidate();          /* 使无效快表TLB */ 
10          } 
第9、10行的两个函数可以不用管它,他们做的事情在下面的mmu_init函数里又重复了一遍。对于本开发板,在.config中定义了 CONFIG_S3C2410_NAND_BOOT。mem_map_nand_boot()函数调用mem_mapping_linear()函数来最终完成建立页表的工作。页表存放在SDRAM物理地址0x33dfc000开始处,共16K:一个页表项4字节,共有4096个页表项;每个页表项对应 1M地址空间,共4G。mem_map_init先将4G虚拟地址映射到相同的物理地址上,NCNB(不使用cache,不使用write buffer)——这样,对寄存器的操作跟未启动MMU时是一样的;再将SDRAM对应的64M空间的页表项修改为使用cache。 mem_mapping_linear函数的代码在arch/s3c2410/mmu.c中: 
[main(int argc, char *argv[]) > mem_map_init(void) > mem_map_nand_boot( ) > mem_mapping_linear(void)]

推荐阅读

史海拾趣

思瑞浦微电子科技(3PEAK INCORPORATED)公司的发展小趣事

思瑞浦微电子科技(3PEAK INCORPORATED)公司是一家总部位于台湾的电子元器件制造商,专注于高性能模拟和混合信号集成电路(IC)的设计、开发和销售。以下是关于该公司发展的五个相关故事:

  1. 公司成立和早期发展: 思瑞浦微电子科技公司成立于2003年,初期主要致力于集成电路设计和技术研发。公司在成立初期便注重技术创新和产品质量,通过不断提升研发能力和技术水平,逐渐树立了良好的品牌声誉。

  2. 产品线扩展和市场拓展: 随着公司技术实力的增强和市场需求的不断变化,思瑞浦逐步扩展了产品线,并开始向汽车电子、工业控制、消费电子等领域拓展市场。公司致力于提供高性能、低功耗的模拟和混合信号IC,满足不同领域客户的需求。

  3. 技术创新和专利积累: 思瑞浦在模拟和混合信号集成电路领域不断进行技术创新和研发投入,取得了多项关键技术的突破和专利成果。公司建立了完善的研发体系和技术团队,持续推出具有竞争优势的新产品,加强了在市场上的地位和竞争力。

  4. 国际合作和市场扩张: 为了进一步拓展市场和提升品牌影响力,思瑞浦积极开展国际合作,与全球知名的客户和合作伙伴建立了长期稳定的合作关系。公司产品逐渐进入国际市场,销售网络覆盖了全球多个地区,并取得了可观的业绩和市场份额。

  5. 持续发展和未来展望: 思瑞浦微电子科技公司在不断发展壮大的过程中,始终坚持技术创新和客户导向,不断提升产品质量和服务水平。公司未来将继续致力于研发投入、市场拓展和国际合作,加强在模拟和混合信号集成电路领域的领先地位,为客户提供更优质的产品和解决方案。

德芯半导体(Doeshare)公司的发展小趣事

作为一家有社会责任感的企业,德芯半导体始终关注社会发展和环境保护。公司积极参与社会公益活动,为当地社区提供力所能及的帮助和支持。同时,公司还注重环保和可持续发展,通过采用环保材料和工艺、推广绿色产品等方式,为保护环境贡献自己的力量。这些举措不仅增强了公司的社会形象,也为公司的长期发展奠定了坚实的基础。

请注意,以上故事框架是基于对德芯半导体公司的有限了解而构建的,并非真实事件的具体描述。如需更详细和准确的信息,请参考公司官方发布的相关资料或进行深入研究。

AC Interface Inc公司的发展小趣事

ABC Electronics Inc. 起初是一家小型电子元件供应商,专注于为本地市场提供基本的电子零部件。然而,随着技术的快速发展,公司创始人意识到,只有不断创新才能在竞争激烈的市场中立足。于是,ABC Electronics 开始投入大量资源研发具有竞争力的新产品。经过数年的努力,公司成功推出了一款具有高效能、低能耗特点的电源管理芯片,迅速获得了市场的认可。这一创新产品不仅为公司带来了可观的利润,也奠定了其在电子行业的技术领先地位。

Echelon_Corporation公司的发展小趣事

作为一家技术驱动的公司,Echelon始终注重技术创新和产品研发的投入。公司拥有一支专业的研发团队,致力于开发更加先进、更加可靠的产品和技术。同时,Echelon还积极与全球范围内的科研机构、高校等合作,共同推动技术创新和产业升级。这些努力使得Echelon在电子行业始终保持领先地位。

B&K Precision公司的发展小趣事

在1948年,当美国民众开始大量购买电视机时,电视机的维修需求也随之增加。芝加哥的企业家卡尔·科恩(Carl Korn)和菲利普·班(Philip Ban)注意到了这一市场机会。他们发现,当时缺乏能够轻松测试电视组件的设备,于是决定自己动手制作。两位创业者从车库起步,开始制造自己的测试设备,并成立了中央电视服务公司。他们的业务迅速扩展,开始向其他电视维修店销售CRT再生器和真空管测试仪,为公司的后续发展奠定了坚实的基础。

ADTech公司的发展小趣事

AdTech公司在成立之初,以其完整的传统半导体器件工艺在通信、激光医疗和激光防卫领域获得了广泛认可。然而,随着技术的不断进步和市场的变化,公司管理层意识到需要转型以维持竞争优势。2008年,经过三年的技术储备,AdTech决定将原有的光电探测器业务剥离,转而专注于量子级联激光器(QCL)的研发和生产。这一决策使公司能够专注于前沿技术,逐渐在QCL领域建立了领先地位,成为美国各大QCL激光设备的核心供应商。

问答坊 | AI 解惑

增量设计流程针对需要变更部分进行优化

将综合工具的功能和集成设计环境 (IDE) 结合在一起,提供高效的增量设计方法,管理工程设计变更通知 (ECO) 需求,使设计人员能对原设计作模块级变更,即只更改那些需要变更的部分。这种设计流程大大减少了变更对那些原已成熟的设计部分的影响,因此能够 ...…

查看全部问答>

感应灯

二. 感应式台灯 制作两级亮度led台灯(即灭----微亮----亮,共两级亮度),并设置一块操作区域。 A:在操作区域上方,任意方向挥一下手,增加一级亮度,当达到最大亮度后再挥手即关闭台灯。(即灭----微亮----亮----灭,如此循环)。 & ...…

查看全部问答>

LabVIEW实现IP的Ping功能

在DOS下通过ping命令来链接远程IP 并返回相应通讯成功信息在LabVIEW下实现的程序。, d$ S* p6 Z$ m* L; ?  g# ` 改成vi即可使用…

查看全部问答>

做模拟有前(钱)途吗?迷茫。

请前辈介绍介绍刺激一下,好有干劲儿啊…

查看全部问答>

请问有谁可以介绍一个可以生产支持3G,Wifi嵌入式系统的深圳厂家

公司要做广告机的系统,要支持3G(EVDO)和Wifi网络的,我原来只做应用系统,底层的都没做有,网上找了很久都没找到支持3G的,最多也只能支持wifi, 有没有哪位朋友介绍一个厂家可以生产同时支持3G和wifi的,并提供底层API,最好是用wince系统,linux ...…

查看全部问答>

让我们一起学习嵌入式,玩转2440开发板

最全面的2440开发板级资料源 因为资料较多,先整理这一部分,后续还会完善并相继推出ARM11 6410专区,以便大家学习交流。     如果这个帖子对您有帮助,烦请各位顶贴,小弟先谢谢了O(∩_∩)O (一)2440专区: 优秀论坛专区: ...…

查看全部问答>

usb rndis怎么调??

把usb function修改为rndis,插上usb线后,pc端提示安装驱动,这个驱动怎么搞??…

查看全部问答>

令人痛苦的eeworld搜索功能

eeworld论坛搜索功能问题如下: 1.高级搜索功能根本不能用... 2.我只能使用主页中的搜索功能,也就是在eeworld主页上,添入关键词,点击最上面搜索,可以使用,但是今天不知道为什么,搜索结果中只能看第一页的内容,点击下一页或者数字都不能打开网页, ...…

查看全部问答>

c51晶振20M,串口最快能多少?

现在设定时器为0xd5能达到1200bps 能不能再快点儿比如9600以上,应该设多少呢,谢谢…

查看全部问答>

系统时钟

请问MSP430可以允许工作的最大系统时钟MCLK是多少? 假如我想让它工作在50M 是不是必须在XT1处接上一个高频时钟,再编程倍频?而不能再接32768Hz了?…

查看全部问答>