欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    vivi-的实现分析.doc

    • 资源ID:23956985       资源大小:321.50KB        全文页数:325页
    • 资源格式: DOC        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    vivi-的实现分析.doc

    Four short words sum up what has lifted most successful individuals above the crowd: a little bit more.-author-datevivi-的实现分析vivi boot loader的实现vivi boot loader的实现参考资料:1. 嵌入式系统 Boot Loader 技术内幕, 詹荣开 (zhanrk)2. Getting started with VIVI, Janhoon Lyu, nandy3. 嵌入式设备上的Linux 系统开发,A. Santhanam etc.4. Linux system development on an embedded device, A. Santhanam5. vivi 有关资料6. smdk2410的硬件和软件/linux相关资料 search 2410说明:本文文字结构照抄” 嵌入式系统 Boot Loader 技术内幕, 詹荣开 (zhanrk)” 一文,以vivi中head.S作为stage1, main()作为stage2,解释了VIVI for SMDK2410 (based on S3C2410) 开发系统的bootloader的实现。将原文放在这里是为了方便读者。注意,VIVI的实现并非完全跟原文一致。多谢原文作者詹大侠的详细解释。附录有一节_SETUP在kernel的作用来自jeppeter (member) from http:/ 文中对MTD subsystem linux没作解释。Google “MTD linux subsystem 文件系统 JFSS2 ”可以获得足够的解释。如有错误,烦请email jonesxu告知。多些Ver.0.95Jones S Z Xu jonesxu2004-09-29Chapter 1 Boot loader基本结构由于 Boot Loader 的实现依赖于 CPU 的体系结构,因此大多数 Boot Loader 都分为 stage1 和 stage2 两大部分。依赖于 CPU 体系结构的代码,比如设备初始化代码等,通常都放在 stage1 中,而且通常都用汇编语言来实现,以达到短小精悍的目的。而 stage2 则通常用C语言来实现,这样可以实现给复杂的功能,而且代码会具有更好的可读性和可移植性。 Boot Loader 的 stage1 通常包括以下步骤(以执行的先后顺序): 硬件设备初始化。为加载 Boot Loader 的 stage2 准备 RAM 空间。 拷贝 Boot Loader 的 stage2 到 RAM 空间中。 设置好堆栈。 跳转到 stage2 的 C 入口点。 Boot Loader 的 stage2 通常包括以下步骤(以执行的先后顺序): 初始化本阶段要使用到的硬件设备。检测系统内存映射(memory map)。 将 kernel 映像和根文件系统映像从 flash 上读到 RAM 空间中。 为内核设置启动参数。 调用内核。1.1 Boot Loader 的 stage11.1.1 基本的硬件初始化这是 Boot Loader 一开始就执行的操作,其目的是为 stage2 的执行以及随后的 kernel 的执行准备好一些基本的硬件环境。它通常包括以下步骤(以执行的先后顺序): 1 屏蔽所有的中断。为中断提供服务通常是 OS 设备驱动程序的责任,因此在 Boot Loader 的执行全过程中可以不必响应任何中断。中断屏蔽可以通过写 CPU 的中断屏蔽寄存器或状态寄存器(比如 ARM 的 CPSR 寄存器)来完成。 2 设置 CPU 的速度和时钟频率。 3 RAM 初始化。包括正确地设置系统的内存控制器的功能寄存器以及各内存库控制寄存器等。 4 初始化 LED。典型地,通过 GPIO 来驱动 LED,其目的是表明系统的状态是 OK 还是 Error。如果板子上没有 LED,那么也可以通过初始化 UART 向串口打印 Boot Loader 的 Logo 字符信息来完成这一点。 5 关闭 CPU 内部指令数据 cache。VIVI在第一阶段完成以下任务 Disable watch dog timer ; disable all interrupts ; initialise system clocks; initialise the static memory All LED on set GPIO for UART Initialize UART 0 ; copy_myself to ram; jump to ram get read to call C functions setup stack pointer call main1.1.2 为加载 stage2 准备 RAM 空间为了获得更快的执行速度,通常把 stage2 加载到 RAM 空间中来执行,因此必须为加载 Boot Loader 的 stage2 准备好一段可用的 RAM 空间范围。 由于 stage2 通常是 C 语言执行代码,因此在考虑空间大小时,除了 stage2 可执行映象的大小外,还必须把堆栈空间也考虑进来。此外,空间大小最好是 memory page 大小(通常是 4KB)的倍数。一般而言,1M 的 RAM 空间已经足够了。具体的地址范围可以任意安排,比如 blob 就将它的 stage2 可执行映像安排到从系统 RAM 起始地址 0xc0200000 开始的 1M 空间内执行。但是,将 stage2 安排到整个 RAM 空间的最顶 1MB(也即(RamEnd-1MB) - RamEnd)是一种值得推荐的方法。 为了后面的叙述方便,这里把所安排的 RAM 空间范围的大小记为:stage2_size(字节),把起始地址和终止地址分别记为:stage2_start 和 stage2_end(这两个地址均以 4 字节边界对齐)。因此: stage2_endstage2_startstage2_size另外,还必须确保所安排的地址范围的的确确是可读写的 RAM 空间,因此,必须对你所安排的地址范围进行测试。具体的测试方法可以采用类似于 blob 的方法,也即:以 memory page 为被测试单位,测试每个 memory page 开始的两个字是否是可读写的。为了后面叙述的方便,我们记这个检测算法为:test_mempage,其具体步骤如下: 1 先保存 memory page 一开始两个字的内容。 2 向这两个字中写入任意的数字。比如:向第一个字写入 0x55,第 2 个字写入 0xaa。 3 然后,立即将这两个字的内容读回。显然,我们读到的内容应该分别是 0x55 和 0xaa。如果不是,则说明这个 memory page 所占据的地址范围不是一段有效的 RAM 空间。 4 再向这两个字中写入任意的数字。比如:向第一个字写入 0xaa,第 2 个字中写入 0x55。 5 然后,立即将这两个字的内容立即读回。显然,我们读到的内容应该分别是 0xaa 和 0x55。如果不是,则说明这个 memory page 所占据的地址范围不是一段有效的 RAM 空间。 6 恢复这两个字的原始内容。测试完毕。 为了得到一段干净的 RAM 空间范围,我们也可以将所安排的 RAM 空间范围进行清零操作。 1.1.3 拷贝 stage2 到 RAM 中 拷贝时要确定两点:(1) stage2 的可执行映象在固态存储设备的存放起始地址和终止地址;(2) RAM 空间的起始地址。 1.1.4 设置堆栈指针 sp 堆栈指针的设置是为了执行 C 语言代码作好准备。通常我们可以把 sp 的值设置为(stage2_end-4),也即在 1.1.2 节所安排的那个 1MB 的 RAM 空间的最顶端(堆栈向下生长)。 此外,在设置堆栈指针 sp 之前,也可以关闭 led 灯,以提示用户我们准备跳转到 stage2。 经过上述这些执行步骤后,系统的物理内存布局应该如下图2所示。 1.1.5 跳转到 stage2 的 C 入口点 在上述一切都就绪后,就可以跳转到 Boot Loader 的 stage2 去执行了。比如,在 ARM 系统中,这可以通过修改 PC 寄存器为合适的地址来实现。 head.S 负责完成硬件初始化操作,具体分析见源码注释 ,汇编差不多忘光了,下面注释中有关汇编的东西多些。其中"linkage.h"#define SYMBOL_NAME_STR(X) #X#define SYMBOL_NAME(X) X#ifdef _STDC_#define SYMBOL_NAME_LABEL(X) X#:#else#define SYMBOL_NAME_LABEL(X) X/*/:#endif#define _ALIGN .align 0#define _ALIGN_STR ".align 0"#ifdef _ASSEMBLY_#define ALIGN _ALIGN#define ALIGN_STR _ALIGN_STR#define ENTRY(name) .globl SYMBOL_NAME(name); ALIGN; SYMBOL_NAME_LABEL(name)#endif其中"machine.h" 包括了smdk2410.h (有关开发板的配置) ,包括memory map, Porocessor memory map ,FLASH, ROM, DRAM的物理地址和在VIVI中用的虚拟地址(?),Architecture magic and machine type, UART,CPU,DRAM的初始化参数等smdk2410.h进一步包括s3c2410.h, 有关CPU的设置,Definition of constants related to the S3C2410 microprocessor(based on ARM 920T)./* * vivi/arch/s3c2410/head.S: * Initialise hardware * * Copyright (C) 2001 MIZI Research, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * Author: Janghoon Lyu <nandy> * Date : $Date: 2003/02/26 10:38:11 $ * * $Revision: 1.18 $ * * * History: * * 2002-05-14: Janghoon Lyu <nandy> * - Initial code * */#include "config.h"/àautoconf.h 空的#include "linkage.h"/定义#include "machine.h" Start of executable code ENTRY(_start)/入口点ENTRY(ResetEntryPoint) Exception vector table (physical address = 0x00000000)/异常向量 表 物理地址0x0000000 0x00: Reset/最 基本操作 :复位 B 是最简单的分支。一旦遇到一个 B 指令,ARM 处理器将立即跳转到给定的地址,从那里继续执行。注意存储在分支指令中的实际的值是相对当前的 R15 的bReset 0x04: Undefined instruction exception/处理未定义的指令 UndefEntryPoint:bHandleUndef 0x08: Software interrupt exception/软中断SWIEntryPoint:bHandleSWI 0x0c: Prefetch Abort (Instruction Fetch Memory Abort) /中文名不知道PrefetchAbortEnteryPoint:bHandlePrefetchAbort 0x10: Data Access Memory Abort/ DataAbortEntryPoint:bHandleDataAbort 0x14: Not used/空NotUsedEntryPoint:bHandleNotUsed 0x18: IRQ(Interrupt Request) exception/中断(普通)IRQEntryPoint:bHandleIRQ 0x1c: FIQ(Fast Interrupt Request) exception/ fast 中断处理FIQEntryPoint:bHandleFIQ VIVI magics 0x20: magic number so we can verify that we only put .long 0 0x24:.long 0 0x28: where this vivi was linked, so we can put it in memory in the right place.long _start 0x2C: this contains the platform, cpu and machine id.long ARCHITECTURE_MAGIC 0x30: vivi capabilities .long 0#ifdef CONFIG_PM/ power management /vivi未用 0x34:bSleepRamProc#endif#ifdef CONFIG_TEST/test modevivi未用 0x38:bhmi#endif Start VIVI headReset:/第一步 RESET disable watch dog timer/disable watch dog定时器movr1, #0x53000000movr2, #0x0strr2, r1/add 0x5300_0000 清 0,bit 5=0 disable this timer#ifdef CONFIG_S3C2410_MPORT3/另一种Platform 非SMDKmovr1, #0x56000000movr2, #0x00000005strr2, r1, #0x70mov r2, #0x00000001strr2, r1, #0x78movr2, #0x00000001str r2, r1, #0x74#endif disable all interrupts/禁止 所有中断movr1, #INT_CTL_BASE/0x4A00_0000 source pending registermovr2, #0xffffffffstrr2, r1, #oINTMSK /0x4A00_0008/0x4A00_0008 INTERRUPT MASK register=0xFFFFFFFF, disable all intldrr2, =0x7ffstrr2, r1, #oINTSUBMSK/0x4A00_001C /Interrupt sub mask register , bit10:0 = 1 ->0x7FF ->disable all initialise system clocks/初始化系统时钟movr1, #CLK_CTL_BASE/ LOCK TIME COUNT REGISTER(LOCKTIME)/0x4c000000mvnr2, #0xff000000strr2, r1, #oLOCKTIME/0x4C000000 ->0xFF00_0000;ldrr2, mpll_50mhz/CPU定成50Mhzstrr2, r1, #oMPLLCON/#ifndef CONFIG_S3C2410_MPORT1/如果未定义成MPORT1 (一种plat form) 1:2:4movr1, #CLK_CTL_BASEmovr2, #0x3strr2, r1, #oCLKDIVN/ vCLKDIVN0x3/* FCLK:HCLK:PCLK = 1:2:4 */mrcp15, 0, r1, c1, c0, 0 read ctrl register orrr1, r1, #0xc0000000 Asynchronous mcrp15, 0, r1, c1, c0, 0 write ctrl register now, CPU clock is 200 Mhz/CPU定成200Mhzmovr1, #CLK_CTL_BASEldrr2, mpll_200mhzstrr2, r1, #oMPLLCON#else/platform= MPORT1 ,以下不理 1:2:2 mov r1, #CLK_CTL_BASE ldr r2, clock_clkdivn str r2, r1, #oCLKDIVN mrc p15, 0, r1, c1, c0, 0 read ctrl register orr r1, r1, #0xc0000000 Asynchronous mcr p15, 0, r1, c1, c0, 0 write ctrl register now, CPU clock is 100 Mhz mov r1, #CLK_CTL_BASE ldr r2, mpll_100mhz str r2, r1, #oMPLLCON#endifblmemsetup/第2步memsetup#ifdef CONFIG_PM/如果有 Power management:不用 Check if this is a wake-up from sleepldrr1, PMST_ADDRldrr0, r1tstr0, #(PMST_SMR)bneWakeupStart#endif#ifdef CONFIG_S3C2410_SMDK/SMDK platform All LED on/点灯,好歹通知一下外面的同志3movr1, #GPIO_CTL_BASEaddr1, r1, #oGPIO_Fldrr2,=0x55aastrr2, r1, #oGPIO_CONmovr2, #0xffstrr2, r1, #oGPIO_UPmovr2, #0x00strr2, r1, #oGPIO_DAT#endif#if 0 SVCmrsr0, cpsrbicr0, r0, #0xdforrr1, r0, #0xd3msrcpsr_all, r1#endif/设置串口 ,内外联络的通道 set GPIO for UARTmovr1, #GPIO_CTL_BASE/ 0x5600_0000addr1, r1, #oGPIO_H/ oGPIO_H 0x70 PORT H CONTROL REGISTERS ldrr2, gpio_con_uart/ vGPHCON= 0x0016faaastrr2, r1, #oGPIO_CON/ 01 01 10 11 11 10 10 10 10 10 10 B/oGPIO_CON = 0x0 / GPH0 bit1:0 = 10 nCTS0/ GPH1 bit3:2 = 10 nRTS0/ GPH2 bit5:4 10 TXD0/ GPH3 bit7:6 = 10 RXD0/ GPH4 bit9:8 = 10 TXD1/ GPH5 bit11:10 10 RXD1/ GPH6 bit13:12 = 11 nRTS1/ GPH7 bit15:14 = 11 nCTS1/ GPH8 bit17:16 10 UEXTCLK/ GPH9 bit19:18 = 01 Output/ GPH10 bit21:20 01 Outputldrr2, gpio_up_uart/ vGPHUP 0x000007ff = 0111 1111 1111 Bstrr2, r1, #oGPIO_UP/ oGPIO_UP 0x8 /* R/W, Pull-up disable register */ 0x7FF -> 1: The pull-up function is disabled. For all GPHx/ reg GPHUP 0x56000078blInitUART/initialize UART#ifdef CONFIG_DEBUG_LL/low level debugging info Print current Program Counter/vivi def没用ldrr1, SerBase/往串口上输出 infomovr0, #'r'blPrintCharmovr0, #'n'blPrintCharmovr0, #''blPrintCharmovr0, pcblPrintHexWord#endif#ifdef CONFIG_BOOTUP_MEMTEST/ comment 'Low Level Hardware Debugging' bool ' Enable simple memory test' CONFIG_BOOTUP_MEMTEST /vivi def没用 simple memory test to find some DRAM flaults.blmemtest/check the first 1MB in increments of 4k/改大点3#endif#ifdef CONFIG_S3C2410_NAND_BOOTblcopy_myself jump to ramldrr1, =on_the_ram/将on_the_ram的地址装入r1addpc, r1, #0/pc = r1+0nopnop1:b1b infinite loop/硬是看不懂这个 B on_the_ram:#endif#ifdef CONFIG_DEBUG_LLldrr1, SerBaseldrr0, STR_STACKblPrintWordldrr0, DW_STACK_STARTblPrintHexWord#endif get read to call C functionsldrsp, DW_STACK_START setup stack pointer/ STACK_BASE+STACK_SIZE-4/ STACK_BASE = (VIVI_PRIV_RAM_BASE - STACK_SIZE)/STACK从上往下用。 所以 STACK_START = STACK_BASE+STACK_SIZE-4movfp, #0 no previous frame, so fp=0mova2, #0 set argv to NULL blmain call main /如果正常,一去不复返的了movpc, #FLASH_BASE otherwise, reboot, /FLASH_BASE=ROM_BASE0 = 0x0 End VIVI head/* * subroutines */ Wake-up codes#ifdef CONFIG_PMWakeupStart:/ power management 用 Clear sleep reset bitldrr0, PMST_ADDRmovr1, #PMST_SMRstrr1, r0 Release the SDRAM signal protectionsldrr0, PMCTL1_ADDRldrr1, r0bicr1, r1, #(SCLKE | SCLK1 | SCLK0)strr1, r0 Go.ldrr0, PMSR0_ADDR read a return addressldrr1, r0movpc, r1nopnop1:b1b infinite loopSleepRamProc:/power management用 SDRAM is in the self-refresh mode */ldrr0, REFR_ADDRldrr1, r0orrr1, r1, #SELF_REFRESHstrr1, r0 wait until SDRAM into self-refreshmovr1, #161:subsr1, r1, #1bne1b Set the SDRAM singal protectionsldrr0, PMCTL1_ADDRldrr1, r0orrr1, r1, #(SCLKE | SCLK1 | SCLK0)strr1, r0/* Sleep. Now */ldrr0, PMCTL0_ADDRldrr1, r0orrr1, r1, #SLEEP_ONstrr1, r01:b1b#ifdef CONFIG_TESThmi:ldrr0, PMCTL0_ADDR / PMCTL0_ADDR: .long 0x4c00000c, Clock Gen Ctrl ldrr1, =0x7fff0/ reset clock gen ctrlstrr1, r0 All LED on/点灯?movr1, #GPIO_CTL_BASEaddr1, r1, #oGPIO_Fldrr2,=0x55aastrr2, r1, #oGPIO_CONmovr2, #0xffstrr2, r1, #oGPIO_UPmovr2, #0xe0strr2, r1, #oGPIO_DAT1:b1b#endif#endifENTRY(memsetup)/memsetup子程序 initialise the static memory set memory control registersmovr1, #MEM_CTL_BASE/memory controlleradrlr2, mem_cfg_valaddr3, r1, #521:ldrr4, r2, #4strr4, r1, #4cmpr1, r3bne1bmovpc, lr/这里返回了么?注意注意:这里memsetup已经返回了,下面是独立的子程序了呢#ifdef CONFIG_S3C2410_NAND_BOOT / NAND如此,NOR应该如何处理呢?/不需要copy vivi to ram? copy_myself: copy vivi to ramcopy_myself:movr10, lr reset NANDmovr1, #NAND_CTL_BASEldrr2, =0xf830 initial valuestrr2, r1, #oNFCONFldrr2, r1, #oNFCONFbicr2, r2, #0x800 enable chipstrr2, r1, #oNFCONFmovr2, #0xff RESET commandstrbr2, r1, #oNFCMDmovr3, #0 wait 1:addr3, r3, #0x1cmpr3, #0xablt1b2:ldrr2, r1, #oNFSTAT wait readytstr2, #0x1beq2bldrr2, r1, #oNFCONForrr2, r2, #0x800 disable chipstrr2, r1, #oNFCONF get read to call C functions (for nand_read()ldrsp, DW_STACK_START setup stack pointermovfp, #0 no previous frame, so fp=0 copy vivi to RAMldrr0, =VIVI_RAM_BASE /(DRAM_BASE + DRAM_SIZE - VIVI_RAM_SIZE)/0x33f00000mov r1, #0x0/start address, now vivi is in steppingstonemovr2, #0x20000/128k ? blnand_read_ll/ nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)/ ro = buf , r1 =start , size = r2=128k ?yeah ? 要这么多干吗?tstr0, #0x0/返回值在r0中beqok_nand_read/nand_read_ll()顺利返回#ifdef CONFIG_DEBUG_LLbad_nand_read: ldrr0, STR_FAILldrr1, SerBaseblP

    注意事项

    本文(vivi-的实现分析.doc)为本站会员(豆****)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开