最近一直在学习研究u-boot,这是我对s5pv210的u-boot的一些学习的一些列的文章中的一部分。这是我的注释代码,希望能帮到正在学习的你们。
/** Memory Setup stuff - taken from blob memsetup.S** Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and*                     Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)** Modified for the Samsung SMDK2410 by* (C) Copyright 2002* David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>** See file CREDITS for list of people who contributed to this* project.** 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*/
/*参考引用
http:@www.cnblogs.com/Efronc/archive/2012/02/29/2373668.html    u-boot_smdkv210 分析三:启动代码lowlevel.s分析 */#include <config.h>
#include <version.h>#include <s5pc110.h>
#include "smart210_val.h"_TEXT_BASE: @定义一个标签,后面将会用到,用于判断代码是否在外部RAM中运行,以此来判断是否初始化外部RAM.word   CONFIG_SYS_TEXT_BASE        @这句话的意思是就是在当前位置放一个word型的值,这个值就是CONFIG_SYS_TEXT_BASE 可以这样理解,_TEXT_BASE是一个地址,这个地址中的内容是CONFIG_SYS_TEXT_BASE@配合后面的  ldr r2, _TEXT_BASE      /* r1 <- original base addr in ram */ 就是将以_TEXT_BASE为地址的变量的值即CONFIG_SYS_TEXT_BASE赋给r2.globl lowlevel_init    @指示告诉汇编器,lowlevel_init这个符号要被链接器用到,所以要在目标文件的符号表中标记它是一个全局符号
lowlevel_init:push    {lr}    @将上一个函数的返回地址压到栈中/* check reset status  */@读取复位标志,如果是睡眠唤醒,跳过接下来的初始化ldr r0, =(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET)@将跳转目的地址Reset Control Register的地址传送给r0 Address = 0xE010_A000 =0xE010_0000+0xA000ldr r1, [r0]    @将存储器地址为 R0(内存储的值) 的字数据读入寄存器 R1。bic r1, r1, #0xfff6ffff     @将r1与0xfff6ffff的反码按位进行与运算(既和0xfff6ffff进行与非运算),并写入r1;结合上一步,可知,这一步的作用是16和19bit置一,其他位清零cmp r1, #0x10000    @判断16bit是不是等于1beq wakeup_reset_pre @如果是从睡眠状态唤醒,就跳转到wakeup_reset_pre,既跳过接下来的初始化cmp r1, #0x80000    @判断是不是从深度空闲(Deep-IDLE)状态唤醒beq wakeup_reset_from_didle @如果是,就跳转到wakeup_reset_from_didle/* IO Retention release */ldr r0, =(ELFIN_CLOCK_POWER_BASE + OTHERS_OFFSET)   @将跳转目的地址MISC Register的地址传送给r0   Address = 0xE010_E000 =0xE010_0000+0xE000ldr r1, [r0]    @将存储器地址为 R0(内存储的值) 的字数据读入寄存器 R1ldr r2, =IO_RET_REL @将IO_RET_REL( ((1 << 31) | (1 << 29) | (1 << 28)) )存入r2orr r1, r1, r2  @将r1和r2的值进行或运算,结果存入r1str r1, [r0]    @将r1的值写入以r0内的值为地址的内存空间/* Disable Watchdog 关闭看门狗*/ldr r0, =ELFIN_WATCHDOG_BASE    /* 0xE2700000 */mov r1, #0str r1, [r0]        @清空以r0内的值为地址的内存空间/* SRAM(2MB) init for SMDKC110 *//* GPJ1 SROM_ADDR_16to21 *//*配置sram引脚,16位数据宽度,22位地址宽度*/ldr r0, =ELFIN_GPIO_BASEldr r1, [r0, #GPJ1CON_OFFSET]bic r1, r1, #0xFFFFFF   @清除r1内的低24位值ldr r2, =0x444444   @引脚设置为addr功能orr r1, r1, r2str r1, [r0, #GPJ1CON_OFFSET]ldr r1, [r0, #GPJ1PUD_OFFSET]ldr r2, =0x3ffbic r1, r1, r2str r1, [r0, #GPJ1PUD_OFFSET]/* GPJ4 SROM_ADDR_16to21 */ldr r1, [r0, #GPJ4CON_OFFSET]bic r1, r1, #(0xf<<16)ldr r2, =(0x4<<16)orr r1, r1, r2str r1, [r0, #GPJ4CON_OFFSET]ldr r1, [r0, #GPJ4PUD_OFFSET]ldr r2, =(0x3<<8)bic r1, r1, r2str r1, [r0, #GPJ4PUD_OFFSET]/* CS0 - 16bit sram, enable nBE, Byte base address */ldr r0, =ELFIN_SROM_BASE    /* 0xE8000000 */mov r1, #0x1str r1, [r0]/* PS_HOLD pin(GPH0_0) set to high *//*设置PMIC(Power Management IC)控制引脚,既电源管理ic引脚(基于I2C)*/ldr r0, =(ELFIN_CLOCK_POWER_BASE + PS_HOLD_CONTROL_OFFSET)ldr r1, [r0]orr r1, r1, #0x300orr r1, r1, #0x1str r1, [r0]/* when we already run in ram, we don't need to relocate U-Boot.* and actually, memory controller must be configured before U-Boot* is running in ram.*//*下面的代码事实上只是判断pc和_TEXT_BASE(0X23e00000)的最高两位是否相同*//*根据s5pv210的数据手册可知,首先,系统会运行固化在irom的BL0,紧接着会从外部nand*或sdcard等设备读取前16K的BL1代码到IRAM中的0xD0020000处。然后从0xD0020010处运行(因为前16byte是校验和的值)*BL1的作用是初始化DRAM,拷贝BL2到DRAM中_TEXT_BASE(0X23e00000)处,然后跳到DRAM中运行×因此可以通过最高两位来判断代码是在哪里运行×同时可知,当代码已经就在DRAM中运行时,就必须跳过DRAM的初始化*/ldr r0, =0x00ffffffbic r1, pc, r0      /* r0 <- current base addr of code */ldr r2, _TEXT_BASE      /* r1 <- original base addr in ram */bic r2, r2, r0      /* r0 <- current base addr of code */cmp     r1, r2                  /* compare r0, r1                  */beq     1f          /* r0 == r1 then skip sdram init   *//* init system clock */bl system_clock_init/* Memory initialize */bl mem_ctrl_asm_init1:/* for UART */bl uart_asm_init    @调用Uart初始化bl tzpc_init        #if defined(CONFIG_ONENAND)bl onenandcon_init
#endif#if defined(CONFIG_NAND)/* simple init for NAND */bl nand_asm_init    @nand初始化
#endif/* check reset status  */ldr r0, =(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET)ldr r1, [r0]bic r1, r1, #0xfffeffffcmp r1, #0x10000beq wakeup_reset_pre/* ABB disable */ldr r0, =0xE010C300orr r1, r1, #(0x1<<23)str r1, [r0]/* Print 'K' */ldr r0, =ELFIN_UART_CONSOLE_BASEldr r1, =0x4b4b4b4bstr r1, [r0, #UTXH_OFFSET]pop {pc}    @返回到start.swakeup_reset_from_didle:    @从深度睡眠中唤醒/* Wait when APLL is locked */ldr r0, =ELFIN_CLOCK_POWER_BASE
lockloop:ldr r1, [r0, #APLL_CON0_OFFSET]and r1, r1, #(1<<29)cmp r1, #(1<<29)bne     lockloopbeq exit_wakeupwakeup_reset_pre:   mrc p15, 0, r1, c1, c0, 1   @Read CP15 Auxiliary control registerand r1, r1, #0x80000000 @Check L2RD is disable or notcmp r1, #0x80000000bne wakeup_reset        @if L2RD is not disable jump to wakeup_resetbl  disable_l2cachebl  v7_flush_dcache_allbl  enable_l2cachewakeup_reset:/* init system clock */bl system_clock_initbl mem_ctrl_asm_initbl tzpc_init
#if defined(CONFIG_ONENAND)bl onenandcon_init
#endif
#if defined(CONFIG_NAND)bl nand_asm_init
#endifexit_wakeup:/*Load return address and jump to kernel*/ldr r0, =(INF_REG_BASE+INF_REG0_OFFSET)ldr r1, [r0]    /* r1 = physical address of s5pc110_cpu_resume function*/mov pc, r1      /*Jump to kernel */nopnop/** system_clock_init: Initialize core clock and bus clock.* void system_clock_init(void)*/
system_clock_init:ldr r0, =ELFIN_CLOCK_POWER_BASE @0xe0100000 将时钟的基地址装载如r0/* Set Mux to FIN */ldr r1, =0x0    @将0x00000000装入r1str r1, [r0, #CLK_SRC0_OFFSET]  @将r1内的值装入地址为(r0内的值+CLK_SRC0_OFFSET = 0xe0100200)的内存(即Clock Source Control Registers)/*上面一段的作用是将Clock Source Control Registers值清空*具体的作用是将VPLL_SEL、EPLL_SEL、MPLL_SEL和APLL_SEL的时钟源设置为FINVPLL,将MUX_MSYS_SEL、MUX_DSYS_SEL和MUX_PSYS_SEL时钟源设置为SCLKMPLL*将ONENAND_SEL时钟源设置为HCLK_PSYS*为什么这样设置,因为未设置 PLL 和各种分频系数之前,我们不能使用 PLL,为了保险起见,暂时直接使用频率较低*的外接的 24MHz 晶振,待设置好 PLL 和分频系数后再重新设置各种时钟开关*/ldr r1, =APLL_LOCKTIME_VAL  @将APLL_LOCKTIME_VAL(0x2cf)装入r1str r1, [r0, #APLL_LOCK_OFFSET] @将r1内的值装入地址为(r0内的值+CLK_SRC0_OFFSET = 0xe0100000)的内存,即设置APLL的锁定周期/**下面是原文对这个步骤的解释,本人不才,不能很好的翻译过来,只能照抄誊录,希望高手空闲的时候能帮忙翻译一下*A PLL requires locking period when input frequency is changed or frequency division (multiplication) values are*changed.PLL_LOCK register specifies this locking period, which is based on PLL’s source clock. During this*period, output will be low state*//* Disable PLL */ldr r1, =0x0str r1, [r0, #APLL_CON0_OFFSET] @将APLL控制寄存器的值清空,这个寄存器的第31位置零关闭APLL 25-16bit配置MDIV的分频 /**13-8bit配置PDIV的分频 2-0bit配置SDIV的分频*/ ldr r1, =0x0str r1, [r0, #MPLL_CON_OFFSET]  @配置MPLLldr r1, =0x0str r1, [r0, #MPLL_CON_OFFSET]  @?为什么再次配置,查看数据手册没有提到需要配置两次ldr     r1, [r0, #CLK_DIV0_OFFSET]  @Clock Divider Control Register(0xe0100300)ldr r2, =CLK_DIV0_MASK  @CLK_DIV0_MASK(0x7fffffff)bic r1, r1, r2  @首先清零ldr r2, =CLK_DIV0_VAL   @CLK_DIV0_VALorr r1, r1, r2str r1, [r0, #CLK_DIV0_OFFSET]/**CLK_DIV0_VAL = ((0<<APLL_RATIO)|(4<<A2M_RATIO)|(4<<HCLK_MSYS_RATIO)|(1<<PCLK_MSYS_RATIO)\*   |(3<<HCLK_DSYS_RATIO)|(1<<PCLK_DSYS_RATIO)|(4<<HCLK_PSYS_RATIO)|(1<<PCLK_PSYS_RATIO))*#define APLL_RATIO 0*#define A2M_RATIO  4*#define HCLK_MSYS_RATIO    8*#define PCLK_MSYS_RATIO    12*#define HCLK_DSYS_RATIO    16*#define PCLK_DSYS_RATIO 20*#define HCLK_PSYS_RATIO    24*#define PCLK_PSYS_RATIO 28*/ldr r1, =APLL_VALstr r1, [r0, #APLL_CON0_OFFSET]ldr r1, =MPLL_VALstr r1, [r0, #MPLL_CON_OFFSET]ldr r1, =VPLL_VALstr r1, [r0, #VPLL_CON_OFFSET]
#if defined(CONFIG_EVT1)ldr r1, =AFC_ONstr r1, [r0, #APLL_CON1_OFFSET]
#endifmov r1, #0x10000
1:  subs    r1, r1, #1  @延时 将r1-1的值存入r1bne 1b  @如果运算结果不等零(即CPSR寄存器标志位Z不等于一),退回到前面标签“1”处执行  当 CPSR 寄存器中的 Z @条件码置位时(即前面的计算结果为零),则顺序执行(即运行接下来的:ldr   r1, [r0, #CLK_SRC0_OFFSET])@当计算结果为零时,Z为1ldr r1, [r0, #CLK_SRC0_OFFSET]  @Clock Source Control Registers(0xe0100200)ldr r2, =0x10001111 @orr r1, r1, r2  @ONENAND时钟源为HCLK_DSYS MUX_PSYS_SEL时钟源为SCLKMPLL  MUX_DSYS_SEL时钟源为SCLKMPLL  MUX_MSYS_SEL时钟源为SCLKAPLL@VPLL_SEL时钟源为FOUTVPLL   EPLL_SEL时钟源为FOUTEPLL    MPLL_SEL时钟源为FOUTMPLL APLL_SEL时钟源为FOUTAPLLstr r1, [r0, #CLK_SRC0_OFFSET]  @装载#if defined(CONFIG_MCP_AC)  @210没有定义,暂时不分析/* CLK_SRC6[25:24] -> OneDRAM clock sel = MPLL */ldr r1, [r0, #CLK_SRC6_OFFSET]bic r1, r1, #(0x3<<24)orr r1, r1, #0x01000000str r1, [r0, #CLK_SRC6_OFFSET]/* CLK_DIV6[31:28] -> 4=1/5, 3=1/4(166MHZ@667MHz), 2=1/3 */ldr r1, [r0, #CLK_DIV6_OFFSET]bic r1, r1, #(0xF<<28)bic r1, r1, #(0x7<<12)  @; ONENAND_RATIO: 0orr r1, r1, #0x30000000str r1, [r0, #CLK_DIV6_OFFSET]#elif defined (CONFIG_MCP_H)/* CLK_SRC6[25:24] -> OneDRAM clock sel = 00:SCLKA2M, 01:SCLKMPLL */ldr r1, [r0, #CLK_SRC6_OFFSET]bic r1, r1, #(0x3<<24)orr r1, r1, #0x00000000str r1, [r0, #CLK_SRC6_OFFSET]/* CLK_DIV6[31:28] -> 4=1/5, 3=1/4(166MHZ@667MHz), 2=1/3 */ldr r1, [r0, #CLK_DIV6_OFFSET]bic r1, r1, #(0xF<<28)bic r1, r1, #(0x7<<12)  @; ONENAND_RATIO: 0orr r1, r1, #0x00000000str r1, [r0, #CLK_DIV6_OFFSET]#elif defined (CONFIG_MCP_B) || defined (CONFIG_MCP_D)/* CLK_SRC6[25:24] -> OneDRAM clock sel = 00:SCLKA2M, 01:SCLKMPLL */ldr r1, [r0, #CLK_SRC6_OFFSET]bic r1, r1, #(0x3<<24)orr r1, r1, #0x01000000str r1, [r0, #CLK_SRC6_OFFSET]/* CLK_DIV6[31:28] -> 4=1/5, 3=1/4(166MHZ@667MHz), 2=1/3 */ldr r1, [r0, #CLK_DIV6_OFFSET]bic r1, r1, #(0xF<<28)bic r1, r1, #(0x7<<12)  @; ONENAND_RATIO: 0orr r1, r1, #0x30000000str r1, [r0, #CLK_DIV6_OFFSET]#elif defined (CONFIG_MCP_SINGLE)   @定义了这个,我们进行分析/* CLK_DIV6 */ldr r1, [r0, #CLK_DIV6_OFFSET]  @设置分频   Clock Divider Control Register(0xe0100318)bic r1, r1, #(0x7<<12)  @; ONENAND_RATIO: @0DIVFLASH clock divider ratio,计算公式:SCLK_ONENAND = MOUTFLASH / (ONENAND_RATIO + 1)str r1, [r0, #CLK_DIV6_OFFSET]#endifmov pc, lr  @打完收功!/** uart_asm_init: Initialize UART in asm mode, 115200bps fixed.* void uart_asm_init(void)*/
uart_asm_init:/* set GPIO(GPA) to enable UART 没什么可说的,串口引脚复用设置*/@ GPIO setting for UARTldr r0, =ELFIN_GPIO_BASEldr r1, =0x22222222str     r1, [r0, #GPA0CON_OFFSET]ldr     r1, =0x2222str     r1, [r0, #GPA1CON_OFFSET]@ HP V210 use. SMDK not use.
#if defined(CONFIG_VOGUES)ldr    r1, =0x100str    r1, [r0, #GPC0CON_OFFSET]ldr    r1, =0x4str    r1, [r0, #GPC0DAT_OFFSET]
#endifldr r0, =ELFIN_UART_CONSOLE_BASE        @0xE2900000mov r1, #0x0str r1, [r0, #UFCON_OFFSET] @0xE2900008 UART FIFO Control Register 在这里关闭了FIFO功能str r1, [r0, #UMCON_OFFSET] @0xE290000c UART Modem Control Register 在这里关闭了AFL(Auto Flow Control硬件流控制)和中断mov r1, #0x3str r1, [r0, #ULCON_OFFSET] @0xE2900000 UART Line Control Register  在这里采用8bit 1个停止位 无奇偶校验 ldr r1, =0x3c5str r1, [r0, #UCON_OFFSET]  @0xE2900000 UART Control Register   ldr r1, =UART_UBRDIV_VAL    @波特率设置str r1, [r0, #UBRDIV_OFFSET]    @0xE2900028ldr r1, =UART_UDIVSLOT_VAL  @较细一些分频,用于补偿str r1, [r0, #UDIVSLOT_OFFSET]ldr r1, =0x4f4f4f4fstr r1, [r0, #UTXH_OFFSET]      @'O'    @打印“O”mov pc, lr/** Nand Interface Init for SMDKC110*/
nand_asm_init:/* Setting GPIO for NAND *//* This setting is NAND initialze code at booting time in iROM. */@设置IO BASEldr r1, [r0, #MP01CON_OFFSET]bic r1, r1, #(0xf<<8)orr r1, r1, #(0x3<<8)str r1, [r0, #MP01CON_OFFSET]ldr r1, [r0, #MP01PUD_OFFSET]bic r1, r1, #(0x3<<4)str r1, [r0, #MP01PUD_OFFSET]ldr r1, [r0, #MP03CON_OFFSET]bic r1, r1, #0xFFFFFFldr r2, =0x22222222orr r1, r1, r2str r1, [r0, #MP03CON_OFFSET]ldr r1, [r0, #MP03PUD_OFFSET]ldr r2, =0x3fffbic r1, r1, r2str r1, [r0, #MP03PUD_OFFSET]ldr r0, =ELFIN_NAND_BASE    @0xB0E00000ldr r1, [r0, #NFCONF_OFFSET]    @Nand Flash Configuration Register  0xB0E00000ldr r2, =0x1412         @smart210对应的NANDFlash是每页是2K 从nand的数据手册可知,需要4个周期所以bit2设置为1 同样bit2选择page大小为2K/*可知nand类型是SLC,bit3设置为0(PS:事实上,原版的不是这样的,选择的是MLC,我这里为了适应我的板子,改为SLC,各位看官可以根据具体*情况自我修改)bit[7-4]TWRPH1 设置nand的延时,公式为:Duration = HCLK x ( TWRPH1 + 1 )   这里设置为b0001*bit[11-8]TWRPH0 设置nand的延时,公式为:Duration = HCLK x ( TWRPH0 + 1 ) 这里设置为b0100*[15:12]  CLE and ALE duration 公式:Duration = HCLK x TACLS 设置为b0001*/bic r1, r1, r2ldr r2, =0x1412@原来是0x7772   ldr r2, =NFCONF_VAL  我对应我的板子做了修改    orr r1, r1, r2str r1, [r0, #NFCONF_OFFSET]ldr r1, [r0, #NFCONT_OFFSET]ldr r2, =0x707C7bic r1, r1, r2ldr r2, =NFCONT_VAL @NFCONT_VAL  (0<<18)|(0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(0x3<<1)|(1<<0)orr r1, r1, r2str r1, [r0, #NFCONT_OFFSET]/*??蔿?誶???蝦????NFCONF_OFFSET]orr r1, r1, #0x70orr r1, r1, #0x7700str     r1, [r0, #NFCONF_OFFSET]ldr r1, [r0, #NFCONT_OFFSET]orr r1, r1, #0x03str     r1, [r0, #NFCONT_OFFSET]*/mov pc, lr/** Setting TZPC[TrustZone Protection Controller]*/
tzpc_init:ldr r0, =ELFIN_TZPC0_BASEmov r1, #0x0str r1, [r0]mov r1, #0xffstr r1, [r0, #TZPC_DECPROT0SET_OFFSET]str r1, [r0, #TZPC_DECPROT1SET_OFFSET]str r1, [r0, #TZPC_DECPROT2SET_OFFSET]ldr     r0, =ELFIN_TZPC1_BASEstr r1, [r0, #TZPC_DECPROT0SET_OFFSET]str r1, [r0, #TZPC_DECPROT1SET_OFFSET]str r1, [r0, #TZPC_DECPROT2SET_OFFSET]ldr r0, =ELFIN_TZPC2_BASEstr r1, [r0, #TZPC_DECPROT0SET_OFFSET]str r1, [r0, #TZPC_DECPROT1SET_OFFSET]str r1, [r0, #TZPC_DECPROT2SET_OFFSET]str r1, [r0, #TZPC_DECPROT3SET_OFFSET]ldr r0, =ELFIN_TZPC3_BASEstr r1, [r0, #TZPC_DECPROT0SET_OFFSET]str r1, [r0, #TZPC_DECPROT1SET_OFFSET]str r1, [r0, #TZPC_DECPROT2SET_OFFSET]mov pc, lr/** OneNAND Interface Init*/
onenandcon_ 癷譶胕觮OneNAND ?肎覲?蝧etting for OneNANDldr r0, =ELFIN_GPIO_BASE    @0xE0200000ldr r1, [r0, #MP01CON_OFFSET]orr r1, r1, #0x00550000str r1, [r0, #MP01CON_OFFSET]ldr r1, [r0, #MP03CON_OFFSET]orr r1, r1, #0x0550orr r1, r1, #0x00550000str r1, [r0, #MP03CON_OFFSET]ldr r1, =0xFFFFstr r1, [r0, #MP01DRV_SR_OFFSET]str r1, [r0, #MP03DRV_SR_OFFSET]str r1, [r0, #MP06DRV_SR_OFFSET]str r1, [r0, #MP07DRV_SR_OFFSET]wait_orwb:@; Read ONENAND_IF_STATUSldr r0, =ELFIN_ONENANDCON_BASE  @; 0xB0600000ldr r1, [r0, #ONENAND_IF_STATUS_OFFSET]bic r1, r1, #0xFFFFFFFEcmp r1, #0x0@; ORWB != 0x0bne wait_orwb@; write new configuration to onenand system configuration1 registerldr r1, =0xF006         @; Sync.ldr r2, =(ELFIN_ONENAND_BASE+0x1E442)   @; 0x1E442(REG_SYS_CONF1)strh    r1, [r2]@; read one dummy halfwordldrh    r1, [r2]ldrh    r1, [r2]@; write new configuration to ONENAND_IF_CTRLldr r0, =ELFIN_ONENANDCON_BASE  @; 0xB0600000@;ldr   r1, =0x2F006            @; ONENAND_IF_CTRL_REG_VAL (GCE off)ldr r1, =0x402F006          @; ONENAND_IF_CTRL_REG_VAL (GCE on)str r1, [r0, #ONENAND_IF_CTRL_OFFSET]mov pc, lr#ifdef CONFIG_ENABLE_MMU    @uboot没有开启mmu#ifdef CONFIG_MCP_SINGLE
/** MMU Table for SMDKC110* 0x0000_0000 -- 0xBFFF_FFFF => Not Allowed* 0xB000_0000 -- 0xB7FF_FFFF => A:0xB000_0000 -- 0xB7FF_FFFF* 0xC000_0000 -- 0xC7FF_FFFF => A:0x3000_0000 -- 0x37FF_FFFF* 0xC800_0000 -- 0xDFFF_FFFF => Not Allowed* 0xE000_0000 -- 0xFFFF_FFFF => A:0xE000_0000 -- 0XFFFF_FFFF*//* form a first-level section entry */
.macro FL_SECTION_ENTRY base,ap,d,c,b.word (\base << 20) | (\ap << 10) | \(\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1)
.endm
.section .mmudata, "a".align 14@ the following alignment creates the mmu table at address 0x4000..globl mmu_table
mmu_table:.set __base,0@ Access for iRAM.rept 0x100FL_SECTION_ENTRY __base,3,0,0,0.set __base,__base+1.endr@ Not Allowed.rept 0x200 - 0x100.word 0x00000000.endr.set __base,0x200@ should be accessed.rept 0x600 - 0x200FL_SECTION_ENTRY __base,3,0,1,1.set __base,__base+1.endr.rept 0x800 - 0x600.word 0x00000000.endr.set __base,0x800@ should be accessed.rept 0xb00 - 0x800FL_SECTION_ENTRY __base,3,0,0,0.set __base,__base+1.endr/*  .rept 0xc00 - 0xb00.word 0x00000000.endr */.set __base,0xB00.rept 0xc00 - 0xb00FL_SECTION_ENTRY __base,3,0,0,0.set __base,__base+1.endr.set __base,0x200@ 256MB for SDRAM with cacheable.rept 0xD00 - 0xC00FL_SECTION_ENTRY __base,3,0,1,1.set __base,__base+1.endr@ access is not allowed.@.rept 0xD00 - 0xC80@.word 0x00000000@.endr.set __base,0xD00@ 1:1 mapping for debugging with non-cacheable.rept 0x1000 - 0xD00FL_SECTION_ENTRY __base,3,0,0,0.set __base,__base+1.endr#else   @ CONFIG_MCP_AC, CONFIG_MCP_H, CONFIG_MCP_B/** MMU Table for SMDKC110* 0x0000_0000 -- 0xBFFF_FFFF => Not Allowed* 0xB000_0000 -- 0xB7FF_FFFF => A:0xB000_0000 -- 0xB7FF_FFFF* 0xC000_0000 -- 0xC7FF_FFFF => A:0x3000_0000 -- 0x37FF_FFFF* 0xC800_0000 -- 0xDFFF_FFFF => Not Allowed* 0xE000_0000 -- 0xFFFF_FFFF => A:0xE000_0000 -- 0XFFFF_FFFF*//* form a first-level section entry */
.macro FL_SECTION_ENTRY base,ap,d,c,b.word (\base << 20) | (\ap << 10) | \(\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1)
.endm
.section .mmudata, "a".align 14@ the following alignment creates the mmu table at address 0x4000..globl mmu_table
mmu_table:.set __base,0@ Access for iRAM.rept 0x100FL_SECTION_ENTRY __base,3,0,0,0.set __base,__base+1.endr@ Not Allowed.rept 0x300 - 0x100.word 0x00000000.endr.set __base,0x300@ should be accessed.rept 0x350 - 0x300FL_SECTION_ENTRY __base,3,0,1,1.set __base,__base+1.endr@ Not Allowed.rept 0x400 - 0x350.word 0x00000000.endr.set __base,0x400@ should be accessed.rept 0x500 - 0x400FL_SECTION_ENTRY __base,3,0,1,1.set __base,__base+1.endr.rept 0x800 - 0x500.word 0x00000000.endr.set __base,0x800@ should be accessed.rept 0xb00 - 0x800FL_SECTION_ENTRY __base,3,0,0,0.set __base,__base+1.endr.set __base,0xB00.rept 0xc00 - 0xb00FL_SECTION_ENTRY __base,3,0,0,0.set __base,__base+1.endr.set __base,0x300@ 80MB for SDRAM with cacheable.rept 0xC50 - 0xC00FL_SECTION_ENTRY __base,3,0,1,1.set __base,__base+1.endr@ Not Allowed.rept 0xD00 - 0xC50.word 0x00000000.endr.set __base,0xD00@ 1:1 mapping for debugging with non-cacheable.rept 0x1000 - 0xD00FL_SECTION_ENTRY __base,3,0,0,0.set __base,__base+1.endr#endif
#endif

如果你觉得写得还行,转载时请保留作者信息。作者:捷宇 邮箱:jayyuz@163.com

s5pv210 u-boot的那些事儿之---lowleve_init.S的分析相关推荐

  1. s5pv210 SD boot (1)

    奇怪的是,为什么折腾了2天多了,SD仍然不能升级. 在XP下:SD Flasher可以运行,但貌似并没有写进去. 在Win7虚拟机下:Relayout的时候,提示ERROR ReadOnly Medi ...

  2. s5pv210 u-boot的那些事儿之---mem_setup.S的分析

    接上一篇,这一篇写得是内存初始化.本人对ddr初始化,不是特别懂.只是勉强翻译注释.如有错误,希望高手能不吝赐教.废话不多说,贴上这该死的代码. /** armboot - Memory Initia ...

  3. Spring Boot下Druid连接池的使用配置分析

    引言: 在Spring Boot下默认提供了若干种可用的连接池,Druid来自于阿里系的一个开源连接池,在连接池之外,还提供了非常优秀的监控功能,这里讲解如何与Spring Boot实现集成. 1.  ...

  4. spring boot实战(第九篇)Application创建源码分析

    前言 通过前面的文章了解到在spring boot的启动时,利用的是编写的Application类,使用了注解@SpringBootApplication,本篇将阐述该Bean的加载过程. [html ...

  5. Spring Boot基础学习笔记02:Spring Boot项目单元测试、热部署与原理分析

    文章目录 零.学习目标 1.掌握Spring Boot单元测试实现 2.掌握Spring Boot热部署实现 3.熟悉Spring Boot基本原理 一.Spring Boot单元测试 (一)Spri ...

  6. FreeNOS-kernel目录下boot.S、链接脚本kernel.ld文件分析(四)

    上节提到过引导程序在将控制权交给内核时,相关寄存器状态已确定,并且程序入口地址为boot.S文件中的_start,下个面就来看看boot.S文件. kernel目录下文件如下: 其中Sconscrip ...

  7. 《深入实践Spring Boot》阅读笔记之三:核心技术源代码分析

    为什么80%的码农都做不了架构师?>>>    刚关注的朋友,可以回顾前两篇文章: 基础应用开发 分布式应用开发 上篇文章总结了<深入实践Spring Boot>的第二部 ...

  8. 滑动窗口限流 java_Spring Boot 的接口限流算法优缺点深度分析

    点击上方蓝色字体,选择"标星公众号" 优质文章,第一时间送达 上一篇:这300G的Java资料是我师傅当年给我的,免费分享给大家(已修复) 下一篇:昨天分享资料不小心把百度网盘深处 ...

  9. Spring Boot 的接口限流算法优缺点深度分析

最新文章

  1. 基于K8S构建企业级Jenkins CI/CD平台实战(二) 之 kubernetes-plugin 插件使用
  2. 数据结构-冒泡排序最优代码(C语言)
  3. 《赤壁》:吴宇森恶搞三国的经过
  4. CodeForces - 1321C Remove Adjacent(贪心+模拟)
  5. java8并行流_Java 8:CompletableFuture与并行流
  6. 谈谈.NET MVC QMVC高级开发
  7. 下列哪项属于正确的锁定计算机桌面,【2018年职称计算机考试WindowsXp练习题及答案1】- 环球网校...
  8. python二进制文件 删除尾部数据_在Python中读取和切片二进制数据文件的最快方法...
  9. ei拼音的四个声调对应的字_非常容易混淆的汉语拼音“er”,究竟特殊在哪里?孩子总是搞不懂...
  10. 将米转换为度(经纬度) 画圆上下多出来一些区域
  11. 50 岁程序员创业说:两个月提交 50 个 PR,三个月内融资 2000 万美元
  12. win7连接linux系统怎么样,win7系统连接linux的操作方法
  13. 运用Unity结合PolicyInjection实现拦截器[结合操作日志实例]
  14. libgdx游戏引擎开发笔记(八)SuperJumper游戏例子的讲解(篇二)---- 游戏界面跳转...
  15. 看服务器硬盘序列号,获得服务器硬件信息(CPUID、硬盘号、主板序列号、IP地址等)...
  16. uni.app H5(微信公众号定位) uni.getLocation
  17. 搭建3款远程开发环境:Pycharm、Jupyter notebook以及code-server
  18. stata实现经济生态的空间杜宾模型
  19. 嗨,我的技术论坛上线啦!
  20. 3D打印机主要元件入门

热门文章

  1. 高手进阶,终极内存技术指南——完整/进阶版 sdram内部原理
  2. 龙芯1C300B主板V3.4嵌入式开发学习笔记一
  3. 精益开发实战:用看板管理大型项目
  4. DEJA_VU3D - Cesium功能集 之 054-模拟火箭发射全过程
  5. APAX-5017PG 项目开发全程记录 - 调试篇
  6. 单机斗地主的一些内容(一)
  7. 程序员你有资格骄傲么?
  8. 什么是 Python?Python 基础编程入门指南
  9. 计算机应用的程序,计算机应用程序
  10. python环境变量配置(win10+Python27)