久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

bootloader功能介紹/時鐘初始化設(shè)置/串口工作原理/內(nèi)存工作原理/NandFlash工作原理

 薛董_艾瑞 2018-03-13

bootloader功能介紹

初始化開發(fā)板上主要硬件(時鐘,,內(nèi)存,,硬盤),,
把操作系統(tǒng)從硬盤拷貝到內(nèi)存,,然后讓cpu跳轉(zhuǎn)到內(nèi)存中執(zhí)行操作系統(tǒng)。

boot階段
1.關(guān)閉影響CPU正常執(zhí)行的外設(shè)
-關(guān)閉看門狗(watch dog)   WTCON 0xE2700000
-關(guān)閉中斷 CPSR I和F位設(shè)置為1,,關(guān)閉,,不響應(yīng)任何中斷。
2.初始化時鐘
-倍頻到1Ghz,,為外設(shè)分頻
*串口驅(qū)動

3.初始化內(nèi)存控制器,,DDRAM
-驗證內(nèi)存,往里面寫一個值,,然后再讀出來
4.初始化硬盤,,nand Flash
-nand flash 讀驅(qū)動(從nand往外讀數(shù)據(jù))

loader階段
1.從硬盤指定的地址加載kernel到內(nèi)存指定的地址。
2.跳轉(zhuǎn)到內(nèi)存kernel所在的地址,,執(zhí)行

附加功能:
實現(xiàn)bootloader中shell(命令解釋器)

附加功能:
實現(xiàn)bootloader中shell(命令解釋器)

uboot中支持的命令,, 
help
loadb 下載程序, kermit 協(xié)議
go 0X21000000;

例如:在uboot中直接控制蜂鳴器
mm 0xe02000a0 0x1(控制寄存器)
mm 0xe02000a4 0x1(數(shù)據(jù)寄存器)

常用調(diào)試手段:
1.led點燈大法
2.串口調(diào)試,,uart_getchar,uart_putchar,進一步實現(xiàn)stdio.h

時鐘初始化設(shè)置

pll 鎖相環(huán),, 倍頻


串口工作原理


串口工作核心圖



#define ULCON0 *((volatile unsigned int *)0XE2900000)
volatile 關(guān)鍵字,防止編譯器做優(yōu)化,,每次讀取寄存器的值,,都是重新讀取寄存器,。
  1. //start.s  
  2.     AREA start_main,CODE, READONLY  
  3.     ENTRY  
  4.     IMPORT uart_test  
  5. START  
  6.     B uart_test  
  7.       
  8.     END  
  9. //uart.c  
  10. #define ULCON0 *((volatile unsigned int *)0XE2900000)  
  11. #define UCON0 *((volatile unsigned int *)0XE2900004)  
  12. #define UTRSTAT0 *((volatile unsigned int *)0XE2900010)  
  13. #define UTXH0 *((volatile unsigned int *)0XE2900020)  
  14. #define URXH0 *((volatile unsigned int *)0XE2900024)  
  15. #define UBRDIV0 *((volatile unsigned int *)0XE2900028)  
  16. #define UDIVSLOT0 *((volatile unsigned int *)0XE290002C)  
  17. #define GPACON0 *((volatile unsigned int *)0XE0200000)  
  18. void uart_init(void)  
  19. {  
  20.     //串口管腳設(shè)置成功能態(tài)  
  21.     GPACON0 = 0x22;  
  22.     //設(shè)置8  N  1  
  23.     ULCON0 = 0X3;  
  24.     //設(shè)置輪詢工作模式  
  25.     UCON0 = 0X5;  
  26.     //設(shè)置波特率  
  27.     UBRDIV0 = 34;  
  28.     UDIVSLOT0 = 0XDDDD;  
  29.       
  30. }  
  31. char uart_getchar(void)  
  32. {  
  33.     char ch;  
  34.     //如果有數(shù)據(jù)到達,狀態(tài)寄存器第0位置1  
  35.     //判斷狀態(tài)位是否為1,,決定讀接收緩沖寄存器,,讀到的值作為函數(shù)的返回值  
  36.     while (!(UTRSTAT0 & 0x1))  
  37.         ;  
  38.     ch = URXH0;  
  39.     return ch;  
  40. }  
  41. void uart_putchar(char ch)  
  42. {  
  43.     //如果狀態(tài)寄存器第1為置1,表示發(fā)送單元為空,,可以發(fā)送數(shù)據(jù)  
  44.     //把ch賦值到發(fā)送緩沖寄存器里,,狀態(tài)寄存器第1為置0, 自動發(fā)送,,當(dāng)發(fā)送完畢  
  45.     while (!(UTRSTAT0 & 0X2))  
  46.         ;  
  47.     UTXH0 = ch;  
  48. }  
  49. void uart_test(void)  
  50. {  
  51.     char ch;  
  52.       
  53.     uart_init();  
  54.     uart_putchar('a');  
  55.     uart_putchar('b');  
  56.     uart_putchar('c');  
  57.     //串口回顯功能  
  58.     while (1)  
  59.     {  
  60.         ch = uart_getchar();  
  61.         uart_putchar(ch);  
  62.     }  
  63. }  

內(nèi)存工作原理


--------------------------------------------------



NandFlash工作原理

內(nèi)存是總線設(shè)備,,nandflash屬于非總線設(shè)備。

沒有地址線,, 只有數(shù)據(jù)線,。
內(nèi)存:總線數(shù)據(jù), nandflash:非總線設(shè)備,。
命令,、地址、數(shù)據(jù)復(fù)用端口,。
忙閑位,。


裸板操作NandFlash的示例代碼:

  1. #define NFCONF (*(volatile unsigned int *)0xB0E00000)  
  2. #define NFCONT (*(volatile unsigned int *)0xB0E00004)  
  3. #define NFCMMD (*(volatile unsigned int *)0xB0E00008)  
  4. #define NFADDR (*(volatile unsigned int *)0xB0E0000C)  
  5. #define NFDATA (*(volatile unsigned int *)0xB0E00010)  
  6. #define NFSTAT (*(volatile unsigned int *)0xB0E00028)  
  7.   
  8. #define MP0_3CON (*(volatile unsigned int *)0xE0200320)  
  9.   
  10. #define PAGE_SIZE   2048  
  11.   
  12. void nand_init(void)  
  13. {  
  14.     //[15:12]TACLS = 1->(1) 1/133Mhz = 7.5ns  
  15.     //[11:8] TWRPH0 = 1->(1+7) 7.5ns*2 = 15ns  
  16.     //[7:4] TWRPH1 = 1->(1+1) 7.5ms *2 = 15ns  
  17.     NFCONF |= 1<<2 | 1<< 8 | 1<< 4;  
  18.     //AdrCycle [1]1=5 address cycle  
  19.     NFCONF |= 1<<1;  
  20.     //MODE [0] NAND Flash controller operating node  
  21.     // 0=disable nand flash controller  
  22.     // *1 = enable nand flash controller  
  23.     NFCONT |= 1<<0;  
  24.     //Reg_nCE0 [1] nandflash memort nRCS[0] signal control   
  25.     // *0 = force nRCS[0] to low (enable chip select)  
  26.     // 1 = force nRCS[0] to high(disable chip select)  
  27.     NFCONT &= ~(1<<1);  
  28.     //GPIO functional mux setting   
  29.     // 0010 = NF_xxx  
  30.     MP0_3CON = 0X22222222;  
  31.     return ;      
  32. }  
  33.   
  34. void nand_read_id(char id[])  
  35. {  
  36.     int i;  
  37.     //write read_id cmd 90th  
  38.     NFCMMD = 0X90;  
  39.     //write address 00h  
  40.     NFADDR = 0x00;  
  41.     for(i=0; i<5; i++)  
  42.     {  
  43.         id[i] = NFDATA;  
  44.     }  
  45.     return ;  
  46. }  
  47.   
  48. void nand_read_page(int addr, char buf[])  
  49. {  
  50.     int i;  
  51.     char tmp;  
  52.     //write read_page cmd 00h  
  53.     NFCMMD = 0X00;  
  54.     //write 5 address  
  55.     NFADDR = (addr >> 0) & 0xFF;  
  56.     NFADDR = (addr >> 8) & 0x7;  
  57.     NFADDR = (addr >> 11) & 0xFF;  
  58.     NFADDR = (addr >> 19) & 0xFF;  
  59.     NFADDR = (addr >> 27) & 0x1;  
  60.     //write read_page cmd 30h  
  61.     NFCMMD = 0X30;  
  62.     //wait for R/nB -->ready  
  63.     while( (NFSTAT &(1<<0))==0 )  
  64.         ;  
  65.     //read data 2048 bytes  
  66.     for(i=0; i<PAGE_SIZE; i++)  
  67.     {  
  68.         buf[i] = NFDATA;  
  69.     }  
  70.     for (i=0; i<64; i++)  
  71.     {  
  72.         tmp = NFDATA;  
  73.     }  
  74.     return ;  
  75.       
  76. }  
  77.   
  78. void nand_read(int nand_addr, char *sdram_addr, int size)  
  79. {  
  80.     int pages = (size -1)/PAGE_SIZE + 1;  
  81.     int i;  
  82.       
  83.     for (i=0; i<pages; i++)  
  84.     {  
  85.         nand_read_page(nand_addr + i*PAGE_SIZE, sdram_addr + i*PAGE_SIZE);        
  86.     }  
  87.       
  88. }  
uboot中操作NandFlash的示例代碼:

//s3c2440_nand.c

  1. #include <common.h>  
  2.   
  3. #if 0  
  4. #define DEBUGN printf  
  5. #else  
  6. #define DEBUGN(x,args ...){}  
  7. #endif  
  8. #include <nand.h>  
  9. #include <asm/arch/s3c24x0_cpu.h>  
  10. #include <asm/arch/s3c2410.h>  
  11. #include <asm/io.h>  
  12.   
  13. #define __REGb(x) (*(volatile unsigned char *)(x))  
  14. #define __REGi(x)  (*(volatile unsigned int *)(x))  
  15.   
  16.   
  17. #define NF_BASE         0x4e000000  
  18.   
  19. #define NFCONF           __REGi(NF_BASE + 0x0)  
  20. #define NFCONT           __REGi(NF_BASE + 0x4)  
  21. #define NFCMD            __REGb(NF_BASE + 0x8)  
  22. #define NFADDR           __REGb(NF_BASE + 0xc)  
  23. #define NFDATA           __REGb(NF_BASE + 0x10)  
  24. #define NFMECCD0         __REGi(NF_BASE + 0x14)  
  25. #define NFMECCD1         __REGi(NF_BASE + 0x18)  
  26. #define NFSECCD          __REGi(NF_BASE + 0x1C)  
  27. #define NFSTAT           __REGb(NF_BASE + 0x20)  
  28. #define NFSTAT0          __REGi(NF_BASE + 0x24)  
  29. #define NFSTAT1          __REGi(NF_BASE + 0x28)  
  30. #define NFMECC0          __REGi(NF_BASE + 0x2C)  
  31. #define NFMECC1          __REGi(NF_BASE + 0x30)  
  32. #define NFSECC           __REGi(NF_BASE + 0x34)  
  33. #define NFSBLK           __REGi(NF_BASE + 0x38)  
  34. #define NFEBLK           __REGi(NF_BASE + 0x3C)  
  35.   
  36. #define S3C2440_NFCONT_nCE (1<<1)  
  37. #define S3C2440_ADDR_NALE 0x08  
  38. #define S3C2440_ADDR_NCLE 0x0c  
  39.   
  40.   
  41.   
  42. #ifdef CONFIG_NAND_SPL  
  43.   
  44. /* in the early stage of NAND flash booting, printf() is not available */  
  45. #define printf(fmt, args...)  
  46.   
  47. static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)  
  48. {  
  49.     int i;  
  50.     struct nand_chip *this = mtd->priv;  
  51.   
  52.     for (i = 0; i < len; i++)  
  53.         buf[i] = readb(this->IO_ADDR_R);  
  54. }  
  55. #endif  
  56.   
  57. ulong  IO_ADDR_W = NF_BASE;   
  58. static void s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)  
  59. {  
  60.     struct nand_chip *chip = mtd->priv;  
  61.     DEBUGN("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);  
  62.     if (ctrl & NAND_CTRL_CHANGE) {  
  63.         IO_ADDR_W = NF_BASE;  
  64.         if (!(ctrl & NAND_CLE))  
  65.                 IO_ADDR_W |= S3C2440_ADDR_NCLE;  
  66.         if (!(ctrl & NAND_ALE))  
  67.                 IO_ADDR_W |= S3C2440_ADDR_NALE;  
  68.   
  69.        if (ctrl & NAND_NCE)  
  70.             NFCONT &= ~ S3C2440_NFCONT_nCE;  
  71.        else  
  72.             NFCONT |= S3C2440_NFCONT_nCE;   
  73.     }  
  74.     if (cmd != NAND_CMD_NONE)  
  75.                 writeb(cmd, (void *)IO_ADDR_W);  
  76. }  
  77.   
  78.   
  79.   
  80. static int s3c2440_dev_ready(struct mtd_info *mtd)  
  81. {  
  82.     DEBUGN("dev_ready\n");  
  83.     return(NFSTAT & 0x01);  
  84. }  
  85.   
  86. #ifdef CONFIG_S3C2410_NAND_HWECC  
  87. void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)  
  88. {  
  89.     struct s3c2410_nand *nand = s3c2410_get_base_nand();  
  90.     debugX(1, "s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode);  
  91.     writel(readl(&nand->NFCONF) | S3C2410_NFCONF_INITECC, &nand->NFCONF);  
  92. }  
  93.   
  94. static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,  
  95.                       u_char *ecc_code)  
  96. {  
  97.     struct s3c2410_nand *nand = s3c2410_get_base_nand();  
  98.     ecc_code[0] = readb(&nand->NFECC);  
  99.     ecc_code[1] = readb(&nand->NFECC + 1);  
  100.     ecc_code[2] = readb(&nand->NFECC + 2);  
  101.     debugX(1, "s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n",  
  102.            mtd , ecc_code[0], ecc_code[1], ecc_code[2]);  
  103.   
  104.     return 0;  
  105. }  
  106.   
  107. static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,  
  108.                      u_char *read_ecc, u_char *calc_ecc)  
  109. {  
  110.     if (read_ecc[0] == calc_ecc[0] &&  
  111.         read_ecc[1] == calc_ecc[1] &&  
  112.         read_ecc[2] == calc_ecc[2])  
  113.         return 0;  
  114.   
  115.     printf("s3c2410_nand_correct_data: not implemented\n");  
  116.     return -1;  
  117. }  
  118. #endif  
  119.   
  120. int board_nand_init(struct nand_chip *nand)  
  121. {  
  122.     u_int32_t cfg;  
  123.     u_int8_t tacls, twrph0, twrph1;  
  124.     struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();  
  125.   
  126.     DEBUGN("board_nand_init()\n");  
  127.   
  128.     writel(readl(&clk_power->CLKCON) | (1 << 4), &clk_power->CLKCON);  
  129.   
  130.     /* initialize hardware */  
  131.     twrph0 = 4;  
  132.     twrph1 =2;  
  133.     tacls = 0;  
  134.   
  135.     cfg = ((tacls<<12)|(twrph0<<8)|(twrph1<<4));  
  136.     NFCONF=cfg;  
  137.     cfg = ((1<<6)|(1<<4)|(0<<1)|(1<<0));      
  138.     NFCONT=cfg;  
  139.     /* initialize nand_chip data structure */  
  140.     nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;  
  141.       
  142.   
  143.     /* read_buf and write_buf are default */  
  144.     /* read_byte and write_byte are default */  
  145.   
  146.     /* hwcontrol always must be implemented */  
  147.     nand->cmd_ctrl = s3c2440_hwcontrol;  
  148.     nand->dev_ready = s3c2440_dev_ready;  
  149.     nand->ecc.mode = NAND_ECC_SOFT;  
  150.   
  151.     DEBUGN("end of nand_init\n");  
  152.   
  153.     return 0;  
  154. }  


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多