嵌入式 uboot以及kernel添加看門狗臨時記錄(個人記錄未整理亂)


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 .L43
.L2:
ldr r3, [r0, #4]
cmp r3, #0
bne .L43
ldr r3, [r0, #8]
cmp r3, #0
ldrne ip, [r0, #12]
bne .L3
ldr ip, [r0, #12]
cmp ip, #0
beq .L6
.L3:
cmp r1, #0
beq .L7
.L45:
tst ip, #2
beq .L8
and r4, ip, #248
mov r4, r4, lsr #3
add r4, r4, #1
cmp r4, #32
movne r4, r6, asl r4
andne ip, ip, #63488
ldr r5, [r2, #0]
movne ip, ip, lsr #11
subne r4, r4, #1
bicne r5, r5, r4, asl ip
ldrne r4, [r0, #4]
ldreq ip, [r0, #4]
orrne ip, r5, r4, asl ip
cmp r3, #0
str ip, [r2, #0]
beq .L11
.L29:
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
subs r3, r3, #1
bne .L29
.L11:
add r0, r0, #16
.L46:
ldr r2, [r0, #0]
cmp r2, #0
beq .L2
.L43:
cmp r1, #0
ldr r3, [r0, #8]
ldr ip, [r0, #12]
bne .L45
.L7:
tst ip, #4
beq .L18
and r4, ip, #248
mov r4, r4, lsr #3
add r4, r4, #1
cmp r4, #32
movne r4, r6, asl r4
andne ip, ip, #63488
ldr r5, [r2, #0]
movne ip, ip, lsr #11
subne r4, r4, #1
bicne r5, r5, r4, asl ip
ldrne r4, [r0, #4]
ldreq ip, [r0, #4]
orrne ip, r5, r4, asl ip
cmp r3, #0
str ip, [r2, #0]
beq .L11
.L32:
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
subs r3, r3, #1
bne .L32
add r0, r0, #16
b .L46
.L8:
tst ip, #131072
bne .L13
cmp r3, #0
beq .L11
.L31:
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
subs r3, r3, #1
bne .L31
add r0, r0, #16
b .L46
.L18:
tst ip, #262144
bne .L22
cmp r3, #0
beq .L11
.L34:
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
subs r3, r3, #1
bne .L34
add r0, r0, #16
b .L46
.L13:
and r4, ip, #16252928
mov r4, r4, lsr #19
add r4, r4, #1
mov r7, r6, asl r4
ldr r5, [r0, #4]
mov r8, ip, lsr #27
sub r7, r7, #1
.L16:
ldr ip, [r2, #0]
cmp r4, #32
andne ip, r7, ip, lsr r8
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
cmp r5, ip
bne .L16
cmp r3, #0
beq .L11
.L30:
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
subs r3, r3, #1
bne .L30
add r0, r0, #16
b .L46
.L22:
and r4, ip, #16252928
mov r4, r4, lsr #19
add r4, r4, #1
mov r8, r6, asl r4
ldr r5, [r0, #4]
sub r8, r8, #1
mov r7, ip, lsr #27
.L25:
ldr ip, [r2, #0]
cmp r4, #32
andne ip, r8, ip, lsr r7
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
cmp r5, ip
bne .L25
cmp r3, #0
beq .L11
.L33:
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
subs r3, r3, #1
bne .L33
add r0, r0, #16
b .L46
.L6:
@ 38 "lowlevel_init.c" 1
nop
@ 0 "" 2
bx lr
/*====================================Hi3518c lowlevelinit.s End=====================================*/


1.U-boot啟動過程:
 
1)/uboot/cpu/arm926ejs/start.S文件是Uboot的入口程序。 
2)/uboot/lib_arm/board.c Uboot執行的第一個C函數,完成系統的初始化。
 
3)init_sequence[] 是基本的初始化函數指針。 
4)void start_armboot(void) 數序執行init_sequence[]數組中的初始化函數。
 
我把U-boot的運行過程簡化描述如下: 
check board->dram_init->flash init->nand init->env relocate->ip,mac獲取->device init->網卡初始化->進入main_loop函數,等待串口輸入(無輸入則執行bootcmd命令)。
 
2.U-boot和內核的主要關系式內核啟動過程中參數的傳遞。
 
U-boot會給Linux Kernel傳遞很多參數,如:串口,RAM,videofb等。而內核也會讀取和處理這些參數。兩者之間通過struct tag來傳遞參數。U-boot把要傳遞給kernel的東西保存在struct tag數據結構中,啟動kernel時,把這個結構體的物理地址傳給kernel;Linux kernel通過這個地址,用parse_tags分析出傳遞過來的參數。 
1、u-boot給kernel傳參數: 
在uboot/common/cmd_bootm.c文件中,bootm命令對應的do_bootm函數,當分析uImage中信息發現OS是Linux時,調用. /lib_arm/bootm.c文件中的do_bootm_linux函數來啟動Linux kernel。 
2、內核讀取U-boot傳遞的相關參數: 
對於Linux Kernel配合ARM平台啟動時,先執行arch/arm/kernel/head.S,這個文件會調用arch/arm/kernel/head-common.S中的函數,在最后調用start_kernel。


start.s-----start_armboot()------main_loop()--------do_bootm()------do_bootm_linux()
1,start.s主要完成的是CPU的基本設置,比如設置位SVC模式,關閉watchog,關閉中斷,關閉MMU(哥當時就笑了, 
      當然,這也提醒和我一樣廣大的同學們要在學習中注重基礎,為什么要關MMu? 因為uboot中所有對地址的操是使用物理地址,在的實地址,不存在虛擬地址,因此MMU必須關閉。曉得了不),還有設置堆棧,最后將剩下的uboot  搬到SDRAM(有人說是將全部的uboot代碼搬過去,有 的又說是只講  stage2的代碼搬過去,到底是哪個不清楚,不過這個問題沒必要糾結,沒什么影響)。
2,start_armboot()主要完成的是對板子的外設的初始化,串口啊,LCD啊,NAND啊,設置一下環境變量啊,這個函數中重點有3個結構體,gd,bd,sequence,搞清楚就ok了
3,mainloop簡單的說就是在板子上電延時的那會,如果有按鍵按下,則進入交互模式,就是一直解析你輸入的命令,如果沒有按下,則繼續往下走,啟動kernel去
4,dobootm主要是解析kernel的頭,制作uboot可以啟動的kernel時,需要在前面加頭,頭的內容包括有什么類型的映像,什么類型的操作系統,還有怎么壓縮的等,最后還完成一個重要的工作就是將kernel搬到SDRAM中,接着調用do_bootm_linux()
5,do_bootm_linux()做的就比較簡單了,設置一下啟動參數,然后直接啟動內核,over






Hi3518c:
Uboot:
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
start.s
1、./include/configs/hi3518c.h:86:#define SF_TEXT_ADRS (SFC_MEM_BASE)
2、指針寄存器包括堆棧寄存器SP(stack pointer)和基數指針寄存器BP(base pointer)
3、跳轉到第二階段代碼入口
    ldr  pc, _start_armboot
_start_armboot:  .word start_armboot
4、./arch/arm/lib/board.c:383:void start_armboot (void)
{
U-Boot使用了一個結構體gd_t來存儲全局數據區的數據
結構體bd_t在include/asm-arm.u/u-boot.h中定義
U-Boot使用一個數組init_sequence來存儲對於大多數開發板都要執行的初始化函數的函數指針

 init_fnc_t *init_sequence[] = {
#if defined(CONFIG_ARCH_CPU_INIT)
arch_cpu_init, /* basic arch cpu dependent setup */
#endif
timer_init,  /* initialize timer before usb init */
board_init,  /* basic board dependent setup */
#if defined(CONFIG_USE_IRQ)
interrupt_init, /* set up exceptions */
#endif
// timer_init, /* initialize timer */
#ifdef CONFIG_FSL_ESDHC
get_clocks,
#endif
env_init,  /* initialize environment */
init_baudrate, /* initialze baudrate settings */
serial_init,  /* serial communications setup */
console_init_f, /* stage 1 init of console */
display_banner, /* say that we are here */
#if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo, /* display cpu info (and speed) */
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
checkboard,  /* display board info */
#endif
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
init_func_i2c,
#endif
dram_init,  /* configure available RAM banks */
#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)
arm_pci_init,
#endif
display_dram_config,
NULL,
};
  }
5、 display_flash_config (flash_init ());調用spiflash驅動進行flash ID 以及type初始化以及識別
6、進入倒計時等候用戶終止uboot進入命令行:
{
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
s = getenv ("bootdelay");
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;

debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);

# ifdef CONFIG_BOOT_RETRY_TIME
init_cmd_timeout ();
# endif  /* CONFIG_BOOT_RETRY_TIME */

#ifdef CONFIG_POST
if (gd->flags & GD_FLG_POSTFAIL) {
s = getenv("failbootcmd");
}
else
#endif /* CONFIG_POST */
#ifdef CONFIG_BOOTCOUNT_LIMIT
if (bootlimit && (bootcount > bootlimit)) {
printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n",
       (unsigned)bootlimit);
s = getenv ("altbootcmd");
}
else
#endif /* CONFIG_BOOTCOUNT_LIMIT */
s = getenv ("bootcmd");

debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");

if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
# ifdef CONFIG_AUTOBOOT_KEYED
int prev = disable_ctrlc(1); /* disable Control C checking */
# endif

# ifndef CONFIG_SYS_HUSH_PARSER
run_command (s, 0);
# else
parse_string_outer(s, FLAG_PARSE_SEMICOLON |
   FLAG_EXIT_FROM_LOOP);
# endif

# ifdef CONFIG_AUTOBOOT_KEYED
disable_ctrlc(prev); /* restore Control C checking */
# endif
}


}


7、Uboot被abort的時候需要在uboot等待用戶命令的時候喂狗:
{
location:/common/console.c
int fgetc(int file)
{
if (file < MAX_FILES) {
#if defined(CONFIG_CONSOLE_MUX)
/*
* Effectively poll for input wherever it may be available.
*/
for (;;) {
/*
* Upper layer may have already called tstc() so
* check for that first.
*/
if (tstcdev != NULL)
return console_getc(file);
console_tstc(file);
#ifdef CONFIG_WATCHDOG
/*
* If the watchdog must be rate-limited then it should
* already be handled in board-specific code.
*/
udelay(1);
#endif
}
#else
return console_getc(file);
#endif
}

return -1;
}
}


注意:在燒寫文件系統或者內核的時候以及keimit的時候進行喂狗


## 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
8、uboot沒有被abort的時候進入bootm命令
{
1、uboot首先把內核鏡像拷貝到內存地址為0x80000000的地方,然后執行bootm 0x80000000命令
 
bootm命令來自 common/cmd_bootm.c文件,完成的功能有
 
》CRC校驗image head struct的64個字節的正確性
 
》根據鏡像頭中指定的壓縮類型(比如gzip),把kernel解壓到指定的位置hdr->ih_load(0x80800000)
 
》調用來自lib_sh/sh_linux.c中的函數do_bootm_linux( . . . ),啟動內核
 
 
 
2、接下來,分析do_bootm_linux函數的執行流程
 
傳給kernel的命令行參數地址是宏定義 #define COMMAND_LINE ((char *)(param+0x100))
 
do_bootm_linux
 
{
 
》從參數去中獲取環境變量bootargs的值
 
char *commandline = getenv("bootargs");
 
》從image head struct中獲取kernel的入口地址
 
void (*theKernel)(void); // 函數指針
 
theKernel = (void (*) (void)) ntohl (hdr->ih_ep);
 
》從image head struct中獲取kernel的指定存儲參數的地址
 
ulong param;
 
param = ntohl (hdr->ih_load);
 
》把commandline拷貝到約定好的COMMAND_LINE地址
 
strcpy (COMMAND_LINE, commandline);
 
 
 
》最后,執行kernel的入口函數,把控制權交給kernel
 
/* now, finally, we pass control to the kernel  itself ... */
 
theKernel();
 
}
load內核然后解壓:
ret = bootm_load_os(images.os, &load_end, 1);
{
/*
* Compression Types
*/
#define IH_COMP_NONE 0 /*  No Compression Used */
#define IH_COMP_GZIP 1 /* gzip Compression Used */
#define IH_COMP_BZIP2 2 /* bzip2 Compression Used */
#define IH_COMP_LZMA 3 /* lzma  Compression Used */
#define IH_COMP_LZO 4 /* lzo   Compression Used */

#define IH_MAGIC 0x27051956 /* Image Magic Number */
#define IH_NMLEN 32 /* Image Name Length */

static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
{
uint8_t comp = os.comp;
ulong load = os.load;
ulong blob_start = os.start;
ulong blob_end = os.end;
ulong image_start = os.image_start;
ulong image_len = os.image_len;
uint unc_len = CONFIG_SYS_BOOTM_LEN;
ulong image_end;

const char *type_name = genimg_get_type_name (os.type);
int boot_sp;

__asm__ __volatile__(
"mov    %0, sp\n"
:"=r"(boot_sp)
:
:"cc"
);

/* Check whether kernel zImage overwrite uboot,
* which will lead to kernel boot fail. */
image_end = load + image_len;
/* leave at most 32KByte for move image stack */
boot_sp -= BOOTM_STACK_GUARD;
if( !((load > _bss_end) || (image_end < boot_sp)) ) {
printf("\nkernel image will overwrite uboot! kernel boot fail!\n");
return BOOTM_ERR_RESET;
}

switch (comp) {
case IH_COMP_NONE:
if (load == blob_start || load == image_start) {
printf ("   XIP %s ... ", type_name);
} else {
printf ("   Loading %s ... ", type_name);
memmove_wd ((void *)load, (void *)image_start,
image_len, CHUNKSZ);
}
*load_end = load + image_len;
puts("OK\n");
break;
#ifdef CONFIG_GZIP
case IH_COMP_GZIP:
printf ("   Uncompressing %s ... ", type_name);
if (gunzip ((void *)load, unc_len,
(uchar *)image_start, &image_len) != 0) {
puts ("GUNZIP: uncompress, out-of-mem or overwrite error "
"- must RESET board to recover\n");
if (boot_progress)
show_boot_progress (-6);
return BOOTM_ERR_RESET;
}

*load_end = load + image_len;
break;
#endif /* CONFIG_GZIP */
#ifdef CONFIG_BZIP2
case IH_COMP_BZIP2:
printf ("   Uncompressing %s ... ", type_name);
/*
* If we've got less than 4 MB of malloc() space,
* use slower decompression algorithm which requires
* at most 2300 KB of memory.
*/
int i = BZ2_bzBuffToBuffDecompress ((char*)load,
&unc_len, (char *)image_start, image_len,
CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
if (i != BZ_OK) {
printf ("BUNZIP2: uncompress or overwrite error %d "
"- must RESET board to recover\n", i);
if (boot_progress)
show_boot_progress (-6);
return BOOTM_ERR_RESET;
}

*load_end = load + unc_len;
break;
#endif /* CONFIG_BZIP2 */
#ifdef CONFIG_LZMA
case IH_COMP_LZMA:
printf ("   Uncompressing %s ... ", type_name);

int ret = lzmaBuffToBuffDecompress(
(unsigned char *)load, &unc_len,
(unsigned char *)image_start, image_len);
if (ret != SZ_OK) {
printf ("LZMA: uncompress or overwrite error %d "
"- must RESET board to recover\n", ret);
show_boot_progress (-6);
return BOOTM_ERR_RESET;
}
*load_end = load + unc_len;
break;
#endif /* CONFIG_LZMA */
#ifdef CONFIG_LZO
case IH_COMP_LZO:
printf ("   Uncompressing %s ... ", type_name);

int ret = lzop_decompress((const unsigned char *)image_start,
 image_len, (unsigned char *)load,
 &unc_len);
if (ret != LZO_E_OK) {
printf ("LZO: uncompress or overwrite error %d "
     "- must RESET board to recover\n", ret);
if (boot_progress)
show_boot_progress (-6);
return BOOTM_ERR_RESET;
}

*load_end = load + unc_len;
break;
#endif /* CONFIG_LZO */
default:
printf ("Unimplemented compression type %d\n", comp);
return BOOTM_ERR_UNIMPLEMENTED;
}
puts ("OK\n");
debug ("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
if (boot_progress)
show_boot_progress (7);

if ((load < blob_end) && (*load_end > blob_start)) {
debug ("images.os.start = 0x%lX, images.os.end = 0x%lx\n", blob_start, blob_end);
debug ("images.os.load = 0x%lx, load_end = 0x%lx\n", load, *load_end);

return BOOTM_ERR_OVERLAP;
}

return 0;
}


}
}
9、uboot調用do_bootm_linux引導內核啟動:
{


int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
{
bd_t *bd = gd->bd;
char *s;
int machid = bd->bi_arch_number;
void (*theKernel)(int zero, int arch, uint params);

#ifdef CONFIG_CMDLINE_TAG
char *commandline = getenv ("bootargs");
#endif

if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
return 1;

theKernel = (void (*)(int, int, uint))images->ep;

s = getenv ("machid");
if (s) {
machid = simple_strtoul (s, NULL, 16);
printf ("Using machid 0x%x from environment\n", machid);
}

show_boot_progress (15);

debug ("## Transferring control to Linux (at address %08lx) ...\n",
      (ulong) theKernel);

#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
   defined (CONFIG_CMDLINE_TAG) || \
   defined (CONFIG_INITRD_TAG) || \
   defined (CONFIG_SERIAL_TAG) || \
   defined (CONFIG_REVISION_TAG)
setup_start_tag (bd);
#ifdef CONFIG_SERIAL_TAG
setup_serial_tag (&params);
#endif
#ifdef CONFIG_REVISION_TAG
setup_revision_tag (&params);
#endif
#ifdef CONFIG_SETUP_MEMORY_TAGS
setup_memory_tags (bd);
#endif
#ifdef CONFIG_CMDLINE_TAG
setup_commandline_tag (bd, commandline);
#endif
#ifdef CONFIG_INITRD_TAG
if (images->rd_start && images->rd_end)
setup_initrd_tag (bd, images->rd_start, images->rd_end);
#endif
#if defined(CONFIG_ETHMDIO_INF)
setup_eth_mdiointf_tag(bd, getenv("mdio_intf"));
#endif
#if defined(CONFIG_ETHADDR_TAG)
setup_ethaddr_tag(bd, getenv("ethaddr"));
#endif
#if defined(CONFIG_NANDID_TAG)
setup_nandid_tag(bd);
#endif
#if defined(CONFIG_SPIID_TAG)
setup_spiid_tag(bd);
#endif
setup_end_tag (bd);
#endif

/* we assume that the kernel is in place */
printf ("\nStarting kernel ...\n\n");

#ifdef CONFIG_USB_DEVICE
{
extern void udc_disconnect (void);
udc_disconnect ();
}
#endif

cleanup_before_linux ();


printf ("\n Init cpu done ................... alter by kj !!!\n\n");

theKernel (0, machid, bd->bi_boot_params);
/* does not return */

return 1;
}


}




/*===========================================hi3518c start kernel begin =============================================*/
進入內核:


一、創建si工程,按前面講的
 二、內核:
  A、處理u-boot傳入的參數,從arch/arm/kernel/head.s開始跟蹤進來
   0、判斷是否支持這個cpu
   1、判斷是否支持這個單板,uboot啟動內核時傳人的機器ID(theKernel (0, bd->bi_arch_number, bd->bi_boot_params);)
     在arch/arm/kernel/head.s下: 
     bl __lookup_machine_type  @ r5=machinfo
     進入__lookup_machine_type由此引出了 
     在arch/arm/kernel/vmlinux.lds    //鏈接腳本
       __arch_info_begin = .;
        *(.arch.info.init)
       __arch_info_end = .;
     在內核里面搜索:
     book@book-desktop:/work/system/linux-2.6.22.6$ grep ".arch.info.init" * -nR
     
     在arch.h里面有:
     #define MACHINE_START(_type,_name)   \
     static const struct machine_desc __mach_desc_##_type \
      __used       \
      __attribute__((__section__(".arch.info.init"))) = { \
      .nr  = MACH_TYPE_##_type,  \
      .name  = _name,
     
     #define MACHINE_END    \
     };
     
     MACHINE_START(S3C2440, "SMDK2440")
      /* Maintainer: Ben Dooks <ben@fluff.org> */
      .phys_io = S3C2410_PA_UART,
      .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
      .boot_params = S3C2410_SDRAM_PA + 0x100,
     
      .init_irq = s3c24xx_init_irq,
      .map_io  = smdk2440_map_io,
      .init_machine = smdk2440_machine_init,
      .timer  = &s3c24xx_timer,
     MACHINE_END
     
     展開宏
     
     static const struct machine_desc __mach_desc_S3C2440 \
      __used       \
      __attribute__((__section__(".arch.info.init"))) = { \
      .nr  = MACH_TYPE_S3C2440,  \
      .name  = "SMDK2440",
      /* Maintainer: Ben Dooks <ben@fluff.org> */
      .phys_io = S3C2410_PA_UART,
      .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
      .boot_params = S3C2410_SDRAM_PA + 0x100,
     
      .init_irq = s3c24xx_init_irq,
      .map_io  = smdk2440_map_io,
      .init_machine = smdk2440_machine_init,
      .timer  = &s3c24xx_timer,
     }; 
   2、建立頁表 
   3、使能MMU
   4、跳到我們內核的第一個c函數:start_kernel,這個函數會處理(theKernel (0, bd->bi_arch_number, bd->bi_boot_params);)里面的啟動參數
  
  B、掛接根文件系統
  C、最終目的:運行應用程序
 


內核的啟動流程:
 arch/arm/kernel/head.s
 
start_kernel
  setup_arch(&command_line);         //解析uboot傳入的參數
  setup_command_line(command_line);  //解析uboot傳入的參數
  parse_early_param
   do_early_param
    從__setup_start到__setup_end,調用early函數
  unknown_bootoption
   obsolete_checksetup
    從__setup_start到__setup_end,調用非early函數
  rest_init();
   kernel_init
    prepare_namespace();
     mount_root();//掛接根文件系統
    init_post();
     //執行應用程序
     
 三、Uboot傳入的命令行參數的處理
 1、說明:對於下面兩個函數只不過是把Uboot傳入的命令行參數記錄下來而已
 setup_arch(&command_line);         //解析uboot傳入的參數
 setup_command_line(command_line);  //解析uboot傳入的參數
 
我們在prepare_namespace();這個函數的時候它肯定得先確定你掛接的是哪一個文件系統:命令行參數root=/dev/mtdblock3指定
 在這個函數里面可以看到ROOT_DEV = name_to_dev_t(root_device_name);
 由於if (saved_root_name[0]) {
   root_device_name = saved_root_name;
   if (!strncmp(root_device_name, "mtd", 3)) {
    mount_block_root(root_device_name, root_mountflags);
    goto out;
   }
   ROOT_DEV = name_to_dev_t(root_device_name);
   if (strncmp(root_device_name, "/dev/", 5) == 0)
    root_device_name += 5;
  }
 在SI里面全局查找saved_root_name在哪里定義,可以搜索到一個函數和一個宏:
 static int __init root_dev_setup(char *line)
 {
  strlcpy(saved_root_name, line, sizeof(saved_root_name));
  return 1;
 }
 __setup("root=", root_dev_setup);
 由這個宏我們可以大膽的估計,在解析命令行的時候發現了root=***,然后以它找到root_dev_setup這個函數,然后調用這個
 函數,這個函數把root=***后面的***保存到變量saved_root_name里面去。
 
2、下面再分析__setup("root=", root_dev_setup);怎么執行:
 在SI里面全局查找__setup在哪里定義,技巧先查找,再在結果里面搜索define
 #define __setup(str, fn)     \
  __setup_param(str, fn, fn, 0)
 再搜索__setup_param
 #define __setup_param(str, unique_id, fn, early)   \
  static char __setup_str_##unique_id[] __initdata = str; \
  static struct obs_kernel_param __setup_##unique_id \
   __attribute_used__    \
   __attribute__((__section__(".init.setup"))) \
   __attribute__((aligned((sizeof(long))))) \
   = { __setup_str_##unique_id, fn, early }
   
 我們把__setup("root=", root_dev_setup)展開,可以分析這個就是定義了如同上面的結構體,這個結構體里面有3個重要的成員
 ①名字"root=" ②函數root_dev_setup③early
 而且__setup("root=", root_dev_setup)定義的結構體有一個特殊的屬性:__attribute__((__section__(".init.setup"))),顯然
 ".init.setup"在鏈接腳本里面
 __setup_start = .;
    *(.init.setup)
   __setup_end = .;
   
搜索一下__setup_start就可以知道命令行是怎么調用的了,在兩個函數里面被調用:
 ①函數obsolete_checksetup
 ②函數do_early_param,這個應該就是對應上面的__setup_str_##unique_id, fn, early 里面的early了。
 再找一下do_early_param是誰調用:
 parse_early_param
 由於我們傳入的參數early是0.很顯然我們用的是①函數obsolete_checksetup
 如下調用過程:
 parse_early_param
   do_early_param
    從__setup_start到__setup_end,調用early函數
 
①函數obsolete_checksetup它被unknown_bootoption調用,搜索這個函數得:它被start_kernel函數調用。
  parse_args("Booting kernel", static_command_line, __start___param,
      __stop___param - __start___param,
      &unknown_bootoption);
 如下調用過程:
 unknown_bootoption
   obsolete_checksetup
    從__setup_start到__setup_end,調用非early函數
 
四、分區表
 如果啟動參數不是下面這個,則要設置啟動參數:
 set bootargs noinitrd root=/dev/mtdblock3 rootfstype=jffs2 init=/linuxrc console=ttySAC0
 
啟動linux后,可以看到啟動時會顯示分區表:
 Creating 4 MTD partitions on "NAND 256MiB 3,3V 8-bit":
 0x00000000-0x00040000 : "bootloader"
 0x00040000-0x00060000 : "params"
 0x00060000-0x00260000 : "kernel"
 0x00260000-0x10000000 : "root"
 
book@book-desktop:/work/system/linux-2.6.22.6$ grep ".arch.info.init" * -nR
 分區應該在arch/arm/plat-s3c24xx/common-smdk.c里面
 
/* NAND parititon from 2.4.18-swl5 */
 
static struct mtd_partition smdk_default_nand_part[] = {
  [0] = {
         .name   = "bootloader",
         .size   = 0x00040000,
   .offset = 0,
  },
  [1] = {
         .name   = "params",
         .offset = MTDPART_OFS_APPEND,
         .size   = 0x00020000,
  },
  [2] = {
         .name   = "kernel",
         .offset = MTDPART_OFS_APPEND,
         .size   = 0x00200000,
  },
  [3] = {
         .name   = "root",
         .offset = MTDPART_OFS_APPEND,
         .size   = MTDPART_SIZ_FULL,
  }
 };




內核啟動流程:
{
內核的啟動流程:
arch/arm/kernel/head.s
 
start_kernel
setup_arch(&command_line);         //解析uboot傳入的參數
setup_command_line(command_line);  //解析uboot傳入的參數
parse_early_param
do_early_param
從__setup_start到__setup_end,調用early函數
unknown_bootoption
obsolete_checksetup
從__setup_start到__setup_end,調用非early函數
rest_init();
kernel_init
prepare_namespace();
mount_root();//掛接根文件系統
init_post();
//執行應用程序


}
1、./arch/arm/boot/compressed/misc.c:193: putstr(" done, booting the kernel.\n");


分析開始:


1、
head.S中得_start 標號開始分析。(有些指令不影響初始化,暫時略去不分析) 
代碼位置在/arch/arm/boot/compressed/head.S中
{
/*
*  linux/arch/arm/boot/compressed/head.S
*
*  Copyright (C) 1996-2002 Russell King
*  Copyright (C) 2004 Hyok S. Choi (MPU support)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/linkage.h>

/*
* Debugging stuff
*
* Note that these macros must not contain any code which is not
* 100% relocatable.  Any attempt to do so will result in a crash.
* Please select one of the following when turning on debugging.
*/
#ifdef DEBUG

#if defined(CONFIG_DEBUG_ICEDCC)

#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
.macro  loadsp, rb, tmp
.endm
.macro  writeb, ch, rb
mcr p14, 0, \ch, c0, c5, 0
.endm
#elif defined(CONFIG_CPU_XSCALE)
.macro  loadsp, rb, tmp
.endm
.macro  writeb, ch, rb
mcr p14, 0, \ch, c8, c0, 0
.endm
#else
.macro  loadsp, rb, tmp
.endm
.macro  writeb, ch, rb
mcr p14, 0, \ch, c1, c0, 0
.endm
#endif

#else

#include <mach/debug-macro.S>

.macro  writeb, ch, rb
senduart \ch, \rb
.endm

#if defined(CONFIG_ARCH_SA1100)
.macro  loadsp, rb, tmp
mov \rb, #0x80000000 @ physical base address
#ifdef CONFIG_DEBUG_LL_SER3
add \rb, \rb, #0x00050000 @ Ser3
#else
add \rb, \rb, #0x00010000 @ Ser1
#endif
.endm
#elif defined(CONFIG_ARCH_S3C2410)
.macro loadsp, rb, tmp
mov \rb, #0x50000000
add \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
.endm
#else
.macro  loadsp, rb, tmp
addruart \rb, \tmp
.endm
#endif
#endif
#endif

.macro  kputc,val
mov r0, \val
bl putc
.endm

.macro  kphex,val,len
mov r0, \val
mov r1, #\len
bl phex
.endm

.macro  debug_reloc_start
#ifdef DEBUG
kputc #'\n'
kphex r6, 8 /* processor id */
kputc #':'
kphex r7, 8 /* architecture id */
#ifdef CONFIG_CPU_CP15
kputc #':'
mrc p15, 0, r0, c1, c0
kphex r0, 8 /* control reg */
#endif
kputc #'\n'
kphex r5, 8 /* decompressed kernel start */
kputc #'-'
kphex r9, 8 /* decompressed kernel end  */
kputc #'>'
kphex r4, 8 /* kernel execution address */
kputc #'\n'
#endif
.endm

.macro  debug_reloc_end
#ifdef DEBUG
kphex r5, 8 /* end of kernel */
kputc #'\n'
mov r0, r4
bl memdump /* dump 256 bytes at start of kernel */
#endif
.endm

.section ".start", #alloc, #execinstr
/*
* sort out different calling conventions
*/
.align
.arm @ Always enter in ARM state
start:
.type start,#function /*uboot跳轉到內核后執行的第一條代碼*/
.rept 7 /*重復定義7次下面的指令,也就是空出中斷向量表的位置*/
mov r0, r0 /*就是nop指令*/
.endr
  ARM(  mov r0, r0  )
  ARM(  b 1f ) @ 跳轉到后面的標號1處
THUMB(  adr r12, BSYM(1f) )
THUMB(  bx r12  )

.word 0x016f2818 @ Magic numbers to help the loader @ 輔助引導程序的幻數,用來判斷鏡像是否是zImage
.word start @ absolute load/run zImage address 加載運行zImage的絕對地址,start表示賦的初值
.word _edata @ zImage end address zImage結尾地址,_edata是在vmlinux.lds.S中定義的,表示init,text,data三個段的結束位置
THUMB(  .thumb )
1: mov r7, r1 @ save architecture ID  /*標號1處*/ ID 保存體系結構ID 用r1保存
mov r8, r2 @ save atags pointer 保存r2寄存器 參數列表,r0始終為0

#ifndef __ARM_ARCH_2__
/*
* Booting from Angel - need to enter SVC mode and disable
* FIQs/IRQs (numeric definitions from angel arm.h source).
* We only do this if we were in user mode on entry.
*/
mrs r2, cpsr @ get current mode 得到當前模式
tst r2, #3 @ not user? 實際上是相與,判斷是否處於用戶模式
bne not_angel   @ 如果不是處於用戶模式,就跳轉到not_angel標號處 不相等跳轉 /*如果是普通用戶模式,則通過軟中斷進入超級用戶權限模式*/
mov r0, #0x17 @ angel_SWIreason_EnterSVC ,向SWI中傳遞參數
ARM( swi 0x123456 ) @ angel_SWI_ARM angel_SWI_ARM 這個是讓用戶空間進入SVC空間 SWI軟中斷
THUMB(  svc 0xab  ) @ angel_SWI_THUMB 
not_angel:
mrs r2, cpsr @ turn off interrupts to  /*表示非用戶模式,可以直接關閉中斷*/
orr r2, r2, #0xc0 @ prevent angel from running 關閉中斷
msr cpsr_c, r2 @ 把r2的值從新寫回到cpsr中
#else
teqp pc, #0x0c000003 @ turn off interrupts
#endif

/*
* Note that some cache flushing and other stuff may
* be needed here - is there an Angel SWI call for this?
*/

/*
* some architecture specific code can be inserted
* by the linker here, but it should preserve r7, r8, and r9.
*/

.text

#ifdef CONFIG_AUTO_ZRELADDR
@ determine final kernel image address
mov r4, pc
and r4, r4, #0xf8000000
add r4, r4, #TEXT_OFFSET
#else
ldr r4, =zreladdr
#endif

bl cache_on

restart:  adr r0, LC0 /*把地址表的起始地址放入r0中*/
ldmia r0, {r1, r2, r3, r6, r10, r11, r12} /*加載地址表中的所有地址到相應的寄存器*/@r0是運行時地址,而r1則是鏈接時地址,而它們兩都是表示LC0表的起始位置,這樣他們兩的差則是運行和鏈接的偏移量,糾正了這個偏移量才可以運行與”地址相關的代碼“
ldr sp, [r0, #28]

/*
* We might be running at a different address.  We need
* to fix up various pointers.
*/
sub r0, r0, r1 @ calculate the delta offset 計算偏移量,並放入r0中
add r6, r6, r0 @ _edata
add r10, r10, r0 @ inflated kernel size location

/*
* The kernel build system appends the size of the
* decompressed kernel at the end of the compressed data
* in little-endian form.
*/
ldrb r9, [r10, #0]
ldrb lr, [r10, #1]
orr r9, r9, lr, lsl #8
ldrb lr, [r10, #2]
ldrb r10, [r10, #3]
orr r9, r9, lr, lsl #16
orr r9, r9, r10, lsl #24

#ifndef CONFIG_ZBOOT_ROM
/* malloc space is above the relocated stack (64k max) */
add sp, sp, r0
add r10, sp, #0x10000
#else
/*
* With ZBOOT_ROM the bss/stack is non relocatable,
* but someone could still run this code from RAM,
* in which case our reference is _edata.
*/
mov r10, r6
#endif

/*
* Check to see if we will overwrite ourselves.
*   r4  = final kernel address
*   r9  = size of decompressed image
*   r10 = end of this image, including  bss/stack/malloc space if non XIP
* We basically want:
*   r4 - 16k page directory >= r10 -> OK
*   r4 + image length <= current position (pc) -> OK
*/
@vmlinux 的起始地址大於 zImage 運行時所需的最大地址( r2 ) , 那么直接將 zImage 解壓到 vmlinux 的目標地址
add r10, r10, #16384
cmp r4, r10
bhs wont_overwrite  /*如果r4大於或等於r10的話*/
add r10, r4, r9
  ARM(  cmp r10, pc  )
THUMB(  mov lr, pc  )
THUMB(  cmp r10, lr  )
bls wont_overwrite

/*
* Relocate ourselves past the end of the decompressed kernel.
*   r6  = _edata
*   r10 = end of the decompressed kernel
* Because we always copy ahead, we need to do it from the end and go
* backward in case the source and destination overlap.
*/
/*
* Bump to the next 256-byte boundary with the size of
* the relocation code added. This avoids overwriting
* ourself when the offset is small.
*/
add r10, r10, #((reloc_code_end - restart + 256) & ~255)
bic r10, r10, #255

/* Get start of code we want to copy and align it down. */
adr r5, restart
bic r5, r5, #31

sub r9, r6, r5 @ size to copy
add r9, r9, #31 @ rounded up to a multiple
bic r9, r9, #31 @ ... of 32 bytes
add r6, r9, r5
add r9, r9, r10

1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
cmp r6, r5
stmdb r9!, {r0 - r3, r10 - r12, lr}
bhi 1b

/* Preserve offset to relocated code. */
sub r6, r9, r6

#ifndef CONFIG_ZBOOT_ROM
/* cache_clean_flush may use the stack, so relocate it */
add sp, sp, r6
#endif

bl cache_clean_flush

adr r0, BSYM(restart)
add r0, r0, r6
mov pc, r0

wont_overwrite:
/*
* If delta is zero, we are running at the address we were linked at.
*   r0  = delta
*   r2  = BSS start
*   r3  = BSS end
*   r4  = kernel execution address
*   r7  = architecture ID
*   r8  = atags pointer
*   r11 = GOT start
*   r12 = GOT end
*   sp  = stack pointer
*/
teq r0, #0
beq not_relocated  @ 如果為0,則不用重定位了,直接跳轉到標號not_relocated處執行
add r11, r11, r0
add r12, r12, r0

#ifndef CONFIG_ZBOOT_ROM
/*
* If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
* we need to fix up pointers into the BSS region.
* Note that the stack pointer has already been fixed up.
*/
add r2, r2, r0
add r3, r3, r0

/*
* Relocate all entries in the GOT table.
*/
1: ldr r1, [r11, #0] @ relocate entries in the GOT
add r1, r1, r0 @ table.  This fixes up the
str r1, [r11], #4 @ C references.
cmp r11, r12
blo 1b
#else

/*
* Relocate entries in the GOT table.  We only relocate
* the entries that are outside the (relocated) BSS region.
*/
1: ldr r1, [r11, #0] @ relocate entries in the GOT
cmp r1, r2 @ entry < bss_start ||
cmphs r3, r1 @ _end < entry
addlo r1, r1, r0 @ table.  This fixes up the
str r1, [r11], #4 @ C references.
cmp r11, r12
blo 1b
#endif

not_relocated: mov r0, #0
1: str r0, [r2], #4 @ clear bss
str r0, [r2], #4
str r0, [r2], #4
str r0, [r2], #4
cmp r2, r3
blo 1b

/*
* The C runtime environment should now be setup sufficiently.
* Set up some pointers, and start decompressing.
*   r4  = kernel execution address
*   r7  = architecture ID
*   r8  = atags pointer
*/
@ 這里的 r1,r2 之間的空間為解壓縮內核程序所使用,也是傳遞給 decompress_kernel 的第二和第三的參數
mov r0, r4
mov r1, sp @ malloc space above stack
add r2, sp, #0x10000 @ 64k max
mov r3, r7
bl decompress_kernel
bl cache_clean_flush
bl cache_off
mov r0, #0 @ must be zero
mov r1, r7 @ restore architecture number
mov r2, r8 @ restore atags pointer
mov pc, r4 @ call kernel   //@ 這里就是最終我們從zImage跳轉到Image的偉大一跳了,跳之前准備好r0,r1,r2

/*讀入地址表。因為我們的代碼可以在任何地址執行,也就是位置無關代碼(PIC),所以我們需要加上一個偏移量。下面有每一個列表項的具體意義。
 
LC0是表的首項,它本身就是在此head.s中定義的
 
.type LC0, #object
 
LC0: .word LC0 @ r1 LC0表的起始位置
 
.word __bss_start @ r2 bss段的起始地址在vmlinux.lds.S中定義
 
.word _end @ r3 zImage(bss)連接的結束地址在vmlinux.lds.S中定義
 
.word zreladdr @ r4 zImage的連接地址,我們在arch/arm/mach-s3c2410/makefile.boot中定義的
 
.word _start @ r5 zImage的基地址,bootp/init.S中的_start函數,主要起傳遞參數作用
 
.word _got_start @ r6 GOT(全局偏移表)起始地址,_got_start是在compressed/vmlinux.lds.in中定義的
 
.word _got_end @ ip GOT結束地址
 
.word user_stack+4096 @ sp 用戶棧底 user_stack是緊跟在bss段的后面的,在compressed/vmlinux.lds.in中定義的
 
@ 在本head.S的末尾定義了zImag的臨時棧空間,在這里分配了4K的空間用來做堆棧。
 
.section ".stack", "w"
 
user_stack: .space 4096
 
GOT表的初值是連接器指定的,當時程序並不知道代碼在哪個地址執行。如果當前運行的地址已經和表上的地址不一樣,還要修正GOT表。
*/


.align  2
.type LC0, #object
LC0: .word LC0 @ r1
.word __bss_start @ r2
.word _end @ r3
.word _edata @ r6
.word input_data_end - 4 @ r10 (inflated size location)
.word _got_start @ r11
.word _got_end @ ip
.word .L_user_stack_end @ sp
.size LC0, . - LC0

#ifdef CONFIG_ARCH_RPC
.globl  params
params:  ldr r0, =0x10000100 @ params_phys for RPC
mov pc, lr
.ltorg
.align
#endif

/*
* Turn on the cache.  We need to setup some page tables so that we
* can have both the I and D caches on.
*
* We place the page tables 16k down from the kernel execution address,
* and we hope that nothing else is using it.  If we're using it, we
* will go pop!
*
* On entry,
*  r4 = kernel execution address
*  r7 = architecture number
*  r8 = atags pointer
* On exit,
*  r0, r1, r2, r3, r9, r10, r12 corrupted
* This routine must preserve:
*  r4, r7, r8
*/
.align  5
cache_on:  mov r3, #8  @ cache_on function
b call_cache_fn

/*
* Initialize the highest priority protection region, PR7
* to cover all 32bit address and cacheable and bufferable.
*/
__armv4_mpu_cache_on:
mov r0, #0x3f @ 4G, the whole
mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting
mcr p15, 0, r0, c6, c7, 1

mov r0, #0x80 @ PR7
mcr p15, 0, r0, c2, c0, 0 @ D-cache on
mcr p15, 0, r0, c2, c0, 1 @ I-cache on
mcr p15, 0, r0, c3, c0, 0 @ write-buffer on

mov r0, #0xc000
mcr p15, 0, r0, c5, c0, 1 @ I-access permission
mcr p15, 0, r0, c5, c0, 0 @ D-access permission

mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache
mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache
mrc p15, 0, r0, c1, c0, 0 @ read control reg
@ ...I .... ..D. WC.M
orr r0, r0, #0x002d @ .... .... ..1. 11.1
orr r0, r0, #0x1000 @ ...1 .... .... ....

mcr p15, 0, r0, c1, c0, 0 @ write control reg

mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache
mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache
mov pc, lr

__armv3_mpu_cache_on:
mov r0, #0x3f @ 4G, the whole
mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting

mov r0, #0x80 @ PR7
mcr p15, 0, r0, c2, c0, 0 @ cache on
mcr p15, 0, r0, c3, c0, 0 @ write-buffer on

mov r0, #0xc000
mcr p15, 0, r0, c5, c0, 0 @ access permission

mov r0, #0
mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
/*
* ?? ARMv3 MMU does not allow reading the control register,
* does this really work on ARMv3 MPU?
*/
mrc p15, 0, r0, c1, c0, 0 @ read control reg
@ .... .... .... WC.M
orr r0, r0, #0x000d @ .... .... .... 11.1
/* ?? this overwrites the value constructed above? */
mov r0, #0
mcr p15, 0, r0, c1, c0, 0 @ write control reg

/* ?? invalidate for the second time? */
mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
mov pc, lr

__setup_mmu:  sub r3, r4, #16384 @ Page directory size
bic r3, r3, #0xff @ Align the pointer
bic r3, r3, #0x3f00
/*
* Initialise the page tables, turning on the cacheable and bufferable
* bits for the RAM area only.
*/
mov r0, r3
mov r9, r0, lsr #18
mov r9, r9, lsl #18 @ start of RAM
add r10, r9, #0x10000000 @ a reasonable RAM size
mov r1, #0x12
orr r1, r1, #3 << 10
add r2, r3, #16384
1: cmp r1, r9 @ if virt > start of RAM
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
orrhs r1, r1, #0x08 @ set cacheable
#else
orrhs r1, r1, #0x0c @ set cacheable, bufferable
#endif
cmp r1, r10 @ if virt > end of RAM
bichs r1, r1, #0x0c @ clear cacheable, bufferable
str r1, [r0], #4 @ 1:1 mapping
add r1, r1, #1048576
teq r0, r2
bne 1b
/*
* If ever we are running from Flash, then we surely want the cache
* to be enabled also for our execution instance...  We map 2MB of it
* so there is no map overlap problem for up to 1 MB compressed kernel.
* If the execution is in RAM then we would only be duplicating the above.
*/
mov r1, #0x1e
orr r1, r1, #3 << 10
mov r2, pc
mov r2, r2, lsr #20
orr r1, r1, r2, lsl #20
add r0, r3, r2, lsl #2
str r1, [r0], #4
add r1, r1, #1048576
str r1, [r0]
mov pc, lr
ENDPROC(__setup_mmu)

__arm926ejs_mmu_cache_on:
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
mov r0, #4 @ put dcache in WT mode
mcr p15, 7, r0, c15, c0, 0
#endif

__armv4_mmu_cache_on:
mov r12, lr
#ifdef CONFIG_MMU
bl __setup_mmu
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
mrc p15, 0, r0, c1, c0, 0 @ read control reg
orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
orr r0, r0, #0x0030
#ifdef CONFIG_CPU_ENDIAN_BE8
orr r0, r0, #1 << 25 @ big-endian page tables
#endif
bl __common_mmu_cache_on
mov r0, #0
mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
#endif
mov pc, r12

__armv7_mmu_cache_on:
mov r12, lr
#ifdef CONFIG_MMU
mrc p15, 0, r11, c0, c1, 4 @ read ID_MMFR0
tst r11, #0xf @ VMSA
blne __setup_mmu
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
tst r11, #0xf @ VMSA
mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
#endif
mrc p15, 0, r0, c1, c0, 0 @ read control reg
orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
orr r0, r0, #0x003c @ write buffer
#ifdef CONFIG_MMU
#ifdef CONFIG_CPU_ENDIAN_BE8
orr r0, r0, #1 << 25 @ big-endian page tables
#endif
orrne r0, r0, #1 @ MMU enabled
movne r1, #-1
mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer
mcrne p15, 0, r1, c3, c0, 0 @ load domain access control
#endif
mcr p15, 0, r0, c1, c0, 0 @ load control register
mrc p15, 0, r0, c1, c0, 0 @ and read it back
mov r0, #0
mcr p15, 0, r0, c7, c5, 4 @ ISB
mov pc, r12

__fa526_cache_on:
mov r12, lr
bl __setup_mmu
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 @ Invalidate whole cache
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
mcr p15, 0, r0, c8, c7, 0 @ flush UTLB
mrc p15, 0, r0, c1, c0, 0 @ read control reg
orr r0, r0, #0x1000 @ I-cache enable
bl __common_mmu_cache_on
mov r0, #0
mcr p15, 0, r0, c8, c7, 0 @ flush UTLB
mov pc, r12

__arm6_mmu_cache_on:
mov r12, lr
bl __setup_mmu
mov r0, #0
mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
mov r0, #0x30
bl __common_mmu_cache_on
mov r0, #0
mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
mov pc, r12

__common_mmu_cache_on:
#ifndef CONFIG_THUMB2_KERNEL
#ifndef DEBUG
orr r0, r0, #0x000d @ Write buffer, mmu
#endif
mov r1, #-1
mcr p15, 0, r3, c2, c0, 0 @ load page table pointer
mcr p15, 0, r1, c3, c0, 0 @ load domain access control
b 1f
.align  5 @ cache line aligned
1: mcr p15, 0, r0, c1, c0, 0 @ load control register
mrc p15, 0, r0, c1, c0, 0 @ and read it back to
sub pc, lr, r0, lsr #32 @ properly flush pipeline
#endif

#define PROC_ENTRY_SIZE (4*5)

/*
* Here follow the relocatable cache support functions for the
* various processors.  This is a generic hook for locating an
* entry and jumping to an instruction at the specified offset
* from the start of the block.  Please note this is all position
* independent code.
*
*  r1  = corrupted
*  r2  = corrupted
*  r3  = block offset
*  r9  = corrupted
*  r12 = corrupted
*/

call_cache_fn: adr r12, proc_types
#ifdef CONFIG_CPU_CP15
mrc p15, 0, r9, c0, c0 @ get processor ID
#else
ldr r9, =CONFIG_PROCESSOR_ID
#endif
1: ldr r1, [r12, #0] @ get value
ldr r2, [r12, #4] @ get mask
eor r1, r1, r9 @ (real ^ match)
tst r1, r2 @       & mask
ARM( addeq pc, r12, r3 ) @ call cache function
THUMB(  addeq r12, r3  )
THUMB(  moveq pc, r12  ) @ call cache function
add r12, r12, #PROC_ENTRY_SIZE
b 1b

/*
* Table for cache operations.  This is basically:
*   - CPU ID match
*   - CPU ID mask
*   - 'cache on' method instruction
*   - 'cache off' method instruction
*   - 'cache flush' method instruction
*
* We match an entry using: ((real_id ^ match) & mask) == 0
*
* Writethrough caches generally only need 'on' and 'off'
* methods.  Writeback caches _must_ have the flush method
* defined.
*/
.align  2
.type proc_types,#object
proc_types:
.word 0x41560600 @ ARM6/610
.word 0xffffffe0
W(b) __arm6_mmu_cache_off @ works, but slow
W(b) __arm6_mmu_cache_off
mov pc, lr
THUMB(  nop )
@ b __arm6_mmu_cache_on @ untested
@ b __arm6_mmu_cache_off
@ b __armv3_mmu_cache_flush

#if !defined(CONFIG_CPU_V7)
/* This collides with some V7 IDs, preventing correct detection */
.word 0x00000000 @ old ARM ID
.word 0x0000f000
mov pc, lr
THUMB(  nop )
mov pc, lr
THUMB(  nop )
mov pc, lr
THUMB(  nop )
#endif

.word 0x41007000 @ ARM7/710
.word 0xfff8fe00
W(b) __arm7_mmu_cache_off
W(b) __arm7_mmu_cache_off
mov pc, lr
THUMB(  nop )

.word 0x41807200 @ ARM720T (writethrough)
.word 0xffffff00
W(b) __armv4_mmu_cache_on
W(b) __armv4_mmu_cache_off
mov pc, lr
THUMB(  nop )

.word 0x41007400 @ ARM74x
.word 0xff00ff00
W(b) __armv3_mpu_cache_on
W(b) __armv3_mpu_cache_off
W(b) __armv3_mpu_cache_flush

.word 0x41009400 @ ARM94x
.word 0xff00ff00
W(b) __armv4_mpu_cache_on
W(b) __armv4_mpu_cache_off
W(b) __armv4_mpu_cache_flush

.word 0x41069260 @ ARM926EJ-S (v5TEJ)
.word 0xff0ffff0
W(b) __arm926ejs_mmu_cache_on
W(b) __armv4_mmu_cache_off
W(b) __armv5tej_mmu_cache_flush

.word 0x00007000 @ ARM7 IDs
.word 0x0000f000
mov pc, lr
THUMB(  nop )
mov pc, lr
THUMB(  nop )
mov pc, lr
THUMB(  nop )

@ Everything from here on will be the new ID system.

.word 0x4401a100 @ sa110 / sa1100
.word 0xffffffe0
W(b) __armv4_mmu_cache_on
W(b) __armv4_mmu_cache_off
W(b) __armv4_mmu_cache_flush

.word 0x6901b110 @ sa1110
.word 0xfffffff0
W(b) __armv4_mmu_cache_on
W(b) __armv4_mmu_cache_off
W(b) __armv4_mmu_cache_flush

.word 0x56056900
.word 0xffffff00 @ PXA9xx
W(b) __armv4_mmu_cache_on
W(b) __armv4_mmu_cache_off
W(b) __armv4_mmu_cache_flush

.word 0x56158000 @ PXA168
.word 0xfffff000
W(b) __armv4_mmu_cache_on
W(b) __armv4_mmu_cache_off
W(b) __armv5tej_mmu_cache_flush

.word 0x56050000 @ Feroceon
.word 0xff0f0000
W(b) __armv4_mmu_cache_on
W(b) __armv4_mmu_cache_off
W(b) __armv5tej_mmu_cache_flush

#ifdef CONFIG_CPU_FEROCEON_OLD_ID
/* this conflicts with the standard ARMv5TE entry */
.long 0x41009260 @ Old Feroceon
.long 0xff00fff0
b __armv4_mmu_cache_on
b __armv4_mmu_cache_off
b __armv5tej_mmu_cache_flush
#endif

.word 0x66015261 @ FA526
.word 0xff01fff1
W(b) __fa526_cache_on
W(b) __armv4_mmu_cache_off
W(b) __fa526_cache_flush

@ These match on the architecture ID

.word 0x00020000 @ ARMv4T
.word 0x000f0000
W(b) __armv4_mmu_cache_on
W(b) __armv4_mmu_cache_off
W(b) __armv4_mmu_cache_flush

.word 0x00050000 @ ARMv5TE
.word 0x000f0000
W(b) __armv4_mmu_cache_on
W(b) __armv4_mmu_cache_off
W(b) __armv4_mmu_cache_flush

.word 0x00060000 @ ARMv5TEJ
.word 0x000f0000
W(b) __armv4_mmu_cache_on
W(b) __armv4_mmu_cache_off
W(b) __armv5tej_mmu_cache_flush

.word 0x0007b000 @ ARMv6
.word 0x000ff000
W(b) __armv4_mmu_cache_on
W(b) __armv4_mmu_cache_off
W(b) __armv6_mmu_cache_flush

.word 0x000f0000 @ new CPU Id
.word 0x000f0000
W(b) __armv7_mmu_cache_on
W(b) __armv7_mmu_cache_off
W(b) __armv7_mmu_cache_flush

.word 0 @ unrecognised type
.word 0
mov pc, lr
THUMB(  nop )
mov pc, lr
THUMB(  nop )
mov pc, lr
THUMB(  nop )

.size proc_types, . - proc_types

/*
* If you get a "non-constant expression in ".if" statement"
* error from the assembler on this line, check that you have
* not accidentally written a "b" instruction where you should
* have written W(b).
*/
.if (. - proc_types) % PROC_ENTRY_SIZE != 0
.error "The size of one or more proc_types entries is wrong."
.endif

/*
* Turn off the Cache and MMU.  ARMv3 does not support
* reading the control register, but ARMv4 does.
*
* On exit,
*  r0, r1, r2, r3, r9, r12 corrupted
* This routine must preserve:
*  r4, r7, r8
*/
.align  5
cache_off:  mov r3, #12  @ cache_off function
b call_cache_fn

__armv4_mpu_cache_off:
mrc p15, 0, r0, c1, c0
bic r0, r0, #0x000d
mcr p15, 0, r0, c1, c0 @ turn MPU and cache off
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
mcr p15, 0, r0, c7, c6, 0 @ flush D-Cache
mcr p15, 0, r0, c7, c5, 0 @ flush I-Cache
mov pc, lr

__armv3_mpu_cache_off:
mrc p15, 0, r0, c1, c0
bic r0, r0, #0x000d
mcr p15, 0, r0, c1, c0, 0 @ turn MPU and cache off
mov r0, #0
mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
mov pc, lr

__armv4_mmu_cache_off:
#ifdef CONFIG_MMU
mrc p15, 0, r0, c1, c0
bic r0, r0, #0x000d
mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
mov r0, #0
mcr p15, 0, r0, c7, c7 @ invalidate whole cache v4
mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4
#endif
mov pc, lr

__armv7_mmu_cache_off:
mrc p15, 0, r0, c1, c0
#ifdef CONFIG_MMU
bic r0, r0, #0x000d
#else
bic r0, r0, #0x000c
#endif
mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
mov r12, lr
bl __armv7_mmu_cache_flush
mov r0, #0
#ifdef CONFIG_MMU
mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB
#endif
mcr p15, 0, r0, c7, c5, 6 @ invalidate BTC
mcr p15, 0, r0, c7, c10, 4 @ DSB
mcr p15, 0, r0, c7, c5, 4 @ ISB
mov pc, r12

__arm6_mmu_cache_off:
mov r0, #0x00000030 @ ARM6 control reg.
b __armv3_mmu_cache_off

__arm7_mmu_cache_off:
mov r0, #0x00000070 @ ARM7 control reg.
b __armv3_mmu_cache_off

__armv3_mmu_cache_off:
mcr p15, 0, r0, c1, c0, 0 @ turn MMU and cache off
mov r0, #0
mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
mov pc, lr

/*
* Clean and flush the cache to maintain consistency.
*
* On exit,
*  r1, r2, r3, r9, r10, r11, r12 corrupted
* This routine must preserve:
*  r4, r6, r7, r8
*/
.align  5
cache_clean_flush:
mov r3, #16
b call_cache_fn

__armv4_mpu_cache_flush:
mov r2, #1
mov r3, #0
mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
mov r1, #7 << 5 @ 8 segments
1: orr r3, r1, #63 << 26 @ 64 entries
2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index
subs r3, r3, #1 << 26
bcs 2b @ entries 63 to 0
subs r1, r1, #1 << 5
bcs 1b @ segments 7 to 0

teq r2, #0
mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
mcr p15, 0, ip, c7, c10, 4 @ drain WB
mov pc, lr

__fa526_cache_flush:
mov r1, #0
mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache
mcr p15, 0, r1, c7, c5, 0 @ flush I cache
mcr p15, 0, r1, c7, c10, 4 @ drain WB
mov pc, lr

__armv6_mmu_cache_flush:
mov r1, #0
mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D
mcr p15, 0, r1, c7, c5, 0 @ invalidate I+BTB
mcr p15, 0, r1, c7, c15, 0 @ clean+invalidate unified
mcr p15, 0, r1, c7, c10, 4 @ drain WB
mov pc, lr

__armv7_mmu_cache_flush:
mrc p15, 0, r10, c0, c1, 5 @ read ID_MMFR1
tst r10, #0xf << 16 @ hierarchical cache (ARMv7)
mov r10, #0
beq hierarchical
mcr p15, 0, r10, c7, c14, 0 @ clean+invalidate D
b iflush
hierarchical:
mcr p15, 0, r10, c7, c10, 5 @ DMB
stmfd sp!, {r0-r7, r9-r11}
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq finished @ if loc is 0, then no need to clean
mov r10, #0 @ start clean at cache level 0
loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt skip @ skip if no cache, or just i-cache
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
mcr p15, 0, r10, c7, c5, 4 @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
loop2:
mov r9, r4 @ create working copy of max way size
loop3:
ARM( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
ARM( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB(  lsl r6, r9, r5 )
THUMB(  orr r11, r10, r6 ) @ factor way and cache number into r11
THUMB(  lsl r6, r7, r2 )
THUMB(  orr r11, r11, r6 ) @ factor index number into r11
mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
subs r9, r9, #1 @ decrement the way
bge loop3
subs r7, r7, #1 @ decrement the index
bge loop2
skip:
add r10, r10, #2 @ increment cache number
cmp r3, r10
bgt loop1
finished:
ldmfd sp!, {r0-r7, r9-r11}
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
iflush:
mcr p15, 0, r10, c7, c10, 4 @ DSB
mcr p15, 0, r10, c7, c5, 0 @ invalidate I+BTB
mcr p15, 0, r10, c7, c10, 4 @ DSB
mcr p15, 0, r10, c7, c5, 4 @ ISB
mov pc, lr

__armv5tej_mmu_cache_flush:
1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate D cache
bne 1b
mcr p15, 0, r0, c7, c5, 0 @ flush I cache
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mov pc, lr

__armv4_mmu_cache_flush:
mov r2, #64*1024 @ default: 32K dcache size (*2)
mov r11, #32 @ default: 32 byte line size
mrc p15, 0, r3, c0, c0, 1 @ read cache type
teq r3, r9 @ cache ID register present?
beq no_cache_id
mov r1, r3, lsr #18
and r1, r1, #7
mov r2, #1024
mov r2, r2, lsl r1 @ base dcache size *2
tst r3, #1 << 14 @ test M bit
addne r2, r2, r2, lsr #1 @ +1/2 size if M == 1
mov r3, r3, lsr #12
and r3, r3, #3
mov r11, #8
mov r11, r11, lsl r3 @ cache line size in bytes
no_cache_id:
mov r1, pc
bic r1, r1, #63 @ align to longest cache line
add r2, r1, r2
1:
ARM( ldr r3, [r1], r11 ) @ s/w flush D cache
THUMB(  ldr     r3, [r1] ) @ s/w flush D cache
THUMB(  add     r1, r1, r11 )
teq r1, r2
bne 1b

mcr p15, 0, r1, c7, c5, 0 @ flush I cache
mcr p15, 0, r1, c7, c6, 0 @ flush D cache
mcr p15, 0, r1, c7, c10, 4 @ drain WB
mov pc, lr

__armv3_mmu_cache_flush:
__armv3_mpu_cache_flush:
mov r1, #0
mcr p15, 0, r1, c7, c0, 0 @ invalidate whole cache v3
mov pc, lr

/*
* Various debugging routines for printing hex characters and
* memory, which again must be relocatable.
*/
#ifdef DEBUG
.align  2
.type phexbuf,#object
phexbuf:  .space 12
.size phexbuf, . - phexbuf

@ phex corrupts {r0, r1, r2, r3}
phex: adr r3, phexbuf
mov r2, #0
strb r2, [r3, r1]
1: subs r1, r1, #1
movmi r0, r3
bmi puts
and r2, r0, #15
mov r0, r0, lsr #4
cmp r2, #10
addge r2, r2, #7
add r2, r2, #'0'
strb r2, [r3, r1]
b 1b

@ puts corrupts {r0, r1, r2, r3}
puts: loadsp r3, r1
1: ldrb r2, [r0], #1
teq r2, #0
moveq pc, lr
2: writeb r2, r3
mov r1, #0x00020000
3: subs r1, r1, #1
bne 3b
teq r2, #'\n'
moveq r2, #'\r'
beq 2b
teq r0, #0
bne 1b
mov pc, lr
@ putc corrupts {r0, r1, r2, r3}
putc:
mov r2, r0
mov r0, #0
loadsp  r3, r1
b 2b

@ memdump corrupts {r0, r1, r2, r3, r10, r11, r12, lr}
memdump:  mov r12, r0
mov r10, lr
mov r11, #0
2: mov r0, r11, lsl #2
add r0, r0, r12
mov r1, #8
bl phex
mov r0, #':'
bl putc
1: mov r0, #' '
bl putc
ldr r0, [r12, r11, lsl #2]
mov r1, #8
bl phex
and r0, r11, #7
teq r0, #3
moveq r0, #' '
bleq putc
and r0, r11, #7
add r11, r11, #1
teq r0, #7
bne 1b
mov r0, #'\n'
bl putc
cmp r11, #64
blt 2b
mov pc, r10
#endif

.ltorg
reloc_code_end:

.align
.section ".stack", "aw", %nobits
.L_user_stack: .space 4096
.L_user_stack_end:


}
./arch/arm/boot/compressed/misc.c:174:decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,


2、進入內核的第二階段:
內核啟動第二階段主要完成的工作有,cpu ID檢查,machine ID(也就是開發板ID)檢查,創建初始化頁表,設置C代碼運行環境,跳轉到內核第一個真正的C函數startkernel開始執行
這一階段涉及到兩個重要的結構體:
 
(1) 一個是struct proc_info_list 主要描述CPU相關的信息,定義在文件arch\arm\include\asm\procinfo.h中,與其相關的函數及變量在文件arch/arm/mm/proc_arm920.S中被定義和賦值。
 
(2) 另一個結構體是描述開發板或者說機器信息的結構體struct machine_desc,定義在\arch\arm\include\asm\mach\arch.h文件中,其函數的定義和變量的賦值在板極相關文件arch/arm/mach-s3c2410/mach-smdk2410.c中實現,這也是內核移植非常重要的一個文件。
 
該階段一般由前面的解壓縮代碼調用,進入該階段要求:
 
MMU = off, D-cache = off, I-cache = dont care,r0 = 0, r1 = machine id.
 
所有的機器ID列表保存在arch/arm/tools/mach-types 文件中,在編譯時會將這些機器ID按照統一的格式鏈接到基本內核映像文件vmlinux的__arch_info_begin和__arch_info_end之間的段中。存儲格式定義在include/asm-arm/mach/arch.h文件中的結構體struct machine_desc {}。這兩個結構體的內容最終會被連接到基本內核映像vmlinux中的兩個段內,分別是*(.proc.info.init)和*(.arch.info.init),可以參考下面的連接腳本。
 
鏈接腳本:arch/arm/kernel/vmlinux.lds
{
鏈接腳本:arch/arm/kernel/vmlinux.lds
 
*****************************鏈接腳本**************************************
 
SECTIONS
 
{
 
. = TEXTADDR;
 
.init : { /* 初始化代碼段*/
 
_stext = .;
 
_sinittext = .;
 
*(.init.text)
 
_einittext = .;
 
__proc_info_begin = .;
 
*(.proc.info.init)
 
__proc_info_end = .;
 
__arch_info_begin = .;
 
*(.arch.info.init)
 
__arch_info_end = .;
 
__tagtable_begin = .;
 
*(.taglist.init)
 
__tagtable_end = .;
 
. = ALIGN(16);
 
__setup_start = .;
 
*(.init.setup)
 
__setup_end = .;
 
__early_begin = .;
 
*(.early_param.init)
 
__early_end = .;
 
__initcall_start = .;
 
*(.initcall1.init)
 
*(.initcall2.init)
 
*(.initcall3.init)
 
*(.initcall4.init)
 
*(.initcall5.init)
 
*(.initcall6.init)
 
*(.initcall7.init)
 
__initcall_end = .;
 
__con_initcall_start = .;
 
*(.con_initcall.init)
 
__con_initcall_end = .;
 
__security_initcall_start = .;
 
*(.security_initcall.init)
 
__security_initcall_end = .;
 
. = ALIGN(32);
 
__initramfs_start = .;
 
usr/built-in.o(.init.ramfs)
 
__initramfs_end = .;
 
. = ALIGN(64);
 
__per_cpu_start = .;
 
*(.data.percpu)
 
__per_cpu_end = .;
 
#ifndef CONFIG_XIP_KERNEL
 
__init_begin = _stext;
 
*(.init.data)
 
. = ALIGN(4096);
 
__init_end = .;
 
#endif
 
}
 
*****************************鏈接腳本**************************************
 
下面開始代碼\arch\arm\kernel\head.S的注釋:


}


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. //./arch/arm/mach-hi3518/core.c +307
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 16256 //vim ./mm/page_alloc.c +3307
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) //./mm/page_alloc.c:5435:
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes) //./mm/page_alloc.c +5435
Memory: 64MB = 64MB total  //./arch/arm/mm/init.c +613: printk(KERN_INFO "Memory:");./arch/arm/mm/init.c +623
Memory: 59748k/59748k available, 5788k reserved, 0K highmem
Virtual kernel memory layout: //./arch/arm/mm/init.c +633
    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 //./mm/slub.c +3327
NR_IRQS:32 nr_irqs:32 32 //./kernel/irq/irqdesc.c +218 
sched_clock: 32 bits at 100MHz, resolution 10ns, wraps every 42949ms ./arch/arm/kernel/sched_clock.c +55
Console: colour dummy device 80x30 //./drivers/tty/vt/vt.c +2933
Calibrating delay loop... 218.72 BogoMIPS (lpj=1093632) //./arch/frv/kernel/setup.c +714
pid_max: default: 32768 minimum: 301 //./kernel/pid.c +561
Mount-cache hash table entries: 512 //./fs/namespace.c +2688
CPU: Testing write buffer coherency: ok //./arch/arm/mm/fault-armv.c +ss240
devtmpfs: initialized //./drivers/base/devtmpfs.c +394
NET: Registered protocol family 16 //./net/socket.c +2480
Serial: AMBA PL011 UART driver //./drivers/tty/serial/amba-pl011.c +2051
uart:0: ttyAMA0 at MMIO 0x20080000 (irq = 5) is a PL011 rev2 //./arch/arm/mach-hi3518/core.c +477
console [ttyAMA0] enabled
uart:1: ttyAMA1 at MMIO 0x20090000 (irq = 5) is a PL011 rev2
bio: create slab <bio-0> at 0 //./fs/bio.c +114
SCSI subsystem initialized //./drivers/scsi/scsi.c +1332
usbcore: registered new interface driver usbfs //./drivers/usb/core/driver.c +879
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
Switching to clocksource timer1 //./kernel/time/clocksource.c +577
NET: Registered protocol family 2 //./net/socket.c +2480
IP route cache hash table entries: 1024 (order: 0, 4096 bytes) // ./mm/page_alloc.c +5435
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) //./arch/arm/nwfpe/fpmodule.c +101
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


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












/*===========================================hi3518c start kernel end =============================================*/


1、第一句話的打印信息為:locationi:/init/Version.c
const char linux_banner[] =
"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
2、


內核初始化后跳轉到start_kernel()
,start_kernel()最后調用rest_init();驅動中初始化內容在rest_init()中調用
init/main.c中
static noinline void __init_refok rest_init(void)
    __releases(kernel_lock)
{
    int pid;


    kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);  //加載
    numa_default_policy();
    pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
    kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
    unlock_kernel();


    /*
     * The boot idle thread must execute schedule()
     * at least once to get things moving:
     */
    init_idle_bootup_task(current);
    rcu_scheduler_starting();
    preempt_enable_no_resched();
    schedule();
    preempt_disable();


    /* Call into cpu_idle with preempt disabled */
    cpu_idle();
}


kernel_init在
static int __init kernel_init(void * unused)
{
    lock_kernel();


    /*
     * init can allocate pages on any node
     */
    set_mems_allowed(node_possible_map);
    /*
     * init can run on any cpu.
     */
    set_cpus_allowed_ptr(current, cpu_all_mask);
    /*
     * Tell the world that we're going to be the grim
     * reaper of innocent orphaned children.
     *
     * We don't want people to have to make incorrect
     * assumptions about where in the task array this
     * can be found.
     */
    init_pid_ns.child_reaper = current;


    cad_pid = task_pid(current);


    smp_prepare_cpus(setup_max_cpus);


    do_pre_smp_initcalls();
    start_boot_trace();


    smp_init();
    sched_init_smp();


    do_basic_setup();  //在此基本設置


    /*
     * check if there is an early userspace init.  If yes, let it do all
     * the work
     */


    if (!ramdisk_execute_command)
        ramdisk_execute_command = "/init";


    if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
        ramdisk_execute_command = NULL;
        prepare_namespace();
    }


    /*
     * Ok, we have completed the initial bootup, and
     * we're essentially up and running. Get rid of the
     * initmem segments and start the user-mode stuff..
     */


    init_post();
    return 0;
}


 do_basic_setup(); 
static void __init do_basic_setup(void)
{
    rcu_init_sched(); /* needed by module_init stage. */
    init_workqueues();
    cpuset_init_smp();
    usermodehelper_init();
    driver_init();//驅動初始化
    init_irq_proc();
    do_ctors();
    do_initcalls();  //調用
}


關於調用順序知識
在2.6內核中,initcall.init區段又分成7個子區段,分別是 
.initcall1.init 
.initcall2.init 
.initcall3.init 
.initcall4.init 
.initcall5.init 
.initcall6.init 
.initcall7.init 


當需要把函數fn放到.initcall1.init區段時,只要聲明 
core_initcall(fn); 
即可。 


其他的各個區段的定義方法分別是: 
core_initcall(fn) --->.initcall1.init 
postcore_initcall(fn) --->.initcall2.init 
arch_initcall(fn) --->.initcall3.init 
subsys_initcall(fn) --->.initcall4.init 
fs_initcall(fn) --->.initcall5.init 
device_initcall(fn) --->.initcall6.init 
late_initcall(fn) --->.initcall7.init 


而與2.4兼容的initcall(fn)則等價於device_initcall(fn)。 


各個子區段之間的順序是確定的,即先調用.initcall1.init中的函數指針 
再調用.initcall2.init中的函數指針,等等。 
而在每個子區段中的函數指針的順序是和鏈接順序相關的,是不確定的。 


在內核中,不同的init函數被放在不同的子區段中,因此也就決定了它們的調用順序。 
這樣也就解決了一些init函數之間必須保證一定的調用順序的問題。 
********************************************
MACHINE_START(MX28EVK, "Freescale MX28EVK board")
    .phys_io    = 0x80000000,
    .io_pg_offst    = ((0xf0000000) >> 18) & 0xfffc,
    .boot_params    = 0x40000100,
    .fixup        = fixup_board,
    .map_io        = mx28_map_io,
    .init_irq    = mx28_irq_init,
    .init_machine    = mx28evk_init_machine,
    .timer        = &mx28_timer.timer,
MACHINE_END
由上發現,MACHINE_START主要是定義了"struct machine_desc"的類型,放在 section(".arch.info.init"),是初始化數據,Kernel 起來之后將被丟棄。
 
各個成員函數在不同時期被調用:
1. .init_machine 在 arch/arm/kernel/setup.c 中被 customize_machine 調用,放在 arch_initcall() 段里面,會自動按順序被調用。
 
2. init_irq在start_kernel() --> init_IRQ() --> init_arch_irq() 被調用
3. map_io 在 setup_arch() --> paging_init() --> devicemaps_init()被調用
 
其他主要都在 setup_arch() 中用到。
 




*************************************
static void __init do_initcalls(void)
{
    initcall_t *call;


    for (call = __early_initcall_end; call < __initcall_end; call++)
        do_one_initcall(*call);


    /* Make sure there is no pending stuff from the initcall sequence */
    flush_scheduled_work();
}
 這個__initcall_start是在文件        arch/xxx/kernel/vmlinux.lds.S (其中的xxx 是你的體系結構的名稱,例如i386)這個文件是內核ld的時候使用的.其中定義了各個sectioin,看看就明白了。在這個文件中有個.initcall.init, 代碼如下: 




./init/main.c:821 driver_init()




./drivers/usb/host/hiusb-3518.c
./drivers/usb/host/.hiusb-3518.o.cmd
./drivers/usb/host/hiusb-3518.o
./drivers/mtd/devices/hisfc350/hisfc350_3518.c
./drivers/mtd/nand/hinfc301/hinfc301_3518.c
./drivers/net/hieth-sf/sys-3518.c
./drivers/mmc/host/himciv100/himci_3518.c
./drivers/cpufreq/hi3518-cpufreq.c
./drivers/cpufreq/.hi3518-cpufreq.o.cmd
./drivers/cpufreq/hi3518-cpufreq.o
./include/config/hi3518
./include/config/mach/hi3518.h
./include/config/arch/hi3518.h
./config_hi3518c
./arch/arm/mach-hi3518


./mm/.highmem.o.cmd
./mm/highmem.o
./mm/highmem.c
./kernel/power/hibernate.c
./kernel/irq/generic-chip.c
./kernel/irq/dummychip.c
./kernel/irq/.dummychip.o.cmd
./kernel/irq/chip.o
./kernel/irq/dummychip.o
./kernel/irq/chip.c
./kernel/irq/.chip.o.cmd
./kernel/stop_machine.c
./net/dccp/ccids/lib/packet_history.h
./net/dccp/ccids/lib/packet_history.c
./net/802/hippi.c
./net/ipv4/tcp_highspeed.c
./net/bluetooth/hidp
./net/bluetooth/hidp/hidp.h
./drivers/input/serio/hil_mlc.c
./drivers/input/touchscreen/hampshire.c
./drivers/input/touchscreen/touchit213.c
./drivers/input/keyboard/hilkbd.c
./drivers/input/keyboard/hil_kbd.c
./drivers/tty/vt/defkeymap.c_shipped
./drivers/sh/intc/chip.c
./drivers/hid
./drivers/hid/hid-ntrig.c
./drivers/hid/hid-belkin.c
./drivers/hid/hid-roccat-kovaplus.h
./drivers/hid/hid-lgff.c
./drivers/hid/hid-ezkey.c
./drivers/hid/hid-emsff.c
./drivers/hid/hid-waltop.c
./drivers/hid/hid-roccat-koneplus.h
./drivers/hid/hid-debug.o
./drivers/hid/hid-dr.c
./drivers/hid/hid-roccat-kovaplus.c
./drivers/hid/hid-elecom.c
./drivers/hid/.hid-core.o.cmd
./drivers/hid/hid-roccat-kone.c
./drivers/hid/hid-samsung.c
./drivers/hid/hid-microsoft.c
./drivers/hid/hid-lcpower.c
./drivers/hid/hid-petalynx.c
./drivers/hid/hid-roccat.c
./drivers/hid/hidraw.c
./drivers/hid/hid-magicmouse.c
./drivers/hid/hid-roccat-pyra.c
./drivers/hid/hid-ortek.c
./drivers/hid/.hid-input.o.cmd
./drivers/hid/hid-lg3ff.c
./drivers/hid/hid-kye.c
./drivers/hid/.hid.o.cmd
./drivers/hid/hid-input.o
./drivers/hid/hid-apple.c
./drivers/hid/hid-monterey.c
./drivers/hid/hid-kensington.c
./drivers/hid/hid-ids.h
./drivers/hid/hid-gaff.c
./drivers/hid/hid-tmff.c
./drivers/hid/hid-input.c
./drivers/hid/hid-zydacron.c
./drivers/hid/hid-uclogic.c
./drivers/hid/usbhid
./drivers/hid/usbhid/.hid-core.o.cmd
./drivers/hid/usbhid/hid-pidff.c
./drivers/hid/usbhid/hid-quirks.c
./drivers/hid/usbhid/usbhid.h
./drivers/hid/usbhid/hid-core.o
./drivers/hid/usbhid/hiddev.c
./drivers/hid/usbhid/hid-quirks.o
./drivers/hid/usbhid/.usbhid.o.cmd
./drivers/hid/usbhid/.hid-quirks.o.cmd
./drivers/hid/usbhid/hid-core.c
./drivers/hid/usbhid/usbhid.o
./drivers/hid/hid-cherry.c
./drivers/hid/hid-sjoy.c
./drivers/hid/hid-chicony.c
./drivers/hid/hid-core.o
./drivers/hid/hid-roccat-arvo.c
./drivers/hid/hid-prodikeys.c
./drivers/hid/hid-sunplus.c
./drivers/hid/hid-roccat-pyra.h
./drivers/hid/hid-roccat-koneplus.c
./drivers/hid/hid-wacom.c
./drivers/hid/hid-roccat-common.h
./drivers/hid/hid-axff.c
./drivers/hid/hid-a4tech.c
./drivers/hid/hid-twinhan.c
./drivers/hid/hid.o
./drivers/hid/hid-lg.h
./drivers/hid/hid-cypress.c
./drivers/hid/hid-gyration.c
./drivers/hid/hid-quanta.c
./drivers/hid/hid-sony.c
./drivers/hid/hid-debug.c
./drivers/hid/hid-roccat-common.c
./drivers/hid/.hid-debug.o.cmd
./drivers/hid/hid-roccat-kone.h
./drivers/hid/hid-topseed.c
./drivers/hid/hid-keytouch.c
./drivers/hid/hid-pl.c
./drivers/hid/hid-picolcd.c
./drivers/hid/hid-lg2ff.c
./drivers/hid/hid-core.c
./drivers/hid/hid-zpff.c
./drivers/hid/hid-multitouch.c
./drivers/hid/hid-lg.c
./drivers/hid/hid-roccat-arvo.h
./drivers/hid/hid-lg4ff.c
./drivers/usb/host/hiusb-ohci.c
./drivers/usb/host/hiusb.h
./drivers/usb/host/hiusb-godarm.c
./drivers/usb/host/hiusb-godbox.c
./drivers/usb/host/hiusb-3518.c
./drivers/usb/host/Kconfig.hiusb
./drivers/usb/host/hiusb-godbox_v1.c
./drivers/usb/host/hiusb-phoenix.c
./drivers/usb/host/hiusb-godnet.c
./drivers/usb/host/hiusb-ehci.c
./drivers/usb/host/hiusb-hi3520d.c
./drivers/usb/host/.hiusb-3518.o.cmd
./drivers/usb/host/hiusb-godeyes.c
./drivers/usb/host/hiusb-3518.o
./drivers/usb/serial/ChangeLog.history
./drivers/usb/serial/whiteheat.h
./drivers/usb/serial/whiteheat.c
./drivers/usb/core/otg_whitelist.h
./drivers/usb/gadget/hid.c
./drivers/usb/gadget/gadget_chips.h
./drivers/usb/gadget/f_hid.c
./drivers/staging/msm/lcdc_toshiba_wvga_pt.c
./drivers/staging/msm/mddi_toshiba.c
./drivers/staging/msm/mddi_toshiba_wvga_pt.c
./drivers/staging/msm/mddi_toshiba.h
./drivers/staging/msm/mddi_toshiba_vga.c
./drivers/staging/brcm80211/include/sbchipc.h
./drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c
./drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h
./drivers/staging/brcm80211/brcmfmac/bcmchip.h
./drivers/staging/phison
./drivers/staging/phison/phison.c
./drivers/staging/rts_pstor/rtsx_chip.h
./drivers/staging/rts_pstor/rtsx_chip.c
./drivers/staging/ath6kl/hif
./drivers/staging/ath6kl/hif/common/hif_sdio_common.h
./drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c
./drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c
./drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h
./drivers/staging/ath6kl/include/hif.h
./drivers/pci/hipcie
./drivers/mtd/chips
./drivers/mtd/chips/chipreg.o
./drivers/mtd/chips/chipreg.c
./drivers/mtd/chips/.chipreg.o.cmd
./drivers/mtd/devices/hisfc300new
./drivers/mtd/devices/hisfc300new/hisfc300new_spi_ids.c
./drivers/mtd/devices/hisfc300new/hisfc300new_godcube.c
./drivers/mtd/devices/hisfc300new/hisfc300new_godarm.c
./drivers/mtd/devices/hisfc300new/hisfc300new.h
./drivers/mtd/devices/hisfc300new/hisfc300new_godnet.c
./drivers/mtd/devices/hisfc300new/hisfc300new.c
./drivers/mtd/devices/hisfc300new/hisfc300new_spi_s25fl256s.c
./drivers/mtd/devices/hisfc300new/hisfc300new_spi_general.c
./drivers/mtd/devices/hisfc300new/hisfc300new_spi_n25q256a.c
./drivers/mtd/devices/hisfc350
./drivers/mtd/devices/hisfc350/hisfc350_spi_mx25l25635e.c
./drivers/mtd/devices/hisfc350/hisfc350.h
./drivers/mtd/devices/hisfc350/hisfc350_spi_ids.o
./drivers/mtd/devices/hisfc350/hisfc350.c
./drivers/mtd/devices/hisfc350/hisfc350_spi_w25q256fv.c
./drivers/mtd/devices/hisfc350/hisfc350_hi3520d.c
./drivers/mtd/devices/hisfc350/hisfc350_spi_ids.c
./drivers/mtd/devices/hisfc350/hisfc350_spi_s25fl256s.c
./drivers/mtd/devices/hisfc350/hisfc350_spi_general.c
./drivers/mtd/devices/hisfc350/.hisfc350.o.cmd
./drivers/mtd/devices/hisfc350/.hisfc350_spi_ids.o.cmd
./drivers/mtd/devices/hisfc350/hisfc350_3518.c
./drivers/mtd/devices/hisfc350/hisfc350_phoenix.c
./drivers/mtd/devices/hisfc350/hisfc350_spi_en25q64.c
./drivers/mtd/devices/hisfc350/hisfc350_spi_n25q256a.c
./drivers/mtd/devices/hisfc350/hisfc350.o
./drivers/mtd/devices/hisfc300
./drivers/mtd/devices/hisfc300/hisfc300.c
./drivers/mtd/devices/hisfc300/hisfc300_spi_ids.c
./drivers/mtd/devices/hisfc300/hisfc300_godnet.c
./drivers/mtd/devices/hisfc300/hisfc300_godbox.c
./drivers/mtd/devices/hisfc300/hisfc300.h
./drivers/mtd/devices/hisfc300/hisfc300_godeyes.c
./drivers/mtd/devices/hisfc300/hisfc300_godcube.c
./drivers/mtd/nand/diskonchip.c
./drivers/mtd/nand/hinfc301
./drivers/mtd/nand/hinfc301/hinfc301dbg.c
./drivers/mtd/nand/hinfc301/hinfc301_phoenix.c
./drivers/mtd/nand/hinfc301/hinfc301.c
./drivers/mtd/nand/hinfc301/hinfc301_godbox.c
./drivers/mtd/nand/hinfc301/hinfc301_3518.c
./drivers/mtd/nand/hinfc301/hinfc301.h
./drivers/mtd/nand/hinfc301/hinfc301_godnet.c
./drivers/mtd/nand/hinfc301/hinfc301_godeyes.c
./drivers/mtd/nand/hinfc301/hinfc301_godarm.c
./drivers/mtd/nand/hinfc300
./drivers/mtd/nand/hinfc300/hinfc300dbg.c
./drivers/mtd/nand/hinfc300/hinfc300.h
./drivers/mtd/nand/hinfc300/hinfc300.c
./drivers/s390/cio/qdio_thinint.c
./drivers/platform/x86/toshiba_bluetooth.c
./drivers/platform/x86/toshiba_acpi.c
./drivers/platform/x86/thinkpad_acpi.c
./drivers/i2c/busses/i2c-highlander.c
./drivers/net/via-rhine.c
./drivers/net/wan/wanxlfw.inc_shipped
./drivers/net/wireless/ath/ath9k/hif_usb.c
./drivers/net/wireless/ath/ath9k/hif_usb.h
./drivers/net/wireless/bcm4329/include/sbchipc.h
./drivers/net/wireless/zd1211rw/zd_chip.h
./drivers/net/wireless/zd1211rw/zd_chip.c
./drivers/net/wireless/bcmdhd/include/sbchipc.h
./drivers/net/hamachi.c
./drivers/net/hieth-sf
./drivers/net/hieth-sf/hieth.h
./drivers/net/hieth-sf/hieth.o
./drivers/net/hieth-sf/sys-hi3520d.c
./drivers/net/hieth-sf/.hieth.o.cmd
./drivers/net/higmacv300
./drivers/net/higmacv300/higmacv300_timer.h
./drivers/net/higmacv300/higmacv300_timer.c
./drivers/net/higmacv300/higmacv300_godarm.h
./drivers/net/higmacv300/higmacv300.h
./drivers/net/higmacv300/higmacv300_regmap.h
./drivers/net/higmacv300/higmacv300_ethtool.c
./drivers/net/higmacv300/higmacv300_proc.c
./drivers/net/higmacv300/higmacv300_proc.h
./drivers/net/higmacv300/higmacv300_main.c
./drivers/net/higmacv300/higmacv300_godarm.c
./drivers/net/higmacv300/higmacv300_mdio.c
./drivers/ata/ahci_sys_hi3520d_defconfig.c
./drivers/macintosh/adbhid.c
./drivers/macintosh/mac_hid.c
./drivers/char/toshiba.c
./drivers/ssb/driver_chipcommon_pmu.c
./drivers/ssb/driver_chipcommon.c
./drivers/mmc/host/sh_mobile_sdhi.c
./drivers/mmc/host/himciv100
./drivers/mmc/host/himciv100/.himci.o.cmd
./drivers/mmc/host/himciv100/hi_mci.h
./drivers/mmc/host/himciv100/hi_mci_reg.h
./drivers/mmc/host/himciv100/himci_godnet.c
./drivers/mmc/host/himciv100/himci_godarm.c
./drivers/mmc/host/himciv100/himci.c
./drivers/mmc/host/himciv100/himci_godeyes.c
./drivers/mmc/host/himciv100/himci.o
./drivers/mmc/host/himciv100/himci_phoenix.c
./drivers/mmc/host/himciv100/himci_godbox.c
./drivers/mmc/host/himciv100/himci_3518.c
./drivers/cpufreq/hi3518-cpufreq.c
./drivers/cpufreq/.hi3518-cpufreq.o.cmd
./drivers/cpufreq/hi3518-cpufreq.o
./drivers/cpufreq/Kconfig.hifreq
./drivers/media/dvb/mantis/mantis_hif.c
./drivers/media/dvb/mantis/mantis_hif.h
./drivers/media/video/omap3isp/isphist.h
./drivers/media/video/omap3isp/isphist.c
./drivers/media/video/pwc/philips.txt
./drivers/bcma/driver_chipcommon_pmu.c
./drivers/bcma/driver_chipcommon.c
./drivers/message/fusion/lsi/mpi_history.txt
./drivers/video/via/chip.h
./drivers/video/hitfb.c
./drivers/video/msm/mddi_client_toshiba.c
./drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
./drivers/video/chipsfb.c
./drivers/scsi/pm8001/pm8001_chips.h
./drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped
./drivers/scsi/aic7xxx/aic79xx_reg.h_shipped
./drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped
./drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped
./drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped
./drivers/scsi/aic7xxx/aic79xx_seq.h_shipped
./drivers/scsi/sym53c8xx_2/sym_hipd.h
./drivers/scsi/sym53c8xx_2/sym_hipd.c
./drivers/scsi/53c700_d.h_shipped
./drivers/scsi/mvsas/mv_chips.h
./drivers/infiniband/hw/ehca/hipz_fns_core.h
./drivers/infiniband/hw/ehca/hipz_fns.h
./drivers/infiniband/hw/ehca/hipz_hw.h
./drivers/infiniband/hw/ipath/ipath_init_chip.c
./drivers/isdn/hisax
./drivers/isdn/hisax/hisax.h
./drivers/isdn/hisax/hisax_debug.h
./drivers/isdn/hisax/hisax_isac.h
./drivers/isdn/hisax/hisax_fcpcipnp.c
./drivers/isdn/hisax/hisax_if.h
./drivers/isdn/hisax/hisax_fcpcipnp.h
./drivers/isdn/hisax/hisax_cfg.h
./drivers/isdn/hisax/hisax_isac.c
./drivers/isdn/hisax/saphir.c
./drivers/crypto/hifn_795x.c
./firmware/whiteheat_loader.HEX
./firmware/whiteheat.HEX
./firmware/whiteheat_loader_debug.HEX
./sound/usb/6fire/chip.h
./sound/usb/6fire/chip.c
./sound/pci/ice1712/prodigy_hifi.h
./sound/pci/ice1712/prodigy_hifi.c
./sound/soc/mid-x86/mfld_machine.c
./tools/perf/Documentation/perf-archive.txt
./tools/perf/perf-archive.sh
./tools/perf/util/hist.h
./tools/perf/util/ui/browsers/hists.c
./tools/perf/util/hist.c
./include/linux/hid-debug.h
./include/linux/hidraw.h
./include/linux/usb/g_hid.h
./include/linux/hiddev.h
./include/linux/mtd/flashchip.h
./include/linux/clockchips.h
./include/linux/regulator/machine.h
./include/linux/hid.h
./include/linux/chio.h
./include/linux/hippidevice.h
./include/linux/hil.h
./include/linux/ssb/ssb_driver_chipcommon.h
./include/linux/mmc/sh_mobile_sdhi.h
./include/linux/toshiba.h
./include/linux/hid-roccat.h
./include/linux/if_hippi.h
./include/linux/highmem.h
./include/linux/bcma/bcma_driver_chipcommon.h
./include/linux/hil_mlc.h
./include/linux/unaligned/le_byteshift.h
./include/linux/unaligned/be_byteshift.h
./include/linux/highuid.h
./include/linux/stop_machine.h
./include/media/v4l2-chip-ident.h
./include/config/hiusb
./include/config/log/buf/shift.h
./include/config/hid
./include/config/usb/hid.h
./include/config/himci
./include/config/himciv100.h
./include/config/mtd/hisfc350.h
./include/config/hid.h
./include/config/hisfc350
./include/config/hisfc350/chip
./include/config/hisfc350/enable/chipselect
./include/config/hi3518
./include/config/hieth
./include/config/arm/l1/cache/shift.h
./include/config/mach/hi3518.h
./include/config/arch/hi3518.h
./config_hi3518c
./Documentation/sh/new-machine.txt
./Documentation/hid
./Documentation/hid/hidraw.txt
./Documentation/hid/hiddev.txt
./Documentation/usb/gadget_hid.txt
./Documentation/power/regulator/machine.txt
./Documentation/DocBook/v4l/vidioc-dbg-g-chip-ident.xml
./Documentation/sound/alsa/soc/machine.txt
./Documentation/sound/alsa/Audiophile-Usb.txt
./Documentation/highuid.txt
./Documentation/laptops/thinkpad-acpi.txt
./Documentation/timers/highres.txt
./Documentation/networking/tcp-thin.txt
./Documentation/vm/highmem.txt
./Documentation/x86/x86_64/machinecheck
./Documentation/arm/SA1100/GraphicsClient
./Documentation/arm/SA1100/GraphicsMaster
./Documentation/filesystems/caching
./Documentation/ABI/testing/sysfs-driver-hid-prodikeys
./Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra
./Documentation/ABI/testing/sysfs-driver-hid-picolcd
./Documentation/ABI/testing/sysfs-driver-hid-roccat-kone
./Documentation/ABI/testing/sysfs-driver-hid
./Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus
./Documentation/ABI/testing/sysfs-driver-hid-roccat-arvo
./Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus
./Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus
./Documentation/block/switching-sched.txt
./fs/fscache/histogram.c
./scripts/kconfig/zconf.tab.c_shipped
./scripts/kconfig/zconf.hash.c_shipped
./scripts/kconfig/lex.zconf.c_shipped
./scripts/genksyms/keywords.c_shipped
./scripts/genksyms/parse.h_shipped
./scripts/genksyms/parse.c_shipped
./scripts/genksyms/lex.c_shipped
./scripts/dtc/dtc-parser.tab.h_shipped
./scripts/dtc/dtc-parser.tab.c_shipped
./scripts/dtc/dtc-lexer.lex.c_shipped
./arch/ia64/kernel/machine_kexec.c
./arch/sh/boards/mach-highlander
./arch/sh/kernel/machine_kexec.c
./arch/sh/include/mach-common/mach/highlander.h
./arch/sh/include/asm/sfp-machine.h
./arch/sh/cchips
./arch/sh/lib/ashiftrt.S
./arch/blackfin/kernel/irqchip.c
./arch/blackfin/lib/umulsi3_highpart.S
./arch/blackfin/lib/smulsi3_highpart.S
./arch/s390/kernel/machine_kexec.c
./arch/s390/include/asm/sfp-machine.h
./arch/s390/include/asm/schid.h
./arch/frv/mm/highmem.c
./arch/frv/include/asm/highmem.h
./arch/unicore32/kernel/hibernate.c
./arch/unicore32/kernel/hibernate_asm.S
./arch/avr32/mach-at32ap/include/mach/chip.h
./arch/xtensa/include/asm/highmem.h
./arch/mn10300/include/asm/highmem.h
./arch/x86/mm/highmem_32.c
./arch/x86/kernel/machine_kexec_32.c
./arch/x86/kernel/machine_kexec_64.c
./arch/x86/kernel/cpu/mcheck/winchip.c
./arch/x86/power/hibernate_asm_64.S
./arch/x86/power/hibernate_64.c
./arch/x86/power/hibernate_asm_32.S
./arch/x86/power/hibernate_32.c
./arch/x86/include/asm/visws/lithium.h
./arch/x86/include/asm/highmem.h
./arch/um/sys-ppc/miscthings.c
./arch/alpha/kernel/sys_rawhide.c
./arch/alpha/include/asm/sfp-machine.h
./arch/powerpc/platforms/cell/spufs/spu_save_dump.h_shipped
./arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped
./arch/powerpc/mm/highmem.c
./arch/powerpc/kernel/machine_kexec_32.c
./arch/powerpc/kernel/machine_kexec_64.c
./arch/powerpc/kernel/machine_kexec.c
./arch/powerpc/include/asm/sfp-machine.h
./arch/powerpc/include/asm/code-patching.h
./arch/powerpc/include/asm/highmem.h
./arch/powerpc/lib/code-patching.c
./arch/arm/mach-pxa/himalaya.c
./arch/arm/mm/highmem.c
./arch/arm/mm/cache-hil2v200.c
./arch/arm/mm/cache-hil2v100.c
./arch/arm/mm/cache-hil2v200.h
./arch/arm/mm/cache-hil2v100.h
./arch/arm/kernel/machine_kexec.c
./arch/arm/mach-hi3518
./arch/arm/configs/hi3516c_full_defconfig
./arch/arm/configs/hi3518a_full_defconfig
./arch/arm/configs/hi3518c_full_defconfig
./arch/arm/configs/hi3518a_mini_defconfig
./arch/arm/configs/hi3518c_mini_defconfig
./arch/arm/configs/hi3516c_mini_defconfig
./arch/arm/configs/hi3520d_full_defconfig
./arch/arm/configs/hi3520d_mini_defconfig
./arch/arm/configs/hi3716m_defconfig
./arch/arm/include/asm/highmem.h
./arch/arm/mach-hi3520d
./arch/arm/mach-u300/dummyspichip.c
./arch/arm/mach-msm/board-sapphire.c
./arch/arm/mach-msm/board-mahimahi.c
./arch/arm/mach-bcmring/csp/chipc
./arch/arm/mach-bcmring/csp/chipc/chipcHw_str.c
./arch/arm/mach-bcmring/csp/chipc/chipcHw_reset.c
./arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c
./arch/arm/mach-bcmring/csp/chipc/chipcHw.c
./arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h
./arch/arm/mach-bcmring/include/mach/csp/chipcHw_reg.h
./arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h
./arch/arm/plat-spear/include/plat/shirq.h
./arch/arm/plat-spear/shirq.c
./arch/arm/mach-godbox/hi_pm_sleep.S
./arch/arm/mach-godbox/hipm.c
./arch/tile/mm/highmem.c
./arch/tile/kernel/machine_kexec.c
./arch/tile/include/hv/drv_mshim_intf.h
./arch/tile/include/asm/highmem.h
./arch/tile/include/arch/chip.h
./arch/tile/include/arch/chip_tilepro.h
./arch/tile/include/arch/chip_tilegx.h
./arch/tile/include/arch/chip_tile64.h
./arch/mips/mm/highmem.c
./arch/mips/kernel/mips_machine.c
./arch/mips/kernel/machine_kexec.c
./arch/mips/power/hibernate.S
./arch/mips/include/asm/mips_machine.h
./arch/mips/include/asm/fw/arc/hinv.h
./arch/mips/include/asm/highmem.h
./arch/mips/include/asm/mach-loongson/machine.h
./arch/sparc/mm/highmem.c
./arch/sparc/kernel/pci_schizo.c
./arch/sparc/include/asm/sfp-machine.h
./arch/sparc/include/asm/sfp-machine_32.h
./arch/sparc/include/asm/highmem.h
./arch/sparc/include/asm/machines.h
./arch/sparc/include/asm/sfp-machine_64.h
./arch/m68k/amiga/chipram.c
./arch/m68k/include/asm/machines.h
./samples/hidraw
./samples/hidraw/hid-example.c








1、arch/arm/mach-spear6xx/include/mach/hardware.h :
/* Vitual to physical translation of statically mapped space */
#define IO_ADDRESS(x) (x | 0xF0000000)


2、arch/arm/mach-spear3xx/include/mach/hardware.h :
/* Vitual to physical translation of statically mapped space */
#define IO_ADDRESS(x) (x | 0xF0000000)


3、U8500 mach/hardware.h
/* this macro is used in assembly, so no cast */
#define IO_ADDRESS(x)           \
(((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + U8500_IO_VIRTUAL)


4、mach/io.h
#define IO_ADDRESS(x) ((x) >= GODNET_IOCH1_PHYS ? (x) + IO_OFFSET_HIGH \
: (x) + IO_OFFSET_MID)


5、3520d
#define IO_ADDRESS(x) ((x) >= HI3520D_IOCH1_PHYS ? (x) + IO_OFFSET_HIGH \
: (x) + IO_OFFSET_MID)


6、./arch/arm/mach-hi3518/include/mach/io.h










/*========================================kj timer begin=====================================*/
kj_add_timer()
{
init_timer(&kj_timer1);

kj_timer.expires = jiffies + 100;
kj_timer.data = 1;
kj_timer.function = ledON;

add_timer(&kj_timer);
}


static void ledON(unsigned long data)
{
  int i = 100;
  //  kj add function
  
  
  
  
  kj_timer.data = data_kj+1;
kj_timer.expires = jiffies + i;
kj_timer.function = ledOFF;
add_timer(&kj_timer);
}




static void ledOFF(unsigned long data)
{
  int i = 300;
  //  kj add function
  
  
  
  
  kj_timer.data = data_kj+1;
kj_timer.expires = jiffies + i;
kj_timer.function = ledON;
add_timer(&kj_timer);
}


static void del_timer_kj(struct timer_list * timer)
{
del_timer(timer);
}
/*=========================================kj timer end====================================*/
#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;
}






}












/*========================================joseph hi3518c feed wdg begin========================================*/


#define HISILICON_SCTL_BASE 0x20050000
/* define watchdog IO */
#define JOSEPH_HIWDT_BASE      0x20040000
#define JOSEPH_HIWDT_REG(x)    (JOSEPH_HIWDT_BASE + (x))


#define JOSEPH_HIWDT_LOAD      0x000
#define JOSEPH_HIWDT_VALUE     0x004
#define JOSEPH_HIWDT_CTRL      0x008
#define JOSEPH_HIWDT_INTCLR    0x00C
#define JOSEPH_HIWDT_RIS       0x010
#define JOSEPH_HIWDT_MIS       0x014
#define JOSEPH_HIWDT_LOCK      0xC00


#define JOSEPH_HIWDT_UNLOCK_VAL    0x1ACCE551


/* module param */
#define HIDOG_TIMER_MARGIN    1 //alter by kj
static DEFINE_SPINLOCK(hidog_lock);
static int cur_margin = HIDOG_TIMER_MARGIN;


#ifndef MHZ
#define MHZ (1000*1000)
#endif


static unsigned long rate = 3*MHZ;


static inline void hidog_set_timeout(unsigned int nr)
{
    unsigned long cnt = (~0x0)/rate;        /* max cnt */
    unsigned long flags; 


    spin_lock_irqsave(&hidog_lock, flags); 


    if( nr==0 || nr>cnt)
        cnt=~0x0; 
    else
        cnt = nr*rate;
    /* unlock watchdog registers */ 
    hiwdt_writel(HIWDT_UNLOCK_VAL, HIWDT_LOCK); 
    hiwdt_writel(cnt, HIWDT_LOAD); 
    hiwdt_writel(cnt, HIWDT_VALUE); 
    /* lock watchdog registers */ 
    hiwdt_writel(0, HIWDT_LOCK); 
    spin_unlock_irqrestore(&hidog_lock, flags); 
};


static void joseph_start_wdg_reg(void)
{
    unsigned long flags;
    unsigned long t;
    
    spin_lock_irqsave(&hidog_lock, flags);
    /* unlock watchdog registers */
    hiwdt_writel(HIWDT_UNLOCK_VAL, HIWDT_LOCK);
    hiwdt_writel(0x00, HIWDT_CTRL);
    hiwdt_writel(0x00, HIWDT_INTCLR);
    hiwdt_writel(0x03, HIWDT_CTRL);
    /* lock watchdog registers */
    hiwdt_writel(0, HIWDT_LOCK);
    /* enable watchdog clock --- set the frequency to 3MHz */
    t = readl(reg_ctl_base_va);
    writel(t & ~0x00800000, reg_ctl_base_va);
    spin_unlock_irqrestore(&hidog_lock, flags);
    
}


























/*========================================joseph hi3518c feed wdg end========================================*/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM