三、位置判断与代码搬移

news/2024/4/30 3:16:18/文章来源:https://blog.csdn.net/liutit/article/details/130034324

判断当前位置

判断当前位置是否在SDRAM

# < cpu\arm920t\start.S >

relocate1: /* relocate U-Boot to RAM    */

adr r0, _start /* r0 <- current position of code   */

ldr r1, _TEXT_BASE /* test if we run from flash or RAM */

cmp r0, r1 /* don't reloc during debug         */

beq stack_setup

判断当前位置为Nand还是Nor Flash

# < cpu\arm920t\start.S >

ldr r1, =0x4000003c

mov r0, #0

str r0, [r1]

// mov r1, #0x3c

ldr r1, =0x4000003c

ldr r0, [r1]

cmp r0, #0

bne relocate2

/**/

ldr r0, =0xdeadbeef

ldr r1, =0x4000003c

str r0, [r1]

说明:

从地址总线可以看出,Nor和Nand启动的区别为BootSRAM位置,所以判断0x40000000-0x40000FFFF是否可以存储数据,就可以知道是不是Nor启动

Nand Boot

# < cpu\arm920t\start.S >

/***************************NAND BOOT*****************************/

#define LENGTH_UBOOT 0x40000

#define NAND_CTL_BASE 0x4e000000

#define oNFCONF 0x00

#define oNFCONT 0x04

#define oNFCMD 0x08

#define oNFSTAT 0x20

/*reset NAND*/

mov r1, #NAND_CTL_BASE

ldr r2, =((2<<12)|(1<<8)|(1<<4)|(0<<0))

str r2, [r1, #oNFCONF]

ldr r2, =((1<<4)|(0<<1)|(1<<0))

str r2, [r1, #oNFCONT]

ldr r2, =0x6

str r2, [r1, #oNFSTAT]

mov r2, #0xff

strb r2, [r1, #oNFCMD]

mov r3, #0

nand1:

add r3, r3, #0x01

cmp r3, #0xa

blt nand1

nand2:

ldr r2, [r1, #oNFSTAT]

tst r2, #0x4

beq nand2

ldr r2, [r1, #oNFCONT]

orr r2, r2, #0x02

str r2, [r1, #oNFCONT]

ldr sp, DW_STACK_START

mov fp, #0

ldr r0, =TEXT_BASE

mov r1, #0x0

mov r2, #LENGTH_UBOOT

bl nand_read_ll

tst r0, #0x0

beq ok_nand_read

bad_nand_read:

loop2:

b loop2

ok_nand_read:

mov r0, #0

ldr r1, =TEXT_BASE

mov r2, #0x400

go_next:

ldr r3, [r0], #4

ldr r4, [r1], #4

teq r3, r4

bne notmatch

subs r2, r2, #4

beq stack_setup

bne go_next

notmatch:

loop3:

b loop3

/* Set up the stack    */

stack_setup:

ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot   */

sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area              */

sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                 */

#ifdef CONFIG_USE_IRQ

sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

#endif

sub sp, r0, #12 /* leave 3 words for abort-stack    */

clear_bss:

ldr r0, _bss_start /* find start of bss segment        */

ldr r1, _bss_end /* stop here                        */

mov r2, #0x00000000 /* clear                            */

clbss_l:

str r2, [r0] /* clear loop...                    */

add r0, r0, #4

cmp r0, r1

ble clbss_l

ldr pc, _start_armboot

_start_armboot: .word start_armboot

NFCONF(指令周期)

    mov r1, #NAND_CTL_BASE

    ldr r2, =((2<<12)|(1<<8)|(1<<4))

    str r2, [r1, #oNFCONF]

周期(HCLK: 100M)

TACLS = 2*HCLK=20ns > 0 ns

TWRPH0 = (1+1)*HCLK=20ns > 12 ns

TWRPH1 = (1+1)*HCLK=20ns > 5 ns

 

 

 

 

 NFCONT(配置使能Nand Flash)

    ldr r2, =((1<<4)|(0<<1)|(1<<0))

    str r2, [r1, #oNFCONT]

初始化ECC(错误校验)

使能片选

Nand Flash控制器使能

 

NFSTAT(Nand Flash状态)

    ldr r2, =0x6

    str r2, [r1, #oNFSTAT]

清除RnB

NFCMD(Nand Flash命令)

    mov r2, #0xff

    strb r2, [r1, #oNFCMD]

复位

片选、设置栈底、跳转c代码拷贝第二阶段

nand2:

        // 判断状态

ldr r2, [r1, #oNFSTAT]

tst r2, #0x4

beq nand2

        

        // 片选

ldr r2, [r1, #oNFCONT]

orr r2, r2, #0x02

str r2, [r1, #oNFCONT]

        // 设置栈顶

ldr sp, DW_STACK_START

mov fp, #0

        设置参数,跳转c代码

ldr r0, =TEXT_BASE

mov r1, #0x0

mov r2, #LENGTH_UBOOT

bl nand_read_ll

c代码拷贝第二阶段

# < board\vbird\mini2440\nand_read.c >

#include <common.h>

#include <linux/mtd/nand.h>

#define _REGb(x) (*(volatile unsigned char *)(x))

#define _REGw(x) (*(volatile unsigned short *)(x))

#define _REGi(x) (*(volatile unsigned int *)(x))

#define NF_BASE 0x4e000000

#define NFCONF _REGi(NF_BASE+0x0)

#define NFCONT _REGi(NF_BASE+0x04)

#define NFCMD _REGb(NF_BASE+0x8)

#define NFADDR _REGb(NF_BASE+0xc)

#define NFDATA _REGb(NF_BASE+0X10)

#define NFDATA16 _REGw(NF_BASE+0x10)

#define NFSTAT _REGb(NF_BASE+0x20)

#define NFSTAT_BUSY 1

#define nand_select() (NFCONT &= ~(1<<1))

#define nand_deselect() (NFCONT |= (1<<1))

#define nand_clear_RnB() (NFSTAT |= (1<<2))

static inline void nand_wait(void)

{

int i;

while (!(NFSTAT & NFSTAT_BUSY))

for (i=0; i<10; i++);

}

struct boot_nand_t{

int page_size;

int block_size;

int bad_block_offset;

};

static int is_bad_block(struct boot_nand_t *nand, unsigned long i)

{

unsigned char data;

unsigned long page_num;

nand_clear_RnB();

if (nand->page_size == 2048)

{

page_num=i>>11;

NFCMD = NAND_CMD_READ0;

NFADDR = nand->bad_block_offset&0xff;

NFADDR = (nand->bad_block_offset>>8)&0xff;

NFADDR = page_num & 0xff;

NFADDR = (page_num>>8)&0xff;

NFADDR = (page_num>>16)&0xff;

NFCMD  = NAND_CMD_READSTART;

}

else

{

return -1;

}

nand_wait();

data = (NFDATA & 0xff);

if (data != 0xff)

return 1;

return 0;

}

static int nand_read_page_ll(struct boot_nand_t *nand,

unsigned char *buf,

unsigned long addr)

{

unsigned char *ptr = (unsigned char *)buf;

unsigned int i, page_num;

nand_clear_RnB();

NFCMD = NAND_CMD_READ0;

if (nand->page_size == 2048)

{

page_num = addr>>11;

NFADDR = 0;

NFADDR = 0;

NFADDR = page_num & 0xff;

NFADDR = (page_num>>8) & 0xff;

NFADDR = (page_num>>16) & 0xff;

NFCMD = NAND_CMD_READSTART;

}

else

{

return -1;

}

nand_wait();

for (i=0; i<(nand->page_size); i++)

{

*ptr = NFDATA;

ptr++;

}

return nand->page_size;

}

static unsigned short nand_read_id()

{

unsigned short res = 0;

NFCMD = NAND_CMD_READID;

NFADDR = 0;

res = NFDATA;

res = (res<<8) | NFDATA;

return res;

}

extern unsigned int dynpart_size[];

int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)

{

int i, j;

unsigned short nand_id;

struct boot_nand_t nand;

/*chip Enable*/

nand_select();

nand_clear_RnB();

for (i=0; i<10; i++);

nand_id=nand_read_id();

nand.page_size = 2048;

nand.block_size = 128*1024;

nand.bad_block_offset = nand.page_size;

if ((start_addr&(nand.block_size-1)) || (size&(nand.block_size-1)))

return -1;

for (i=start_addr; i<(start_addr+size);)

{

j = nand_read_page_ll(&nand, buf, i);

i += j;

buf += j;

}

nand_deselect();

return 0;

}

设置栈、bss段、跳转第二阶段

# < cpu\arm920t\start.S >

stack_setup:

ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot   */

sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area              */

sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                 */

#ifdef CONFIG_USE_IRQ

sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

#endif

sub sp, r0, #12 /* leave 3 words for abort-stack    */

clear_bss:

ldr r0, _bss_start /* find start of bss segment        */

ldr r1, _bss_end /* stop here                        */

mov r2, #0x00000000 /* clear                            */

clbss_l:

str r2, [r0] /* clear loop...                    */

add r0, r0, #4

cmp r0, r1

ble clbss_l

ldr pc, _start_armboot

_start_armboot: .word start_armboot

Nor Boot

# < cpu\arm920t\start.S >

/*****************************CHECK_CODE_POSITION***************/

ldr r1, =0x4000003c

mov r0, #0

str r0, [r1]

mov r1, #0x3c

ldr r0, [r1]

cmp r0, #0

bne relocate2

/**/

ldr r0, =0xdeadbeef

ldr r1, =0x4000003c

str r0, [r1]

loop3:

b loop3

/*******************nor boot*********************/

relocate2:

ldr r1, =0xdeadbeef

cmp r0, r1

bne loop3

adr r0, _start

ldr r1, _TEXT_BASE

ldr r2, _armboot_start

ldr r3, _bss_start

sub r2, r3, r2

// stmia r1!, {r3-r10}

cmp r0, r2

ble copy_loop

ldr r2, _armboot_start

ldr r3, _bss_start

sub r2, r3, r2 /* r2 <- size of armboot            */

add r2, r0, r2 /* r2 <- source end address         */

copy_loop:

ldmia r0!, {r3-r10} /* copy from source address [r0]    */

stmia r1!, {r3-r10} /* copy to   target address [r1]    */

cmp r0, r2 /* until source end addreee [r2]    */

ble copy_loop

#endif /* CONFIG_SKIP_RELOCATE_UBOOT */

_armboot_start = _start 代码起始

_bss_start 代码结尾

_bss_start - _armboot_start 代码大小

拷贝:从_start,拷贝(_bss_start - _armboot_start )整个代码

copy_loop:

ldmia r0!, {r3-r10} /* copy from source address [r0]    */

stmia r1!, {r3-r10} /* copy to   target address [r1]    */

cmp r0, r2 /* until source end addreee [r2]    */

ble copy_loop

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_283817.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于支持向量机SVM的脑部肿瘤识别,脑电波样本熵提取

目录 支持向量机SVM的详细原理 SVM的定义 SVM理论 Libsvm工具箱详解 简介 参数说明 易错及常见问题 SVM应用实例,基于SVM的的脑部肿瘤识别分类预测 代码 结果分析 展望 支持向量机SVM的详细原理 SVM的定义 支持向量机(support vector machines, SVM)是一种二分类模型,它…

电视王者沦落到再度卖楼求生,家电巨头跌落神坛,凸显行业之囧

电视无疑是中国家电行业中做得最成功的行业之一&#xff0c;在国内市场将外资品牌挤压出市场&#xff0c;还走向了海外市场&#xff0c;不过有一家国内的电视企业如今却无奈再度卖楼求生&#xff0c;这家企业就是长虹。一、长虹的变幻长虹称雄国内电视市场出自上一任领导人倪润…

pytorch 线性回归总结

测试1(y3∗x1−4∗x2y3*x_{1}-4*x_{2}y3∗x1​−4∗x2​),lr1e-2 %matplotlib inline import torch import numpy as np torch.manual_seed(1) from torch.nn import Linear from torch.autograd import Variable import torch.nn as nn import random np.random.seed(1) rand…

Robocup 仿真2D 学习笔记(四)阵型编辑

一、阵型文件介绍 阵型文件里设置的是球员在比赛中的跑位点 基于helios base的阵型文件&#xff0c;在目录/src/formations-dt中 阵型的调用在/src/strategy.cpp 文件&#xff1a; before-kick-off.conf 是球员上场之后的阵型 &#xff08;或进球等待开球&#xff09; no…

049:cesium加载czml文件,显示图形

第049个 点击查看专栏目录 本示例的目的是介绍如何在vue+cesium中加载czml文件, 显示图形。这是官网的一个示例,这里转换了处理方式。 直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共78行)相关API参考:专栏目标示…

暴击一棵树——二叉树入门一(入门基础概念)

目录 1.树的概念 2.二叉树的概念 二叉树&#xff08;Binary Tree&#xff09; 满二叉树&#xff08;Full Binary Tree&#xff09; 完全二叉树&#xff08;Complete Binary Tree&#xff09; 3.堆和二叉树 4、二叉树的结构 1.二叉树的逻辑结构 2.二叉树的物理结构 1.树…

《钢琴调律师 五级》 笔记

声音产生的三个条件&#xff1a;物体振动、媒质传播、人耳接收 复合音&#xff1a;由一些频率不同的简谐成分合成的声音。大多数乐器都是复合音&#xff0c;因此才各有不同的音色特征 纯音&#xff1a;物体做简谐振动所产生的声音 乐音&#xff1a;指有较为明确音调感的声音。噪…

spark第七章:SparkStreaming实例

系列文章目录 系列文章目录 spark第一章&#xff1a;环境安装 spark第二章&#xff1a;sparkcore实例 spark第三章&#xff1a;工程化代码 spark第四章&#xff1a;SparkSQL基本操作 spark第五章&#xff1a;SparkSQL实例 spark第六章&#xff1a;SparkStreaming基本操作 spa…

javaEE+jsp820高校校园设备报修系统dzkfa9程序mysql

1&#xff0e;系统登录&#xff1a;系统登录是用户访问系统的路口&#xff0c;设计了系统登录界面&#xff0c;包括用户名、密码和验证码&#xff0c;然后对登录进来的用户判断身份信息&#xff0c;判断是管理员用户还是普通用户。 2&#xff0e;系统用户管理&#xff1a;不管是…

从C出发 13 --- 多维数组

数组的本质是数据集合&#xff0c;我们在程序里面操作数组&#xff0c;就是在操作数据 数组中的元素能不能是其他程序元素? 这个说法只是表示数组里面的元素是int 类型 而这个数组的类型是 int [5] 由元素类型和数组大小共同决定 int a[10] {0}; // a的类型 : int[10]…

文件小注意

目录 0 前言 1 标识 O_CREAT O_APPEND 2 ftruncate与truncate 3 O_DIRECT与O_DSYNC、O_SYNC 4 open与fopen 5 关于mmap 0 前言 文件操作在软件开发中是很常见的一件事。虽然与它相关的工作看起来不怎么起眼&#xff0c;无非就是通过通过open、read、write、close几个调用…

【MySQL】主从复制过程(实践)

1.安装好2台数据库服务器的系统&#xff0c;然后安装好MySQL软件 [rootjd-mysql ~]# mysql --version mysql Ver 14.14 Distrib 5.7.40, for linux-glibc2.12 (x86_64) using EditLine wrapper[rootjd-mysql-2 ~]# mysql --version …

第03章_用户与权限管理

第03章_用户与权限管理 1. 用户管理 ​ MysQL用户可以分为普通用户和root用户。root用户是超级管理员&#xff0c;拥有所有权限&#xff0c;包括创建用户 、删除用户和修改用户的密码等管理权限;普通用户只拥有被授予的各种权限。 MysQL提供了许多语句用来管理用户账号&#…

认识C++字符串复合类型

目录 前言&#xff1a; 1.数组 1.1C的数组 1.2C数组初始化 *2.字符串 2.1字符串与数组 2.2字符数组的存储 2.3字符串输入cin 2.4cin.getline() 2.5cin.get() 2.6函数重载例子 2.7混合输入数字和字符串 前言&#xff1a; C与C语言在内容上有些是一样的&#xff0c;也…

Zooker配置与测试

目录 1.介绍 2.配置 1.配置准备 2.配置修改 3.测试 1.介绍 2.配置 1.配置准备 zookeeper官网:Apache ZooKeeper &#xff08;1&#xff09;安装 JDK &#xff08;2&#xff09;拷贝 apache-zookeeper-3.5.7-bin.tar.gz 安装包到software目录下 &#xff08;3&#xff09;解…

mysql常用的基础命令

通过学习mysql命令提高数据处理和工作效率 基础命令 1.登录MySQL mysql -u root -p 2.查看当前系统所有数据库 show databases; 3.切换数据库 use 数据库名称 4.查看数据库下的所有表 show tables; 5.查看表结构&#xff1b; desc 表名&#xff1b; 6.创建数据库 crea…

CentOS7的下载、安装和配置(详细图解)

CentOS7安装包的下载 Centos7的安装包可以去官网&#xff08;https://www.centos.org/&#xff09;下载&#xff0c;但速度比较慢。 也可以用搜索引擎搜索国内镜像站点的安装包文件与官网同步&#xff0c;下载的速度非常快。 CentOS7软件安装包的分享 百度网盘分享&#xff…

python函数详解_INDEX函数

一. 函数的作用 函数就是将一段具有独立功能的代码块 整合到一个整体并命名&#xff0c;在需要的位置调用这个名称即可完成对应的需求。 函数在开发过程中&#xff0c;可以更高效的实现代码重用。 二. 函数的使用步骤 1. 定义函数 def 函数名(参数):代码1代码2...... 复制 …

usb_cam相机录制rosbag

文章目录运行环境&#xff1a;1.1 usb_cam连接&#xff1a;1.2 usb-cam启动1.2 查看相机话题名称2.1 rosbag录制2.2 播放rosbag运行环境&#xff1a; ubuntu20.04 noetic 杰瑞微通usb_cam&#xff08;分辨率640x480&#xff09; 宏基暗影骑士笔记本 1.1 usb_cam连接&#xff…

Golang每日一练(leetDay0030)

目录 88. 合并两个有序数组 Merge Sorted Array &#x1f31f; 89. 格雷编码 Gray Code &#x1f31f;&#x1f31f; 90. 子集 II Subsets II &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/…