在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            自己寫bootloader

            作者: 時(shí)間:2016-11-21 來源:網(wǎng)絡(luò) 收藏
            啟動(dòng)匯編文件
            #define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02))
            #define S3C2440_MPLL_400MHZ ((0x5c<<12)|(0x01<<4)|(0x01))
            #define MEM_CTL_BASE 0x48000000
            .text
            .global _start
            _start:
            // 1、關(guān)看門狗 //
            ldr r0, =0x53000000
            mov r1, #0
            str r1, [r0]
            // 2、設(shè)置系統(tǒng)時(shí)鐘 //
            ldr r0, =0x4c000014
            //mov r1, #0x03 // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
            mov r1, #0x05; // FCLK:HCLK:PCLK=1:4:8
            str r1, [r0]
            // 如果HDIVN非0,CPU的總線模式應(yīng)該從“fast bus mode”變?yōu)?ldquo;asynchronous bus mode” //
            mrc p15, 0, r1, c1, c0, 0 // 讀出控制寄存器 //
            orr r1, r1, #0xc0000000 // 設(shè)置為“asynchronous bus mode” //
            mcr p15, 0, r1, c1, c0, 0 // 寫入控制寄存器 //
            ldr r0, =0x4c000004
            ldr r1, =S3C2440_MPLL_400MHZ
            str r1, [r0]
            // 啟動(dòng)ICACHE //
            mrc p15, 0, r0, c1, c0, 0 @ read control reg
            orr r0, r0, #(1<<12)
            mcr p15, 0, r0, c1, c0, 0 @ write it back
            // 3、初始化SDARM //
            ldr r0, =MEM_CTL_BASE
            adr r1, sdarm_config
            add r3, r0,#(13*4)
            1:
            ldr r2, [r1],#4
            str r2, [r0],#4
            cmp r0, r3
            bne 1b
            // 4. 重定位 : 把bootloader本身的代碼從flash復(fù)制到它的鏈接地址去 //
            ldr sp, =0x34000000 //讓SP指向最高的內(nèi)存,棧是往下增長的
            bl nand_init //即使是nor啟動(dòng)也要初始化nand flash,因?yàn)閮?nèi)核是存在nandflash上面的,還 //要去nandflash上面把內(nèi)核讀出來。
            mov r0, #0
            ldr r1, =_start //鏈接地址在鏈接腳本中注明,即程序運(yùn)行時(shí)應(yīng)該在的地方,0x33f80000
            ldr r2, =__bss_start
            sub r2, r2, r1
            bl copy_code_to_sdram
            bl clear_bss
            // 5、執(zhí)行main函數(shù) //
            ldr lr, =halt
            ldr pc, =main //跳到main函數(shù)中運(yùn)行,不用bl指令是因?yàn)樵撝噶顣絪darm中執(zhí)行
            halt:
            halt
            sdarm_config:
            .long 0x22011110 //BWSCON
            .long 0x00000700 //BANKCON0
            .long 0x00000700 //BANKCON1
            .long 0x00000700 //BANKCON2
            .long 0x00000700 //BANKCON3
            .long 0x00000700 //BANKCON4
            .long 0x00000700 //BANKCON5
            .long 0x00018005 //BANKCON6
            .long 0x00018005 //BANKCON7
            .long 00x008C04F4 //REFRESH
            .long 00x000000B1 //BANKSIZE
            .long 00x00000030 //MRSRB6
            .long 00x00000030 //MRSRB7
            ==============================================================
            nand flash初始化文件:
            // NAND FLASH控制器 //
            #define NFCONF (*((volatile unsigned long *)0x4E000000))
            #define NFCONT (*((volatile unsigned long *)0x4E000004))
            #define NFCMMD (*((volatile unsigned char *)0x4E000008))
            #define NFADDR (*((volatile unsigned char *)0x4E00000C))
            #define NFDATA (*((volatile unsigned char *)0x4E000010))
            #define NFSTAT (*((volatile unsigned char *)0x4E000020))
            void nand_init(void)
            {
            #define TACLS 0
            #define TWRPH0 3
            #define TWRPH1 0
            // 設(shè)置時(shí)序 //
            NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
            // 使能NAND Flash控制器, 初始化ECC, 禁止片選 //
            NFCONT = (1<<4)|(1<<1)|(1<<0);
            }
            void nand_select(void)
            {
            NFCONT &= ~(1<<1);
            }
            void del_select(void)
            {
            NFCONT |= (1<<1);
            }
            void nand_cmd(unsigned char cmd)
            {
            volatile int i=0;
            NFCMMD = cmd;
            for(i=0; i<10; i++);
            }
            void nand_wait_ready(void)
            {
            while (!(NFSTAT & 1));
            }
            unsigned char nand_data(void)
            {
            return NFDATA;
            }
            void nand_addr(unsigned int addr)
            {
            unsigned int col = addr % 2048;
            unsigned int page = addr / 2048;
            unsigned int i=0;
            NFADDR = col & 0xff;
            for(i=0; i<10; i++);
            NFADDR = (col>>8) & 0xff;
            for(i=0; i<10; i++);
            NFADDR = page & 0xff;
            for(i=0; i<10; i++);
            NFADDR = (page>>8) & 0xff;
            for(i=0; i<10; i++);
            NFADDR = (page>>16) & 0xff;
            for(i=0; i<10; i++);
            }
            //addr--->0,下面的nand_read函數(shù)從nand flash的0地址讀數(shù)據(jù)放在buf地方
            //buf---->_start 即鏈接地址在鏈接腳本中注明,程序運(yùn)行時(shí)應(yīng)該在的地方,0x33f80000,把程序拷貝過去
            //len----->__bss_start-_start
            void nand_read(unsigned int addr, unsigned char *buf, unsigned int len)
            {
            int col = addr 48;
            int i = 0;
            // 選中片選 //
            nand_select();
            while(i
            {
            // 發(fā)讀命令 //
            nand_cmd(0x00);
            // 發(fā)地址 //
            nand_addr(addr);
            // 發(fā)讀命令 //
            nand_cmd(0x30);
            // 判斷狀態(tài) //
            nand_wait_ready();
            // 讀數(shù)據(jù) //
            for(; (col<2048) && (i
            {
            buf[i] = nand_data();
            i++;
            addr++;
            }
            col = 0;
            }
            // 取消片選 //
            del_select();
            }
            //
            為什么該函數(shù)能夠判斷成功,因?yàn)槌绦蜻\(yùn)行到此時(shí)如果是nand啟動(dòng),則上電后nand flash的前4K會被復(fù)制到片內(nèi)SARM中運(yùn)行,往地址0寫入數(shù)據(jù)相當(dāng)于往片內(nèi)內(nèi)存0地址寫數(shù)據(jù)可以成功;但是如果是nor啟動(dòng),上電后直接在nor的0地址運(yùn)行,程序依然在nor flash中,nor flash可以像內(nèi)存一樣讀,但是無法像內(nèi)存一樣寫,故直接向0地址賦值會失敗。
            //
            int isBootFromNorFlash(void)
            {
            volatile int *p =(volatile int *)0;
            int val=0;
            val = *p;
            *p = 0x1234ab;
            if(*p == 0x1234ab)
            {
            //寫成功,表示是nand flash啟動(dòng)
            *p=val;
            return 0;
            }
            else
            {
            //寫失敗,說明是nor flash啟動(dòng)
            return 1;
            }
            }
            void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
            {
            unsigned int i=0;
            if(isBootFromNorFlash())//nor啟動(dòng)
            {
            while(i
            {
            dest[i] = src[i];
            i++;
            }
            }
            else //nand啟動(dòng)
            {
            nand_read(src,dest,len);
            }
            }
            void clear_bss(void)
            {
            extern int __bss_start, __bss_end;
            int *p = &__bss_start;
            for(; p < &__bss_end; p++)
            *p = 0;
            }
            #define PCLK 50000000 // init.c中的clock_init函數(shù)設(shè)置PCLK為50MHz
            #define UART_CLK PCLK // UART0的時(shí)鐘源設(shè)為PCLK
            #define UART_BAUD_RATE 115200 // 波特率
            #define UART_BRD ((UART_CLK / (UART_BAUD_RATE * 16)) - 1)
            //
            * 初始化UART0
            * 115200,8N1,無流控
            //
            void uart0_init(void)
            {
            GPHCON |= 0xa0; // GPH2,GPH3用作TXD0,RXD0
            GPHUP = 0x0c; // GPH2,GPH3內(nèi)部上拉
            ULCON0 = 0x03; // 8N1(8個(gè)數(shù)據(jù)位,無較驗(yàn),1個(gè)停止位)
            UCON0 = 0x05; // 查詢方式,UART時(shí)鐘源為PCLK
            UFCON0 = 0x00; // 不使用FIFO
            UMCON0 = 0x00; // 不使用流控
            UBRDIV0 = UART_BRD; // 波特率為115200
            }
            //
            * 發(fā)送一個(gè)字符
            //
            void putc(unsigned char c)
            {
            // 等待,直到發(fā)送緩沖區(qū)中的數(shù)據(jù)已經(jīng)全部發(fā)送出去 //
            while (!(UTRSTAT0 & TXD0READY));
            // 向UTXH0寄存器中寫入數(shù)據(jù),UART即自動(dòng)將它發(fā)送出去 //
            UTXH0 = c;
            }
            void puts(char *str)
            {
            int i = 0;
            while (str[i])
            {
            putc(str[i]);
            i++;
            }
            }
            void puthex(unsigned int val)
            {
            // 0x1234abcd //
            int i;
            int j;
            puts("0x");
            for (i = 0; i < 8; i++)
            {
            j = (val >> ((7-i)*4)) & 0xf;
            if ((j >= 0) && (j <= 9))
            putc(0 + j);
            else
            putc(A + j - 0xa);
            }
            }
            =================================================================
            boot.c
            #include "setup.h"
            extern void uart0_init(void);
            extern void nand_read(unsigned int addr, unsigned char *buf, unsigned int len);
            extern void puts(char *str);
            extern void puthex(unsigned int val);
            static struct tag *params;
            void setup_start_tag(void)
            {
            params = (struct tag *)0x30000100;
            params->hdr.tag = ATAG_CORE;
            params->hdr.size = tag_size (tag_core);
            params->u.core.flags = 0;
            params->u.core.pagesize = 0;
            params->u.core.rootdev = 0;
            params = tag_next (params);
            }
            void setup_memory_tags(void)
            {
            params->hdr.tag = ATAG_MEM;
            params->hdr.size = tag_size (tag_mem32);
            params->u.mem.start = 0x30000000;
            params->u.mem.size = 64*1024*1024;
            params = tag_next (params);
            }
            int strlen(char *str)
            {
            int i = 0;
            while (str[i])
            {
            i++;
            }
            return i;
            }
            void strcpy(char *dest, char *src)
            {
            while ((*dest++ = *src++) !=