嵌入式 uboot以及kernel添加看门狗临时记录(个人记录未整理乱)

本文记录了在U-Boot 2010.06版本中添加看门狗功能的过程,以及如何在Kernel中进行相应的配置,旨在为个人学习和理解嵌入式系统的看门狗机制提供参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Uboot_Kernerl_Add_Watch_Dog:


U-Boot 2010.06 (Nov 01 2013 - 15:28:44)

DRAM:  128 MiB
Check spi flash controller v350... Found
Spi(cs1) ID: 0xEF 0x40 0x18 0x00 0x00 0x00
Spi(cs1): Block:64KB Chip:16MB Name:"W25Q128B"
*** Warning - bad CRC, using default environment


In:    serial
Out:   serial
Err:   serial
Hit any key to stop autoboot:  0 
16384 KiB hi_sfc at 0:0 is now current device


## Booting kernel from Legacy Image at 82000000 ...
   Image Name:   Linux-3.0.8
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2735184 Bytes = 2.6 MiB
   Load Address: 80008000
   Entry Point:  80008000
   Loading Kernel Image ... OK
OK


Starting kernel ...


Uncompressing Linux... done, booting the kernel.
Linux version 3.0.8 (root@u12d32) (gcc version 4.4.1 (Hisilicon_v100(gcc4.4-290+uclibc_0.9.32.1+eabi+linuxpthread)) ) #17 Tue Mar 25 16:34:29 CST 2014
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
CPU: VIVT data cache, VIVT instruction cache
Machine: hi3518
Memory policy: ECC disabled, Data cache writeback
AXI bus clock 200000000.
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 16256
Kernel command line: mem=64M console=ttyAMA0,115200 root=/dev/mtdblock4 rootfstype=jffs2 mtdparts=hi_sfc:256k(boot)ro,128k(env),128k(config),3072k(kernel),11264k(rootfs)
PID hash table entries: 256 (order: -2, 1024 bytes)
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total
Memory: 59748k/59748k available, 5788k reserved, 0K highmem
Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
    DMA     : 0xffc00000 - 0xffe00000   (   2 MB)
    vmalloc : 0xc4800000 - 0xfe000000   ( 920 MB)
    lowmem  : 0xc0000000 - 0xc4000000   (  64 MB)
    modules : 0xbf000000 - 0xc0000000   (  16 MB)
      .init : 0xc0008000 - 0xc0029000   ( 132 kB)
      .text : 0xc0029000 - 0xc04cf000   (4760 kB)
      .data : 0xc04d0000 - 0xc04f35a0   ( 142 kB)
       .bss : 0xc04f35c4 - 0xc0510e78   ( 119 kB)
SLUB: Genslabs=13, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
NR_IRQS:32 nr_irqs:32 32
sched_clock: 32 bits at 100MHz, resolution 10ns, wraps every 42949ms
Console: colour dummy device 80x30
Calibrating delay loop... 218.72 BogoMIPS (lpj=1093632)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
devtmpfs: initialized
NET: Registered protocol family 16
Serial: AMBA PL011 UART driver
uart:0: ttyAMA0 at MMIO 0x20080000 (irq = 5) is a PL011 rev2
console [ttyAMA0] enabled
uart:1: ttyAMA1 at MMIO 0x20090000 (irq = 5) is a PL011 rev2
bio: create slab <bio-0> at 0
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
Switching to clocksource timer1
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 2048 (order: 2, 16384 bytes)
TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
TCP: Hash tables configured (established 2048 bind 2048)
TCP reno registered
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
NetWinder Floating Point Emulator V0.97 (double precision)
VFS: Disk quotas dquot_6.5.2
Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
JFFS2 version 2.2. (NAND) 漏 2001-2006 Red Hat, Inc.
fuse init (API version 7.16)
msgmni has been set to 116
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
io scheduler noop registered
io scheduler deadline registered (default)
io scheduler cfq registered
brd: module loaded
loop: module loaded
Spi id table Version 1.22
Spi(cs1) ID: 0xEF 0x40 0x18 0x00 0x00 0x00
SPI FLASH start_up_mode is 3 Bytes
Spi(cs1): 
Block:64KB 
Chip:16MB 
Name:"W25Q128B"
spi size: 0x16777216
chip num: 1
5 cmdlinepart partitions found on MTD device hi_sfc
Creating 5 MTD partitions on "hi_sfc":
0x000000000000-0x000000040000 : "boot"
0x000000040000-0x000000060000 : "env"
0x000000060000-0x000000080000 : "config"
0x000000080000-0x000000380000 : "kernel"
0x000000380000-0x000000e80000 : "rootfs"
Fixed MDIO Bus: probed
himii: probed
PPP generic driver version 2.4.2
PPP Deflate Compression module registered
PPP BSD Compression module registered
PPP MPPE Compression module registered
NET: Registered protocol family 24
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
hiusb-ehci hiusb-ehci.0: HIUSB EHCI
hiusb-ehci hiusb-ehci.0: new USB bus registered, assigned bus number 1
hiusb-ehci hiusb-ehci.0: irq 15, io mem 0x100b0000
hiusb-ehci hiusb-ehci.0: USB 0.0 started, EHCI 1.00
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
hiusb-ohci hiusb-ohci.0: HIUSB OHCI
hiusb-ohci hiusb-ohci.0: new USB bus registered, assigned bus number 2
hiusb-ohci hiusb-ohci.0: irq 16, io mem 0x100a0000
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 1 port detected
usbcore: registered new interface driver cdc_acm
cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
usbcore: registered new interface driver cdc_wdm
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
usbcore: registered new interface driver ums-alauda
usbcore: registered new interface driver ums-datafab
usbcore: registered new interface driver ums-freecom
usbcore: registered new interface driver ums-isd200
usbcore: registered new interface driver ums-jumpshot
usbcore: registered new interface driver ums-sddr09
usbcore: registered new interface driver ums-sddr55
usbcore: registered new interface driver mdc800
mdc800: v0.7.5 (30/10/2000):USB Driver for Mustek MDC800 Digital Camera
usbcore: registered new interface driver usbserial
usbserial: USB Serial Driver core
USB Serial support registered for GSM modem (1-port)
usbcore: registered new interface driver option
option: v0.7.2:USB Driver for GSM modems
mousedev: PS/2 mouse device common for all mice
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
TCP cubic registered
Initializing XFRM netlink socket
NET: Registered protocol family 10
NET: Registered protocol family 17
NET: Registered protocol family 15
lib80211: common routines for IEEE802.11 drivers
Registering the dns_resolver key type
registered taskstats version 1
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
鴘sb 1-1: new high speed USB device number 2 using hiusb-ehci
VFS: Mounted root (jffs2 filesystem) on device 31:4.
devtmpfs: mounted
Freeing init memory: 132K


            _ _ _ _ _ _ _ _ _ _ _ _
            \  _  _   _  _ _ ___
            / /__/ \ |_/
           / __   /  -  _ ___
          / /  / /  / /
  _ _ _ _/ /  /  \_/  \_ ______
___________\___\__________________


[RCS]: /etc/init.d/S00devs
mknod: /dev/console: File exists
mknod: /dev/ttyAMA0: File exists
mknod: /dev/ttyAMA1: File exists
mknod: /dev/null: File exists
[RCS]: /etc/init.d/S01udev
udevd (600): /proc/600/oom_adj is deprecated, please use /proc/600/oom_score_adj instead.
[RCS]: /etc/init.d/S80network
/
Auto login as root ...
/opt/joseph
Jan  1 08:00:03 login[606]: root login on 'ttyS000'
Welcome to HiLinux.
Congratulate joseph_power_init ok  !
Congratulate joseph_led_init ok  !
None of nfsroot found in cmdline.
[root@njqy]#


1、P447(硬件设计用户指南)

系统初始化配置
系统上电复位后WatchDog计数器处于停止计数状态,在系统初始化过程中需要将
WatchDog初始化并启动其运行。WatchDog的初始化过程如下:
1.  写寄存器WDG_LOAD,设定计数初值。
2.  写寄存器WDG_CONTROL,打开中断屏蔽并启动WatchDog计数。
3.  写寄存器WDG_LOCK,给WatchDog上锁,防止软件错误修改WatchDog的配置。
----结束
中断处理过程
收到WatchDog发出的中断后,应及时清除其中断状态,并使其载入计数初值重新开始
计数。WatchDog中断处理的过程如下所示:
1.  向WDG_LOCK写0x1ACC_E551,为WatchDog开锁。
2.  写寄存器WDG_INTCLR,清除WatchDog的中断状态,同时也使WatchDog自动载入
计数初值重新开始计数。
3.  向寄存器WDG_LOCK写入0x1ACC_E551以外的任何值,给WatchDog上锁。
----结束 
Hi3518 HD IP Camera SoC 
用户指南  3 系统
文档版本04 (2013-09-25) 
海思专有和保密信息
版权所有? 深圳市海思半导体有限公司
3-176
关闭WatchDog 
向寄存器WDG_CONTROL[inten]控制位写入0或1控制WatchDog的状态:
z  0:关闭WatchDog;
z  1:打开WatchDog。

表3-33 WatchDog寄存器概览(基址是0x2004_0000)
偏移地址  名称  描述  页码
0x0000 WDG_LOAD  计数初值寄存器  3-174
0x0004 WDG_VALUE  计数器当前值寄存器  3-175
0x0008 WDG_CONTROL  控制寄存器  3-175
0x000C WDG_INTCLR  中断清除寄存器  3-176
0x0010 WDG_RIS  原始中断寄存器  3-176
0x0014 WDG_MIS  屏蔽后中断寄存器  3-176
0x0018~
0x0BFC 
RESERVED  保留  - 
0x0C00 WDG_LOCK  LOCK寄存器  3-177

Examples:

1、
uboot中默认看门狗策略由两个宏CONFIG_HW_WATCHDOG和CONFIG_WATCHDOG来使能。


此策略是在代码执行中的不同阶段,添加喂狗代码。

这种喂狗方法会使代码很乱,uboot中到处都充斥的喂狗代码。另外这种方法对代码执行时间是敏感的,如果有段代码执行时间很长(如搬运code),则需要添加喂狗代码,很繁。

uboot的默认策略比较适合外部看门狗。

我们现在用的是CPU内部看门狗,直接无视上述两宏。我们要在watchdog interrupt中喂狗,即只在watchdog interrupt handler中喂狗,比较简便
2、
在include/watchdog.h文件中有宏定义 
#ifdef CONFIG_HW_WATCHDOG 
    #if defined(__ASSEMBLY__) 
        #define WATCHDOG_RESET bl hw_watchdog_reset 
    #else 
        extern void hw_watchdog_reset(void); 
        #define WATCHDOG_RESET hw_watchdog_reset 
    #endif 
所以,需要打开CONFIG_HW_WATCHDOG开关以及实现hw_watchdog_reset喂狗函数。
3、


Hi3518C_Current_Uboot_Env :




joseph # printenv
bootargs=mem=64M console=ttyAMA0,115200 root=/dev/mtdblock4 rootfstype=jffs2 mtdparts=hi_sfc:256k(boot)ro,128k(env),128k(config),3072k(kernel),11264k(rootfs)
bootcmd=sf probe 0;sf read 0x82000000 0x80000 0x300000;bootm 0x82000000
bootdelay=1
baudrate=115200
ethaddr=00:00:23:34:45:66
ipaddr=192.168.1.10
serverip=192.168.1.2
netmask=255.255.255.0
bootfile="uImage"
stdin=serial
stdout=serial
stderr=serial
verify=n
ver=U-Boot 2010.06 (Nov 01 2013 - 15:28:44)

Environment size: 459/262140 bytes


















#define GPIO_LIGHT_DAT (IO_ADDRESS(0x201A0000 + 0x03FC))
#define GPIO_LIGHT_DIR (IO_ADDRESS(0x201A0000 + 0x0400))
#define GPIO_LIGHT_MUX (IO_ADDRESS(0x200F0000 + 0x009C))




#define GPIO_1_1_DAT (IO_ADDRESS(0x201503FC))//red
#define GPIO_1_1_DIR (IO_ADDRESS(0x20150400))
#define GPIO_1_1_MUX (IO_ADDRESS(0x200F0004))


#define GPIO_6_0_DAT (IO_ADDRESS(0x201A03FC))//blue
#define GPIO_6_0_DIR   (IO_ADDRESS(0x201A0400))
#define GPIO_6_0_MUX   (IO_ADDRESS(0x200F0080))










/*alter by kj*/
/*
Author : kj
Time : 2014-04-19
Function : 
control gpio led
Instruction :
1 - red on
2 - red off
3 - blue on
4 - blue off
5 - light on
6 - light off


writel(0x2, REG_BASE_SCTL+REG_SC_SYSRES);
 */
static void joseph_set_gpio_hi3518c(int led_status)
{
switch(led_status)
{
case 1:
{
printk("\nThe uboot set red led on and blue led off begin alter by kj !!!\n");
writel(0x00000002,GPIO_1_1_DIR);
writel(0x00000000,GPIO_1_1_MUX);
writel(0x00000002,GPIO_1_1_DAT);// 1 - on ;0 - off


writel(0x00000001,GPIO_6_0_DIR);
writel(0x00000000,GPIO_6_0_MUX);
writel(0x00000000,GPIO_6_0_DAT);// blue off


break;
}
case 2:
{
printk("\nThe uboot  red off light begin alter by kj !!!\n");
writel(0x00000002,GPIO_1_1_DIR);
writel(0x00000000,GPIO_1_1_MUX);
writel(0x00000000,GPIO_1_1_DAT);// red off


break;
}
case 3:
{


printk("\nThe uboot set bule on begin alter by kj !!!\n");
writel(0x00000001,GPIO_6_0_DIR);
writel(0x00000000,GPIO_6_0_MUX);
writel(0x00000001,GPIO_6_0_DAT);//bule on
break;
}
case 4:
{


printk("\nThe uboot set blue off begin alter by kj !!!\n");
writel(0x00000001,GPIO_6_0_DIR);
writel(0x00000000,GPIO_6_0_MUX);
writel(0x00000000,GPIO_6_0_DAT);//blue off
break;
}
case 5:
{
printk("\nThe uboot set light on begin alter by kj !!!\n");
writel(0x00000080,GPIO_LIGHT_DIR);
writel(0x00000000,GPIO_LIGHT_MUX);
writel(0x00000000,GPIO_LIGHT_DAT);//light on

break;
}
case 6:
{


printk("\nThe uboot set light off begin alter by kj !!!\n");
writel(0x00000080,GPIO_LIGHT_DIR);
writel(0x00000001,GPIO_LIGHT_MUX);
writel(0x00000000,GPIO_LIGHT_DAT);//light off


break;
}
default:
break;
}






}








/*====================================Hi3518c start.S Begin 2014-04-20=============================================*/
/*
 *  armboot - Startup Code for ARM926EJS CPU-core
 *
 *  Copyright (c) 2003  Texas Instruments
 *
 *  ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------
 *
 *  Copyright (c) 2001 Marius Gr?ger <mag@sysgo.de>
 *  Copyright (c) 2002 Alex Z?pke <azu@sysgo.de>
 *  Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
 *  Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
 *  Copyright (c) 2003 Kshitij <kshitij@ti.com>
 *
 * 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
 */




#include <config.h>
#include <version.h>


/*
 *************************************************************************
 *
 * Jump vector table as in table 3.1 in [1]
 *
 *************************************************************************
 */




.globl _start //汇编程序都要提供一个_start符号并且用.globl声明
_start: b reset //B或BL指令引起处理器转移到“子程序名”处开始执行 复位
ldr     pc, _undefined_instruction 
ldr     pc, _software_interrupt
ldr     pc, _prefetch_abort
ldr     pc, _data_abort
ldr     pc, _not_used
ldr     pc, _irq
ldr     pc, _fiq


_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
_pad: .word 0x12345678 /* now 16*4=64 */


/*.fill 
     语法:.fill repeat, size, value
     含义是反复拷贝 size个字节,重复 repeat 次,
         其中 size 和 value 是可选的,默认值分别为 1 和 0.
*/
__blank_zone_start:
.fill 1024*4,1,0 //给某个具体的寄存器里填数
__blank_zone_end:


.globl _blank_zone_start
_blank_zone_start:
.word __blank_zone_start




.globl _blank_zone_end
_blank_zone_end:
.word __blank_zone_end


.balignl 16,0xdeadbeef
/*
 *************************************************************************
 *
 * Startup Code (reset vector)
 *
 * do important init only if we don't start from memory!
 * setup Memory and board specific bits prior to relocation.
 * relocate armboot to ram
 * setup stack
 *
 *************************************************************************
 */


_TEXT_BASE:
.word TEXT_BASE


.globl _armboot_start
_armboot_start:
.word _start


/*
 * These are defined in the board-specific linker script.
 */
.globl _bss_start
_bss_start:
.word __bss_start


.globl _bss_end
_bss_end:
.word _end


#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de


/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif




_clr_remap_spi_entry:
    .word   SF_TEXT_ADRS + do_clr_remap - TEXT_BASE
_clr_remap_nand_entry:
    .word   NAND_TEXT_ADRS + do_clr_remap - TEXT_BASE


/*
 * the actual reset code
 */


reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr //将状态寄存器的内容传送至通用寄存器,将CPSR中的内容传送至R0
bic r0,r0,#0x1f //位清除指令 将R0最低5位清零,其余位不变 工作模式位清零
orr r0,r0,#0xd3 //工作模式位设置为“10011”(管理模式),并将中断禁止位和快中断禁止位置1 "1101 0011" 指令用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中
msr cpsr,r0 //将通用寄存器的内容传送至状态寄存器,将中的内容R0传送至CPSR


/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/


/*
* flush v4 I/D caches
*/
mov r0, #0 //置零ro通用寄存器
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ //向c7写入0将使ICache与DCache无效 "0"表示省略opcode_2 MCR{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>}
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ //MCR{条件} 协处理器编码,协处理器操作码1,源寄存器,目的寄存器1,目的寄存器2,协处理器操作码2


/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */
bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
mcr p15, 0, r0, c1, c0, 0 //保存r0到控制寄存器


mov r0, pc, lsr#24 //LSL、LSR、ASR、ROR 寄存器移位
cmp r0, #0x0
bne do_clr_remap //检测是否需要跳转,PC的高八位如果不为0(已经在ram中运行了)则跳转 不等于则调转


check_start_mode:
ldr r0, =REG_BASE_SCTL
ldr r0, [r0, #REG_SYSSTAT]
mov r6, r0, lsr#5
and r6, #0x1


/* reg[0x2005008c:5]:
* 0: start from spi
* 1: start from nand
*/


cmp r6, #BOOT_FROM_SPI
ldreq   pc, _clr_remap_spi_entry


ldr pc, _clr_remap_nand_entry
@b . /* bug here */


/*
LDR和STR用来存取内存,关于"索引偏移",你是不是指pre-indexed addressing和post-indexed addressingpre-indexed addressing是指地址经过运算不写回基址寄存器post-indexed addressing则回写到基址寄存器比如pre-indexed addressing:mov r1,#0STR r0, [r1, #0x10]       ;r1+0x10这个是所用的实际地址值,但是不回写入r1,在此句之后,r1=0post-indexed addressing:STR r0, [r1], #0x10       ;r1+0x10这个是所用的实际地址值,这个值回写入r1,此句之后,r1=0x10
*/
do_clr_remap:
ldr     r4, =REG_BASE_SCTL //用来从存储器(确切地说是地址空间)中装载数据到通用寄存器 系统控制器寄存器 0x20050000 写地址
ldr r0, [r4, #REG_SC_CTRL] //加载32位的立即数或一个地址值到指定寄存器 不回写 其实是r4+#0x0是实际地址值


/* reg[0x20050000:8]:
* 0: keep remap
* 1: clear remap 重映射
*/
@Set clear remap bit.
orr r0, #(1<<8) //第八位置1
str r0, [r4, #REG_SC_CTRL] //不回写 @表示注释


@Setup TCM (ENABLED, 2KB) // TCM时钟门控使能
ldr     r0, =( 1 | (MEM_CONF_ITCM_SIZE<<2) | MEM_BASE_ITCM)
mcr     p15, 0, r0, c9, c1, 1


@enable I-Cache now
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
mcr p15, 0, r0, c1, c0, 0


@Check if I'm running in ddr //代码内存运行测试
mov r0, pc, lsr#28
cmp r0, #8
bleq    relocate //小于等于跳转


ldr     r0, _blank_zone_start
ldr     r1, _TEXT_BASE //代码段
sub     r0, r0, r1 //减法 sub a,b (a-b)
adrl    r1, _start //将相对于程序或相对于寄存器的地址载入寄存器中 adrl宽
add     r0, r0, r1 //加法
mov     r1, #0          /* flags: 0->normal 1->pm */
bl      init_registers //初始化寄存器


#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate:
@copy arm exception table in 0 address
adrl r0, _start
mov r1, #0
mov r2, #0x100 /* copy arm Exception table to 0 addr */
add     r2, r0, r2
copy_exception_table:
ldmia   r0!, {r3 - r10}
stmia   r1!, {r3 - r10}
cmp     r0, r2
ble     copy_exception_table


@relocate U-Boot to RAM
adrl 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
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 */


/* 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    */
bic sp, sp, #7 /*8-byte alignment for ABI compliance*/


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




/*
 *************************************************************************
 *
 * CPU_init_critical registers
 *
 * setup important registers
 * setup memory timing
 *
 *************************************************************************
 */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
cpu_init_crit:
/*
* flush v4 I/D caches
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */


/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */
bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
mcr p15, 0, r0, c1, c0, 0


/*
* Go setup Memory and board specific bits prior to relocation.
*/
mov ip, lr /* perserve link reg across call */
@bl lowlevel_init /* go setup pll,mux,memory */
mov lr, ip /* restore link */
mov pc, lr /* back to my caller */
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */


#ifndef CONFIG_PRELOADER
/*
 *************************************************************************
 *
 * Interrupt handling
 *
 *************************************************************************
 */


@
@ IRQ stack frame.
@
#define S_FRAME_SIZE 72


#define S_OLD_R0 68
#define S_PSR 64
#define S_PC 60
#define S_LR 56
#define S_SP 52


#define S_IP 48
#define S_FP 44
#define S_R10 40
#define S_R9 36
#define S_R8 32
#define S_R7 28
#define S_R6 24
#define S_R5 20
#define S_R4 16
#define S_R3 12
#define S_R2 8
#define S_R1 4
#define S_R0 0


#define MODE_SVC 0x13
#define I_BIT 0x80


/*
 * use bad_save_user_regs for abort/prefetch/undef/swi ...
 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
 */


.macro bad_save_user_regs
@ carve out a frame on current user stack
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12


ldr r2, _armboot_start
sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
@ set base 2 words into abort stack
sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)
@ get values for "aborted" pc and cpsr (into parm regs)
ldmia r2, {r2 - r3}
add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
add r5, sp, #S_SP
mov r1, lr
stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
mov r0, sp @ save current stack into r0 (param register)
.endm


.macro irq_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
@ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
add r8, sp, #S_PC
stmdb r8, {sp, lr}^ @ Calling SP, LR
str lr, [r8, #0] @ Save calling PC
mrs r6, spsr
str r6, [r8, #4] @ Save CPSR
str r0, [r8, #8] @ Save OLD_R0
mov r0, sp
.endm


.macro irq_restore_user_regs
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
mov r0, r0
ldr lr, [sp, #S_PC] @ Get PC
add sp, sp, #S_FRAME_SIZE
subs pc, lr, #4 @ return & move spsr_svc into cpsr
.endm


.macro get_bad_stack
ldr r13, _armboot_start @ setup our mode stack
sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
@ reserved a couple spots in abort stack
sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8)


str lr, [r13] @ save caller lr in position 0 of saved stack
mrs lr, spsr @ get the spsr
str lr, [r13, #4] @ save spsr in position 1 of saved stack
mov r13, #MODE_SVC @ prepare SVC-Mode
@ msr spsr_c, r13
msr spsr, r13 @ switch modes, make sure moves will execute
mov lr, pc @ capture return pc
movs pc, lr @ jump to next instruction & switch modes.
.endm


.macro get_irq_stack @ setup IRQ stack
ldr sp, IRQ_STACK_START
.endm


.macro get_fiq_stack @ setup FIQ stack
ldr sp, FIQ_STACK_START
.endm
#endif /* CONFIG_PRELOADER */


/*
 * exception handlers
 */
#ifdef CONFIG_PRELOADER
.align 5 //加上.align汇编语句后,指令就对齐
do_hang:
ldr sp, _TEXT_BASE /* switch to abort stack */
1:
bl 1b /* hang and never return */
#else /* !CONFIG_PRELOADER */
.align  5
undefined_instruction:
get_bad_stack
bad_save_user_regs
bl do_undefined_instruction


.align 5
software_interrupt:
get_bad_stack
bad_save_user_regs
bl do_software_interrupt


.align 5
prefetch_abort:
get_bad_stack
bad_save_user_regs
bl do_prefetch_abort


.align 5
data_abort:
get_bad_stack
bad_save_user_regs
bl do_data_abort


.align 5
not_used:
get_bad_stack
bad_save_user_regs
bl do_not_used


#ifdef CONFIG_USE_IRQ


.align 5
irq:
get_irq_stack
irq_save_user_regs
bl do_irq
irq_restore_user_regs


.align 5
fiq:
get_fiq_stack
/* someone ought to write a more effiction fiq_save_user_regs */
irq_save_user_regs
bl do_fiq
irq_restore_user_regs


#else


.align 5
irq:
get_bad_stack
bad_save_user_regs
bl do_irq


.align 5
fiq:
get_bad_stack
bad_save_user_regs
bl do_fiq


#endif
#endif /* CONFIG_PRELOADER */
#include "lowlevel_init.S"
/*====================================Hi3518c start.S End=============================================*/






/*====================================Hi3518c lowlevelinit.s Begin=====================================*/
.text
.align 2
.global init_registers
.type init_registers, %function
init_registers:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
ldr r2, [r0, #0]
cmp r2, #0
mov r6, #1
bne
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值