第2阶段——编写uboot之编译测试以及改进(3)

编译测试:

1.将写好的uboot复制到linux下面

2.make编译,然后将错误的地方修改,生成boot.bin

(编译出错的解决方案:http://www.cnblogs.com/lifexy/p/7326172.html)

3.通过make生成的反汇编来查看代码是否正确

4.通过oflash烧写到板子nand flash上

5.查看串口是否数据打印 

发现串口无数据,发现两处错误:

5.1在init.C中define定义 没有加大括号,没有定义volatile型

例如:

 #define NFCONF       *((unsigned long *)0x4E000000)  

需要改为: #define NFCONF      (*((volatile unsigned long *)0x4E000000) )

5.2 在init.C中nand_read_addr()函数出错,代码如下:

void nand_read_addr(unsigned int addr)
{
   volatile int i;
   NFADDR=( addr>>0)&0xff;         //A7~A0        
   for(i=0;i<10;i++);
   NFADDR=( addr>>8)&0x0f;         //A11~A8
   for(i=0;i<10;i++);
   NFADDR=( addr>>12)&0xff;         //A19~A12
   for(i=0;i<10;i++);

   NFADDR=( addr>>20)&0xff;         //A27~A20
   for(i=0;i<10;i++);

   NFADDR=( addr>>28)&0xff;         //A28
   for(i=0;i<10;i++);  
}

上面之所以错是因为nand flash是2048B一页,这里的写的一页是A11~A0,其值=4096,已经属于两页大小了

应该改为:

void nand_read_addr(unsigned int addr)
{
   unsigned int col  = addr % 2048;
   unsigned int page = addr / 2048;
   volatile int i;
   NFADDR=(col>>0)&0xff;         //A7~A0
   for(i=0;i<10;i++);
   NFADDR=(col>>8)&0x0f;         //A10~A8
   for(i=0;i<10;i++);
   NFADDR=(page>>0)&0xff;         //A18~A11
   for(i=0;i<10;i++); 
   NFADDR=(page>>8)&0xff;         //A26~A19
   for(i=0;i<10;i++);
   NFADDR=(page>>16)&0xff;         //A27
   for(i=0;i<10;i++);   
}

优化改进(加快内核启动时间)

1 提高CPU频率

将CPU频率设为最大值400MHZ(内核启动时间7S变为6S,因为HCLK和PCLK频率没有改变)

然后分频系数FCLK:HCLK:PCLK需要设置为1:4:8

因为HCLK最高133MHZ,这里需要设置为100MHZ

PCLK最高50MHZ,这里需要设置为50HZ

如下图所示,得出 CLKDIVN寄存器需要等于0X5即可

通过下图看出,提高CPU频率需要设置MPLLCON中MDIV、PDIV、SDIV

通过下图得出,取400MHZ时,设置MDIV为0X5C,PDIV为0x1,SDIV为0x1

所以改进代码如下:

#define S3C2440_MPLL_400MHZ     ((0x5c<<12)|(0x01<<4)|(0x01))  //设置FCLK=400MHZ
/*    2.设置时钟(必须设为异步总线模式)  */
   ldr r0,=CLKDIVN
   mov r1,#5                                  /*FCLK:HCLK:PCLK=1:4:8*/
   str r1,[r0]
   mrc p15, 0, r1, c1, c0                 /* 读出控制寄存器 */
   orr  r1, r1, #0xc0000000               /* 设置为“asynchronous bus mode” */
   mcr   p15, 0, r1, c1, c0, 0               /* 写入控制寄存器 */

   ldr r0,=MPLLCON
   ldr r1,= S3C2440_MPLL_400MHZ      //使用复杂的数不能用mov,需要用ldr
   str r1,[r0]

2.开启ICAHE(内核启动时间6S变为1.5S)

CAHE介绍:通过高速缓存存储器来加快对内存的数据访问,在CAHE中有ICAHE(指令缓存)和DCAHE(数据缓存)

ICAHE: 指令缓存,用来存放执行这些数据的指令

DCAHE:用来存放数据,需要开启MMU才能开启DCAHE

在没开启ICAHE之前,CPU读取SDRAM地址数据时,每次都需要先访问一次地址值,在读数据.当开了ICAHE后,第一次读取SDRAM地址数据时,ICAHE发现缓存里没有这个地址数据,然后将SDRAM中需要读取的那部分一大块内存数据都复制在缓存中,后面陆续读取数据就不会再访问SDRAM了,直到CPU没有找到地址数据后ICAHE再从SDRAM中重新复制 

通过CP15协处理器来开启ICAHE

 (CP15协处理器操作用法:  http://www.cnblogs.com/lifexy/p/7203786.html)

从上面链接中可以找到ICAHE控制位在CP15的寄存器C1中位12(如下图), 然后通过MRS和MSR向该位12置1,开启ICAHE

所以代码如下(放在SDRAM初始化之前)

   mrc p15, 0, r0, c1, c0, 0                     //将 CP15 的寄存器 C1 的值读到 r0 中
   orr r0, r0, #(1<<12)                          //将r0中位12置1     
   mcr p15,0, r0,c1,c0,0                         //开启ICAHE

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏熊二哥

快速入门系列--WCF--07传输安全、授权与审核

这部分主要涉及企业级应用的安全问题,一般来说安全框架主要提供3个典型的安全行为:认证、授权和审核。除了典型的安全问题,对于一个以消息作为通信手段的分布式应用,还...

1709
来自专栏原创

个推推送Android问题检测

1、获取不到CID问题: 1.      查看配置文件是否有问题,appkey、appsecret、appid是否有空格存在。 2.      相关权限是否全部...

4687
来自专栏FreeBuf

如何设置自己的Dionaea蜜罐来收集恶意软件样本

许多安全人员都热衷于恶意软件的逆向工程。在本文中我将教大家设置一个自己的Dionaea蜜罐,来协助我们恶意软件样本的收集工作。

1134
来自专栏静下来

Unix/Linux系统安全检查工具Lynis 2.1.0发布

Lynis是针对Unix/Linux的开源安全检查工具,可以发现潜在的系统安全威胁。这个工具覆盖可疑文件监测、漏洞、恶意程序扫描、配置错误等,同时扩展性非常优秀...

2867
来自专栏FreeBuf

收集各类安全设备、Nginx日志实现日志统一管理及告警

近来安全测试项目较少,想着把安全设备、nginx日志收集起来并告警, 话不多说,直接说重点,搭建背景:

1507
来自专栏龙渊阁测试精英

入侵常用端口详解

第三方通用组件漏洞struts thinkphp jboss ganglia zabbix 

1292
来自专栏gaoqin31

redis故障记录

最近线上的redis出现无法访问的现象,redis-cli能进入,但是任何命令都提示需要密码验证,以前一直都没有设置密码的,重启redis后正常,没过多久又出现...

1222
来自专栏JAVA同学会

CAS与OAuth2的区别

  CAS客户端要获取的最终信息是,这个用户到底有没有权限访问我(CAS客户端)的资源。

902
来自专栏尚国

如何通过审计安全事件日志检测密码喷洒(Password Spraying)攻击

许多渗透测试人员和攻击者通常都会使用一种被称为“密码喷洒(Password Spraying)”的技术来进行测试和攻击。对密码进行喷洒式的攻击,这个叫法很形象,...

663
来自专栏Seebug漏洞平台

披着狼皮的羊——寻找惠普多款打印机中的RCE漏洞

原文:https://foxglovesecurity.com/2017/11/20/a-sheep-in-wolfs-clothing-finding-rce...

823

扫码关注云+社区