MMU 裸机程序

来自:http://blog.sina.com.cn/s/blog_49d9a0820100e37l.html

一级页表

head.S//

@*************************************************************************
@ File:head.S
@ 功能:设置SDRAM,将第二部分代码复制到SDRAM,设置页表,启动MMU,

     然后跳到SDRAM继续执行
@************************************************************************* 
     

.text
.global _start
_start:
 
   ldr sp,=4096                      @ 设置栈指针,以下都是C函数,调用前需要设好栈
 
   bldisable_watch_dog              @ 关闭WATCHDOG,否则CPU会不断重启
 
   blmemsetup                       @ 设置存储控制器以使用SDRAM
 
   blcopy_2th_to_sdram              @ 将第二部分代码复制到SDRAM
 
   blcreate_page_table              @ 设置页表
 
   blmmu_init                       @ 启动MMU
 
   ldr sp,=0xB4000000                @ 重设栈指针,指向SDRAM顶端(使用虚拟地址)
 
   ldr pc,=0xB0004000                @ 跳到SDRAM中继续执行第二部分代码
halt_loop:
 
    halt_loop

//init.c//



#defineWTCON 
         (*(volatile unsigned long *)0x53000000)

#defineMEM_CTL_BASE 
  0x48000000



void disable_watch_dog(void)
{
 
   WTCON = 0;// 关闭WATCHDOG很简单,往这个寄存器写0即可
}


void memsetup(void)
{
 
  
 
   unsignedlong const   mem_cfg_val[]={0x22011110,    //BWSCON
 
                                          0x00000700,    //BANKCON0
 
                                          0x00000700,    //BANKCON1
 
                                          0x00000700,    //BANKCON2
 
                                          0x00000700,    //BANKCON3
 
                                          0x00000700,    //BANKCON4
 
                                          0x00000700,    //BANKCON5
 
                                          0x00018005,    //BANKCON6
 
                                          0x00018005,    //BANKCON7
 
                                          0x008C07A3,    //REFRESH
 
                                          0x000000B1,    //BANKSIZE
 
                                          0x00000030,    //MRSRB6
 
                                          0x00000030,    //MRSRB7
 
                                  };
 
  int    i = 0;
 
   volatileunsigned long *p = (volatile unsigned long *)MEM_CTL_BASE;
 
   for(; i< 13; i++)
 
      p[i] = mem_cfg_val[i];
}


void copy_2th_to_sdram(void)
{
 
   unsigned int*pdwSrc = (unsigned int *)2048;
 
   unsigned int*pdwDest = (unsigned int *)0x30004000;
 
  
 
   while(pdwSrc < (unsigned int *)4096)
 
   {
 
      *pdwDest = *pdwSrc;
 
      pdwDest++;
 
      pdwSrc++;
 
   }
}


void create_page_table(void)
{


#defineMMU_FULL_ACCESS 
   (3 <<10)  
#defineMMU_DOMAIN 
        (0 <<5)   
#defineMMU_SPECIAL 
       (1 <<4)   
#defineMMU_CACHEABLE 
     (1 <<3)   
#defineMMU_BUFFERABLE 
    (1 <<2)   
#defineMMU_SECTION 
       (2)        
#defineMMU_SECDESC 
       (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | \
 
                           MMU_SECTION)
#defineMMU_SECDESC_WB 
    (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | \
 
                           MMU_CACHEABLE | MMU_BUFFERABLE | MMU_SECTION)
#defineMMU_SECTION_SIZE 
  0x00100000

 
   unsignedlong virtuladdr, physicaladdr;
 
   unsignedlong *mmu_tlb_base = (unsigned long *)0x30000000;
 
  
 
  
 
   virtuladdr =0;
 
   physicaladdr= 0;
 
  *(mmu_tlb_base + (virtuladdr >> 20))= (physicaladdr & 0xFFF00000) | \
 
                                          MMU_SECDESC_WB;

//从SDRAM的开始存放页表,将虚拟地址0对应的物理地址0的页表创建好,当我们以后对这个虚拟地址操作的时候,MMU可以为我们在这个页表也找到相应的物理地址。
 
  
 
   virtuladdr =0xA0000000;
 
   physicaladdr= 0x56000000;
 
  *(mmu_tlb_base + (virtuladdr >> 20))= (physicaladdr & 0xFFF00000) | \
 
                                          MMU_SECDESC;

 
  
 
   virtuladdr =0xB0000000;
 
   physicaladdr= 0x30000000;
 
   while(virtuladdr < 0xB4000000)
 
  {创建好了页表以后
 
      *(mmu_tlb_base + (virtuladdr >> 20))= (physicaladdr & 0xFFF00000) | \
 
                                              MMU_SECDESC_WB;
 
      virtuladdr += 0x100000;
 
      physicaladdr += 0x100000;
 
   }
}


void mmu_init(void)
{
 
   unsignedlong ttb = 0x30000000;

__asm__(
 
  "mov    r0,#0\n"
 
  "mcr    p15, 0,r0, c7, c7,0\n"   
 
  
 
  "mcr    p15, 0,r0, c7, c10, 4\n"  
 
  "mcr    p15, 0,r0, c8, c7,0\n"   
 
  
 
  "mov    r4,%0\n"                  
 
  "mcr    p15, 0,r4, c2, c0,0\n"   
 
  
 
  "mvn    r0,#0\n"                  
 
  "mcr    p15, 0,r0, c3, c0,0\n"      
 
  
 
  "mrc    p15, 0,r0, c1, c0,0\n"   
 
  
 
  
 
  
 
  
 
                                      
 
  "bic    r0, r0,#0x3000\n"         
 
  "bic    r0, r0,#0x0300\n"         
 
  "bic    r0, r0,#0x0087\n"         

 
  
 
  "orr    r0, r0,#0x0002\n"         
 
  "orr    r0, r0,#0x0004\n"         
 
  "orr    r0, r0,#0x1000\n"         
 
  "orr    r0, r0,#0x0001\n"         
 
  
 
  "mcr    p15, 0,r0, c1, c0,0\n"   
 
   :
 
   : "r" (ttb));
}

/mmu.lds/
SECTIONS
{
 
      first0x00000000 : {head.o init.o} #first
 
      second0xB0004000 : AT(2048) {leds.o}#指定这个段在编译出来的映像文件中的地址-加载地址。如果不使用这个选项,并且不指定0xB0004000,则加载地址等于运行地址,否则指定了 0xB0004000是不相同的。通过这个选项。可以控制各段分别保存输出文件中不同的位置。这里指定leds.o保存在映像文件的2048这个起始地址,而0xB0000000这个是段重定位地址,也称为运行地址,它是个虚拟地址。
}

///Makefile/
objs := head.o init.o leds.o

mmu.bin : $(objs)
 
  arm-softfloat-linux-gnu-ld -Tmmu.lds -o mmu_elf $^
 
  arm-softfloat-linux-gnu-objcopy -O binary -S mmu_elf $@
 
  arm-softfloat-linux-gnu-objdump -D -m arm mmu_elf >mmu.dis
 
  
%.o:%.c
 
  arm-softfloat-linux-gnu-gcc -Wall -O2 -c -o $@$<

%.o:%.S
 
  arm-softfloat-linux-gnu-gcc -Wall -O2 -c -o $@$<

clean:
 
   rm -fmmu.bin mmu_elf mmu.dis*.o      

leds.c///


#defineGPFCON 
    (*(volatile unsigned long*)0xA0000050)    // 物理地址0x56000050
#defineGPFDAT 
    (*(volatile unsigned long*)0xA0000054)    // 物理地址0x56000054

#defineGPF4_out 
  (1<<(4*2))
#defineGPF5_out 
  (1<<(5*2))
#defineGPF6_out 
  (1<<(6*2))
#defineGPF7_out 
  (1<<(7*2))


static inline void wait(unsigned long dly)
{
 
   for(; dly> 0; dly--);
}

int main(void)
{
 
   unsignedlong i = 0;
 
  
 
   //将LED1-4对应的GPF4/5/6/7四个引脚设为输出
 
   GPBCON =GPF4_out|GPF5_out|GPF6_out|GPF7_out;      

 
  while(1){
 
      wait(300000);
 
      GPBDAT =(~(i<<4));    // 根据i的值,点亮LED1-4
 
      if(++i == 16)
 
          i = 0;
 
   }

 
   return0;
}

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值