主题 : 新人发个bootloader,不足4k,功能简单,求高手优化。。。 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 30304
精华: 1
发帖: 28
金钱: 190 两
威望: 38 点
贡献值: 1 点
综合积分: 76 分
注册时间: 2010-10-14
最后登录: 2019-08-02
楼主  发表于: 2011-03-16 09:35

 新人发个bootloader,不足4k,功能简单,求高手优化。。。

最近学习uboot,然后自己动手移植2010.09版的始终不成功。。。
最后参考启动流程自己写了个,启动了开发板。。功能就初始化硬件,然后加载内核到内存指定位置。

.text
.global _start
#  define pWTCON    0x53000000
#  define INTMOD         0X4A000004
#  define INTMSK    0x4A000008    /* Interupt-Controller base addresses */
#  define INTSUBMSK    0x4A00001C


#define TEXT_BASE    0x33F80000


_start:
    //关闭看门狗和各自中断
    ldr    r0, =pWTCON
    mov    r1, #0x0
    str    r1, [r0]

    /*
     * mask all IRQs by setting all bits in the INTMR - default
     */
    mov    r1, #0xffffffff
    ldr    r0, =INTMSK
    str    r1, [r0]

    ldr    r1, =0x3ff
    ldr    r0, =INTSUBMSK
    str    r1, [r0]
    
//重新配置clock   Fin=12Mhz
/*S3C2440: Mpll = (2*m * Fin) / (p * 2^s),
           UPLL = (m * Fin) / (p * 2^s)
   m = M (the value for divider M)+ 8,
   p = P (the value for divider P) + 2
*/
/*clock register*/
#define CLK_CTL_BASE        0x4C000000
#define CLKDIVN            0x4C000014    /* clock divisor register */
#define S3C2440_CLKDIV          0x05
//#define S3C2440_MPLL_400MHZ     ((0x5c<<12)|(0x01<<4)|(0x01))
#define MDIV_400        0x5c<<12
#define PDIV_400        0x01<<4
#define SDIV_400        0x01
//#define S3C2440_UPLL_48MHZ      ((0x38<<12)|(0x02<<4)|(0x02))
#define MDIV_48            0x38<<12
#define PDIV_48            0x02<<4
#define SDIV_48            0x02
  

    /*初始化clock分频比例*/
/* FCLK:HCLK:PCLK = 1:4:8, UCLK = UPLL/2 */
    ldr    r0, =CLKDIVN
    mov    r1, #S3C2440_CLKDIV
    str    r1, [r0]
    
    /* change to asynchronous bus mod 见手册说明*/
    mrc    p15, 0, r1, c1, c0, 0    /* read ctrl register   */  
        orr    r1, r1, #0xc0000000      /* Asynchronous         */  
        mcr    p15, 0, r1, c1, c0, 0    /* write ctrl register  */    
    
    mov r1,#CLK_CTL_BASE
    mov r2,#MDIV_48
    add r2,r2,#PDIV_48
    add r2,r2,#SDIV_48
    str r2,[r1,#0x08]
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    mov r2,#MDIV_400
    add r2,r2,#PDIV_400
    add r2,r2,#SDIV_400
    str r2,[r1,#0x04]

//关闭MMU,CACHE
/*
     * 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

//mem control config
    bl ramctrl_config

//stack setup
    ldr sp, =TEXT_BASE
    sub sp,sp,#332*1024
#define GPACON        0x56000000
#define GPADAT        0x56000004
#define GPAUP            0x56000008
#define GPBCON        0x56000010
#define GPBDAT        0x56000014
#define GPBUP            0x56000018
#define GPCCON        0x56000020
#define GPCDAT        0x56000024
#define GPCUP            0x56000028
#define GPDCON        0x56000030
#define GPDDAT        0x56000034
#define GPDUP            0x56000038
#define GPECON        0x56000040
#define GPEDAT        0x56000044
#define GPEUP            0x56000048
#define GPFCON        0x56000050
#define GPFDAT        0x56000054
#define GPFUP            0x56000058
#define GPGCON        0x56000060
#define GPGDAT        0x56000064
#define GPGUP            0x56000068
#define GPHCON        0x56000070
#define GPHDAT        0x56000074
#define GPHUP            0x56000078
#define GPJCON        0x560000d0
#define GPJDAT        0x560000d4
#define GPJUP            0x560000d8
#define GPB5_out    1<<10
#define GPB6_out    1<<12
#define GPB7_out    1<<14
#define GPB8_out    1<<16

#define CODE_ADDR    0x00240000
#define linux_addr    0x30008000
#define CODE_SIZE    0x00200000


//copy code    
    
    //turn on all led
    ldr r0,=GPBCON
    ldr r1,=(GPB5_out|GPB6_out|GPB7_out|GPB8_out)
    str r1,[r0]
    ldr r0,=GPBDAT
    ldr r1,=(~(0xf<<5))
    str r1,[r0]

    ldr r0,=CODE_ADDR
    ldr r1,=linux_addr
    ldr r2,=CODE_SIZE

    bl copycode2ram
    cmp r0,#0x0
    beq call_linux
halt:
    b halt
halt2:
#if 0
//failed to setup boot params ,  turn off all led
    ldr r0,=GPBCON
    ldr r1,=(GPB5_out|GPB6_out|GPB7_out|GPB8_out)
    str r1,[r0]
    ldr r0,=GPBDAT
    ldr r1,=(~(0x0<<6))
    str r1,[r0]
#endif
    b halt2
#define MACH_TYPE 168            /*r1*/
#define PARAMS_ADDR  0x30000100   /*r2*/

call_linux:
    

gpio_setup:
    ldr r0,=GPACON
    ldr r1,=0x007FFFFF
    str r1,[r0]

    ldr r0,=GPBCON
    ldr r1,=0x00055554
    str r1,[r0]
    ldr r0,=GPBUP
    ldr r1,=0x000007FF
    str r1,[r0]

    ldr r0,=GPCCON
    ldr r1,=0xAAAAAAAA
    str r1,[r0]
    ldr r0,=GPCUP
    ldr r1,=0x0000FFFF
    str r1,[r0]

    ldr r0,=GPDCON
    ldr r1,=0xAAAAAAAA
    str r1,[r0]
    ldr r0,=GPDUP
    ldr r1,=0x0000FFFF
    str r1,[r0]

    ldr r0,=GPECON
    ldr r1,=0xAAAAAAAA
    str r1,[r0]
    ldr r0,=GPEUP
    ldr r1,=0x0000FFFF
    str r1,[r0]

    ldr r0,=GPFCON
    ldr r1,=0x000055AA
    str r1,[r0]
    ldr r0,=GPFUP
    ldr r1,=0x000000FF
    str r1,[r0]

    ldr r0,=GPGCON
    ldr r1,=0xFF94FFBA
    str r1,[r0]
    ldr r0,=GPGUP
    ldr r1,=0x0000FFFF
    ldr r1,[r0]

    ldr r0,=GPHCON
    ldr r1,=0x002AFAAA
    str r1,[r0]
    ldr r0,=GPHUP
    ldr r1,=0x000007FF
    str r1,[r0]

    ldr r0,=GPJCON
    ldr r1,=0x02aaaaaa
    str r1,[r0]
    ldr r0,=GPJUP
    ldr r1,=0x00001fff
    str r1,[r0]
//lcd poweren
#define LCDCON1    0x4d000000
#define LCDCON5    0x4d000010    
    ldr r0,=GPGDAT
    ldr r1,[r0]
    orr r1,r1,#1<<4
    str r1,[r0]
    

    ldr r0,=LCDCON5
    ldr r1,[r0]
    orr r1,r1,#1<<3  //poweren
    and r1,r1,#~(1<<5) //invpoweren
    str r1,[r0]

//初始化串口
    bl init_serial
//初始化标记列表
    //ldr r0,=PARAMS_ADDR
    bl setup_tags

    //b halt2  /*failed to setup boot params*/

    // turn on led 5 8
    ldr r0,=GPBCON
    ldr r1,=(GPB5_out|GPB8_out)
    str r1,[r0]
    ldr r0,=GPBDAT
    ldr r1,=(~(0x9<<5))
    str r1,[r0]

    //envid 现在打开LCD
    ldr r0,=LCDCON1
    ldr r1,[r0]
    orr r1,r1,#0x1
    str r1,[r0]
//设置启动参数
    ldr r0,=0x0
    ldr r1,=MACH_TYPE
    ldr r2,=PARAMS_ADDR
//everything is fine
    ldr pc,=linux_addr


//serial setup
#define      UART_BASE    0x50000000
#define         ULCON0    0x50000000
//#define         ULCON1    0x50004000
//#define         ULCON2    0x50008000
    
#define         UCON0    0x50000004
//#define         UCON1    0x50004004
//#define         UCON2    0x50008004

#define         UFCON0    0x50000008
//#define         UFON1    0x50004008
//#define         UFON2    0x50008008

#define         UMCON0    0x5000000c
//#define         UMON1    0x5000400c

#define      UTRSTAT0   0x50000010
#define      UERSTAT0    0x50000014
#define      UFSTAT0    0x50000018
#define      UMSTAT0    0x5000001c
#define      UTXH0    0x50000020    
#define      UBRDIV0    0x50000028

#define PCLK        50000000
#define UART_CLK    PCLK
#define UART_BAUD_RATE    115200
#define UART_BRD    ((UART_CLK/(UART_BAUD_RATE*16))-1)
init_serial:
    ldr r0,=ULCON0
    ldr r1,=0x3
    str r1,[r0]
    ldr r0,=UCON0
    ldr r1,=0x245
    str r1,[r0]
    ldr r0,=UFCON0
    ldr r1,=0x07
    str r1,[r0]
    ldr r0,=UMCON0
    ldr r1,=0x0
    str r1,[r0]
    ldr r0,=UBRDIV0
    ldr r1,=UART_BRD
    str r1,[r0]
    

put_hello:

wait_tx_fifo:
    ldr r0,=UTRSTAT0
    ldr r1,[r0]
    and r1,r1,#0x2
    cmp r1,#0x2
    bne wait_tx_fifo
wait_cts:
    ldr r0,=UMSTAT0
    ldr r1,[r0]
    and r1,r1,#0x1
    cmp r1,#0x1
    bne wait_cts
    
    ldr r0,=UTXH0
    ldr r1,='H'
    str r1,[r0]
    //ldr r0,=UTXH0
    ldr r1,='e'
    str r1,[r0]
    //ldr r0,=UTXH0
    ldr r1,='l'
    str r1,[r0]
    //ldr r0,=UTXH0
    ldr r1,='l'
    str r1,[r0]
    //ldr r0,=UTXH0
    ldr r1,='o'
    str r1,[r0]
    ldr r1,='\n'
    str r1,[r0]
    mov pc,lr



setup_tags:
    ldr r0,=PARAMS_ADDR
    ldr r1,=TAG_PARAMS
    add r2,r1,#28*4
copy_tagsval:
    ldr r3,[r1],#4
    str r3,[r0],#4
    cmp r1,r2
    bne copy_tagsval
    
    mov pc,lr

/*内存初始化*/
#define BWSCON    0x48000000

/* BWSCON */
#define DW8             (0x0)
#define DW16             (0x1)
#define DW32             (0x2)
#define WAIT             (0x1<<2)
#define UBLB             (0x1<<3)

#define B1_BWSCON          (DW16)
#define B2_BWSCON          (DW16)
#define B3_BWSCON          (DW16 + WAIT + UBLB)
#define B4_BWSCON          (DW16)
#define B5_BWSCON          (DW8)
#define B6_BWSCON          (DW32)
#define B7_BWSCON          (DW32)

/* BANK0CON */
#define B0_Tacs             0x0    /*  0clk */
#define B0_Tcos             0x0    /*  0clk */
#define B0_Tacc             0x7    /* 14clk */
#define B0_Tcoh             0x0    /*  0clk */
#define B0_Tah             0x0    /*  0clk */
#define B0_Tacp             0x0
#define B0_PMC             0x0    /* normal */

/* BANK1CON */
#define B1_Tacs             0x0    /*  0clk */
#define B1_Tcos             0x0    /*  0clk */
#define B1_Tacc             0x7    /* 14clk */
#define B1_Tcoh             0x0    /*  0clk */
#define B1_Tah             0x0    /*  0clk */
#define B1_Tacp             0x0
#define B1_PMC             0x0

#define B2_Tacs             0x0
#define B2_Tcos             0x0
#define B2_Tacc             0x7
#define B2_Tcoh             0x0
#define B2_Tah             0x0
#define B2_Tacp             0x0
#define B2_PMC             0x0

#define B3_Tacs             0x0    /*  0clk */
#define B3_Tcos             0x3    /*  4clk */
#define B3_Tacc             0x7    /* 14clk */
#define B3_Tcoh             0x1    /*  1clk */
#define B3_Tah             0x0    /*  0clk */
#define B3_Tacp             0x3     /*  6clk */
#define B3_PMC             0x0    /* normal */

#define B4_Tacs             0x0    /*  0clk */
#define B4_Tcos             0x0    /*  0clk */
#define B4_Tacc             0x7    /* 14clk */
#define B4_Tcoh             0x0    /*  0clk */
#define B4_Tah             0x0    /*  0clk */
#define B4_Tacp             0x0
#define B4_PMC             0x0    /* normal */

#define B5_Tacs             0x0    /*  0clk */
#define B5_Tcos             0x0    /*  0clk */
#define B5_Tacc             0x7    /* 14clk */
#define B5_Tcoh             0x0    /*  0clk */
#define B5_Tah             0x0    /*  0clk */
#define B5_Tacp             0x0
#define B5_PMC             0x0    /* normal */

#define B6_MT             0x3    /* SDRAM */
/*#define B6_Trcd              0x1    *//* 3clk */
/*#define B6_SCAN        0x1    *//* 9bit */
/*#define B6_Trcd              0x0    *//* 2clk */
/*#define B6_SCAN        0x2    *//* 10bit */
#define B6_Trcd            0x1
#define B6_SCAN            0x1

#define B7_MT             0x3    /* SDRAM */
/*#define B7_Trcd             0x1    *//* 3clk */
/*#define B7_SCAN        0x1    *//* 9bit */
/*#define B7_Trcd              0x0    *//* 2clk */
/*#define B7_SCAN        0x2    *//* 10bit */
#define B7_Trcd            0x1
#define B7_SCAN            0x1

/* REFRESH parameter */
#define REFEN             0x1    /* Refresh enable */
#define TREFMD             0x0    /* CBR(CAS before RAS)/Auto refresh */
/*#define Trp             0x0    *//* 2clk */
/*#define Trc                0x3    *//* 7clk */
/*#define Tchr             0x2    *//* 3clk */
/*#define REFCNT             0x4f4    *//* period=7.8125us, HCLK=100Mhz, (2048+1-7.8125*100) */
#define Trp             0x0
#define Trc                0x3
#define Tchr             0x2
#define REFCNT             0x4f4
/**************************************/

ramctrl_config:
    /* memory control configuration */
    /* make r0 relative the current location so that it */
    /* reads SMRDATA out of FLASH rather than memory ! */
    ldr     r0, =SMRDATA
    ldr    r1, =BWSCON    /* Bus Width Status Controller */
    add     r2, r0, #13*4
0:
    ldr     r3, [r0], #4
    str     r3, [r1], #4
    cmp     r2, r0
    bne     0b

    /* everything is fine now */
    mov    pc, lr

    .ltorg
/* the literal pools origin */

SMRDATA:
    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
    .word 0x32
    .word 0x30
    .word 0x30

#define ATAG_NONE    0x00000000
#define ATAG_CORE    0x54410001
#define ATAG_MEM    0x54410002
#define ATAG_CMDLINE    0x54410009
#define SIZEOF_CORE    5
#define SIZEOF_MEM    4
#define SIZEOF_CMDLINE    17
#define SIZEOF_NONE    0
TAG_PARAMS:
    .word    SIZEOF_CORE
    .word    ATAG_CORE
    .word    0
    .word    0
    .word    0
    
    .word    SIZEOF_MEM
    .word    ATAG_MEM
    .word    0x04000000
    .word    0x30000000

    .word    SIZEOF_CMDLINE
    .word    ATAG_CMDLINE
//cmdline="noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0"
    .word    0x6e696f6e
    .word    0x64727469
    .word    0x6f6f7220
    .word    0x642f3d74
    .word    0x6d2f7665
    .word    0x6c626474
    .word    0x326b636f
    .word    0x696e6920
    .word    0x6c2f3d74
    .word    0x78756e69
    .word    0x63206372
    .word    0x6f736e6f
    .word    0x743d656c
    .word    0x41537974
    .word    0x20203043
#if 0
    .word    SIZEOF_CMDLINE
    .word    ATAG_CMDLINE
    .word    'n''o''i''n'
    .word    'i''t''r''d'
    .word    ' ''r''o''o'
    .word    't''=''/''d'
    .word    'e''v''/''m'
    .word    't''d''b''l'
    .word    'o''c''k''2'
    .word    ' ''i''n''i'
    .word    't''=''/''l'
    .word    'i''n''u''x'
    .word    'r''c'' ''c'
    .word    'o''n''s''o'
    .word    'l''e''=''t'
    .word    't''y''S''A'
    .word    'C''0'' '' '
#endif
    .word    SIZEOF_NONE
    .word    ATAG_NONE
能自学入门Linux的人将可练就一种坚韧不拔的精神。。。
级别: 侠客
UID: 57277
精华: 0
发帖: 53
金钱: 270 两
威望: 54 点
贡献值: 0 点
综合积分: 106 分
注册时间: 2011-10-21
最后登录: 2012-01-08
1楼  发表于: 2011-12-21 22:08
膜拜一下高手。。。。
级别: 新手上路
UID: 73892
精华: 0
发帖: 11
金钱: 55 两
威望: 11 点
贡献值: 0 点
综合积分: 22 分
注册时间: 2012-07-16
最后登录: 2012-08-23
2楼  发表于: 2012-08-03 15:38
你敢不敢分几个文件,一团糟
级别: 新手上路
UID: 54775
精华: 0
发帖: 32
金钱: 170 两
威望: 34 点
贡献值: 0 点
综合积分: 64 分
注册时间: 2011-09-05
最后登录: 2013-10-08
3楼  发表于: 2012-11-01 16:51
高手是不会这样发代码的