自己写 bootloader

来源:互联网 发布:晋中市网络平台登录 编辑:程序博客网 时间:2024/06/05 07:10

本文基于:mini2440开发板

    想想 uboot 的代码量,我们说自己写一个 bootloader 是不是口出狂言了?然而并没有,bootloader 的唯一目的只有一个,那便是启动内核。内核就是一大段可执行程序,我们只要跳转到它的入口地址去执行不就OK? 所以,写一个简单的 bootloader 并不困难。

    现在来思考一下,目的是启动内核,那么内核在哪里?刚上电的时候,内核肯定是位于 nandflash 里的,我们得具备初始化 nandflash 并读取的功能。那么,我们将内核去读到 sdram 然后跳转到入口地址去执行就够了么?然而还不行,bootloader 启动内核时还需要给内核传递一些信息(tag),两个必不可少的信息是 内存标记和命令行参数。信息传递完,那么内核就一定能起得来么?未必,启动内核时,我们还会传递一个机器ID,如果Uboot传递进去的机器ID和内核支持的机器ID不匹配,那么内核也无法启动。想必,分析过 uboot 的同学对这个并不陌生。

    自己写 bootloader ,或者移植 uboot ,需要知道的一些信息

    1、内核在 nandflash 中的地址,是 uImage 还是 zImage ,我这里用的是 uImage ,在 nandflash 里的 0x60000处,uImage 是用来支持 uboot 启动的,不过我们自己写的话用 uImage 也没关系,因为 uImage 就是在 zImage 的基础上加了一个 64 字节的头部,用来告诉 uboot 内核的信息,比如版本号、加载地址、链接地址、编译时间等。uboot 会获取到这个头部,干一些事情。我们自己写的话,直接跳到 uImage 启示地址 + 64 的地方去执行就OK 。

    2、内核的链接地址:0x30008000 ,这个连接地址实际上应该说是“真正”内核的链接地址,如果是 uImage ,不应该包含它的头部。知道什么意思了吧,使用 uImage 时,我们应当将整个 uImage 拷贝到 0x30008000 - 64 的地方去,也就是 0x30007fc0 。

    3、bootloader 的连接地址:uboot的链接地址一般为 0x3ff80000 处,我们自己写的也用这个地址好了。说到这里,必须得提一下,对于2440来说,不管是 nand 启动,还是 nor 启动,刚上电的时候我们的 bootloader 并不是运行在链接地址处,那么这时候跑在非链接地址处的这些指令就得有特殊要求——位置无关码。我个人做法,在将自身代码拷贝到链接地址处之前,能用汇编写的尽量不用C写,因为用汇编我们自己可以分得清哪些是位置无关码,迫不得已的情况下用C写,写完看反汇编,看看那些跳转指令是否依赖于当前PC值。

    4、标记 tag 的地址,2440 常用的做法是放在 0x30000100 处,我们同样也放在这里。其实放那都行,地址会作为参数传递给内核的。tag的放置方法,可以参考 uboot ,必须以 ATAG_CORE 类型的开头,以 ATAG_NONE 类型的结尾。

    5、启动内核时传递给内核的参数,3个,第一个默认0,第三个是前边提到的 tag 的地址,第二个是机器ID。内核中所有支持的“机器”或者称作开发板、单板都用一个 MACHINE_START 宏来定义,这个宏的作用就是填充一个 machine_desc 类型的结构体,填充的过程中会对它的 .nr 成员赋值,这个 nr 就是所谓的机器ID。举个例子:

[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. MACHINE_START(HALIBUT,"Halibut Board (QCT SURF7200A)")    
  2.     .boot_params      = 0x10000100,    
  3.     .map_io           = halibut_map_io,    
  4.     .init_irq         = halibut_init_irq,    
  5.     .init_machine     = halibut_init,    
  6.     .timer            = &msm_timer,    
  7. MACHINE_END   
[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. struct machine_desc __mach_desc_HALIBUT{    
  2. __used                                                              
  3. __attribute__((__section__(".arch.info.init")))= {    
  4.     .nr               = MACH_TYPE_HALIBUT,                  
  5.     .name             = "HalibutBoard (QCT SURF7200A)",    
  6.     .boot_params      = 0x10000100,    
  7.     .map_io           = halibut_map_io,    
  8.     .init_irq         = halibut_init_irq,    
  9.     .init_machine     = halibut_init,    
  10.     .timer            = &msm_timer,    
  11. };   
    MACH_TYPE_HALIBUT 这个宏,搜遍代码也没找到,我在 linux-2.6.32.2\arch\arm\tools\mach-types 里发现了一点踪迹,应该是在这里的信息生成的宏吧。对于 MINI2440 来说,机器ID定义的是 1999 。这里边也有个 boot_params 和前边实际tag存放的地址要一致。

    6、内核刚启动时会打印一些信息,但是那时候内核自己并不会初始化串口,也为了方便自己调试,bootloader里需要初始化串口。

    熟悉以上6条,自己写一个 bootloader 就十分简单了,下边直接上代码。支持 Nor nand 启动,也可以直接跑在 sdram 里。整个程序编译完小于4K,因此自身代码的重定位比较简单。

[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. boot.bin : boot_elf  
  2.     arm-linux-objcopy -O binary -S boot_elf boot.bin  
  3.     arm-linux-objdump -D -m arm  boot_elf > boot.dis  
  4.   
  5. boot_elf : start.o init.o main.o  
  6.     arm-linux-ld -Tboot.lds -g start.o init.o main.o -o boot_elf  
  7.       
  8. %.o:%.c  
  9.     arm-linux-gcc -g -c -o $@ $<  
  10.   
  11. %.o:%.S  
  12.     arm-linux-gcc -g -c -o $@ $<  
  13.   
  14. clean:  
  15.     rm -f *.o *.bin *.elf *.dis  
[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. SECTIONS {  
  2.     . = 0x33f80000;  
  3.     .text : { *(.text) }  
  4.       
  5.     . = ALIGN(4);  
  6.     .rodata : {*(.rodata*)}   
  7.       
  8.     . = ALIGN(4);  
  9.     .data : { *(.data) }  
  10.       
  11.     . = ALIGN(4);  
  12.     __bss_start = .;  
  13.     .bss : { *(.bss)  *(COMMON) }  
  14.     __bss_end = .;  
  15. }  
[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. .equ WTCON,     0x53000000  
  2. .equ BWSCON,    0x48000000  
  3. .equ CLKDIVN,   0x4c000014    
  4. .equ MPLLCON,   0x4c000004  
  5.   
  6. .text  
  7. .global _start  
  8. _start:  
  9.   
  10.     bl close_watch_dog  
  11.     bl set_clock  
  12.     bl init_sdram  
  13.     ldr sp, =0x34000000  
  14.     bl relocate  
  15.     bl clear_bss  
  16.     ldr lr, =loop_halt          @设置返回地址  
  17.     ldr pc, =main  
  18.   
  19. loop_halt:  
  20.     b loop_halt  
  21.       
  22. close_watch_dog:  
  23.     ldr r0, =WTCON  
  24.     mov r1, #0  
  25.     str r1, [r0]  
  26.     mov pc, lr  
  27.       
  28. set_clock:  
  29.     ldr r0, =CLKDIVN  
  30.     mov r1, #0x05   // FCLK:HCLK:PCLK=1:4:8, HDIVN=2,PDIVN=1  
  31.     str r1, [r0]  
  32.       
  33.     mrc p15, 0, r1, c1, c0, 0        /* 读出控制寄存器*/   
  34.     orr r1, r1, #0xc0000000          /* 设置为“asynchronous bus mode?*/  
  35.     mcr p15, 0, r1, c1, c0, 0        /* 写入控制寄存器*/  
  36.       
  37.     ldr r0, =MPLLCON  
  38.     ldr r1, =((0x5c<<12)|(0x01<<4)|(0x01))  //MPLL_400MHZ    
  39.     str r1, [r0]  
  40.       
  41.     /* 启动ICACHE */  
  42.     mrc p15, 0, r0, c1, c0, 0   @ read control reg  
  43.     orr r0, r0, #(1<<12)  
  44.     mcr p15, 0, r0, c1, c0, 0   @ write it back  
  45.       
  46.     mov pc, lr  
  47.   
  48. init_sdram:  
  49.     /* 如果程序在sdram里,那么就不初始化了 */  
  50.     adr r0, _start  
  51.     ldr r1, =0x33f80000   
  52.     cmp r0, r1  
  53.     beq 2f  
  54.       
  55.     mov r0,#0x48000000  
  56.     adrl r1,mem_cfg_val  
  57.                             @STr [r1],[r0],#4  
  58.     mov r4, #0  
  59. 1:    
  60.     ldr r3, [r1], #4  
  61.     str r3, [r0], #4  
  62.     add r4, #1  
  63.     cmp r4, #13  
  64.     bne 1b  
  65. 2:    
  66.     mov pc, lr  
  67.   
  68. relocate:  
  69.     /* 如果程序在sdram里,那么就不重定位了 */  
  70.     adr r0, _start  
  71.     ldr r1, =0x33f80000   
  72.     cmp r0, r1  
  73.     beq 5f  
  74.       
  75.     /* 如果是 nandflash 启动 或者nor 启动,条件:整个程序小于4k*/  
  76.     mov r0, #0x0  
  77.     ldr r1, =__bss_start  
  78.     ldr r2, =0x33f80000  
  79.     sub r1, r1, r2  
  80.     add r1, r1, #4  
  81. 4:    
  82.     ldr r3, [r0] ,#4  
  83.     str r3 ,[r2] ,#4  
  84.     cmp r0, r1  
  85.     bne 4b  
  86.           
  87. 5:    
  88.     mov pc, lr    
  89.   
  90.       
  91. clear_bss:  
  92.     ldr r0, =__bss_start          
  93.     ldr r1, =__bss_end        
  94.     mov r2, #0x00000000       
  95.   
  96. clbss_l:  
  97.     str r2, [r0]          
  98.     add r0, r0, #4  
  99.     cmp r0, r1  
  100.     ble clbss_l  
  101.     mov pc, lr  
  102.   
  103.   
  104. .align 4  
  105. mem_cfg_val:  
  106.     @ 存储控制器13个寄存器的设置值  
  107.     .long   0x22011110      @ BWSCON  
  108.     .long   0x00000700      @ BANKCON0  
  109.     .long   0x00000700      @ BANKCON1  
  110.     .long   0x00000700      @ BANKCON2  
  111.     .long   0x00000700      @ BANKCON3    
  112.     .long   0x00000700      @ BANKCON4  
  113.     .long   0x00000700      @ BANKCON5  
  114.     .long   0x00018005      @ BANKCON6  
  115.     .long   0x00018005      @ BANKCON7  
  116.     .long   0x008C07A3      @ rEFrESH  
  117.     .long   0x000000B1      @ BANKSIZE  
  118.     .long   0x00000030      @ MrSrB6  
  119.     .long   0x00000030      @ MrSrB7  
[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. #include "s3c2440.h"  
  2.   
  3. #define S3C2440_MPLL_400MHZ     ((0x5c<<12)|(0x01<<4)|(0x01))  
  4.   
  5. #define PCLK            50000000    // init.c中的clock_init函数设置PCLK为50MHz  
  6. #define UART_CLK        PCLK        //  UART0的时钟源设为PCLK  
  7. #define UART_BAUD_RATE  115200      // 波特率  
  8. #define UART_BRD        ((UART_CLK  / (UART_BAUD_RATE * 16)) - 1)  
  9.   
  10. void write_cmd(unsigned char cmd){  
  11.     NFCMD = cmd;  
  12. }  
  13. unsigned char read_data(){  
  14.     return NFDATA;  
  15. }  
  16. void nand_chip_select(){  
  17.       
  18.     NFCONT &= 0xfffffffd; //1111111111  
  19. }  
  20. void nand_chip_release(){  
  21.     NFCONT |= 0x02;     //1111111111  
  22. }  
  23. void nand_busy(){     
  24.     while(!(NFSTAT&(1<<0)));  //11111111        
  25. }  
  26. void s3c2440_nand_reset()  
  27. {  
  28.     nand_chip_select();  
  29.     write_cmd(0xff);   
  30.     nand_busy();  
  31.     nand_chip_release();  
  32. }  
  33. void nand_init(){  
  34. #define TACLS   1  
  35. #define TWRPH0  1  
  36. #define TWRPH1  0  
  37.     NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);  
  38.     NFCONT = (1<<4)|(1<<1)|(1<<0);  
  39.     NFSTAT =0x0;  
  40.     s3c2440_nand_reset();  
  41. }  
  42. void write_addr(unsigned int addr){  
  43.   
  44.     int i;  
  45.     int col, page;  
  46.     col = addr & 2047;  
  47.     page = addr / 2048;  
  48.       
  49.     NFADDR = col & 0xff;            /* Column Address A0~A7 */  
  50.     for(i=0; i<10; i++);       
  51.     NFADDR = (col >> 8) & 0x0f;   /* Column Address A8~A11 */  
  52.     for(i=0; i<10; i++);  
  53.     NFADDR = page & 0xff;           /* Row Address A12~A19 */  
  54.     for(i=0; i<10; i++);  
  55.     NFADDR = (page >> 8) & 0xff;  /* Row Address A20~A27 */  
  56.     for(i=0; i<10; i++);  
  57.     NFADDR = (page >> 16) & 0x01; /* Row Address A28 */  
  58.     for(i=0; i<10; i++);  
  59. }  
  60. void nand_read(unsigned char *buf, unsigned long start_addr, int size){//按页读取,一个起始地址对应至少2K的数捿  
  61.     int i, j;  
  62.   
  63.     if ((start_addr & 2047) || (size & 2047)) {  
  64.         return ;    /* 地址或长度不对齐 */  
  65.     }  
  66.   
  67.     nand_chip_select();  
  68.   
  69.     for(i=start_addr; i < (start_addr + size);) {  
  70.   
  71.         write_cmd(0);  
  72.         write_addr(i);  
  73.         write_cmd(0x30);          
  74.         nand_busy();  
  75.   
  76.         for(j=0; j < 2048; j++, i++) {   //按页读取  
  77.   
  78.             *buf = read_data();  
  79.             buf++;  
  80.         }  
  81.     }  
  82.   
  83.     nand_chip_release();  
  84.       
  85.     return ;  
  86. }  
  87.   
  88. void init_uart(){  
  89. <span style="white-space:pre">    </span>GPHCON  |= 0xa0;    // GPH2,GPH3用作TXD0,RXD0  
  90.     GPHUP   = 0x0c;     // GPH2,GPH3内部上拉      
  91.     ULCON0  = 0x03;     // 8N1(8个数据位,无较验,1个停止位)  
  92.     UCON0   = 0x05;     // 终端或查询方式,UART时钟源为PCLK  
  93.     UFCON0  = 0x00;     // 不使用FIFO  
  94.     UMCON0  = 0x00;     // 不使用流控  
  95.     UBRDIV0 = UART_BRD; // 波特率为115200  
  96. }  
  97.   
  98. void printch(unsigned char ch)  
  99. {  
  100.     while (!(UTRSTAT0 & 0x04)){  
  101.         ;  
  102.     }  
  103.     UTXH0 = ch;  
  104. }  
  105.   
  106. void printdec(unsigned int dec)  
  107. {  
  108.     if(dec==0)  
  109.     {  
  110.         printch( (char)('0'));  
  111.         return;  
  112.     }  
  113.     if(dec/10 != 0)printdec(dec/10);  
  114.     printch( (char)(dec%10 + '0'));  
  115. }  
  116.   
  117. void    printflt(double flt)  
  118. {  
  119.     int icnt = 0;  
  120.     int tmpint = 0;  
  121. }  
  122.   
  123. void    printstr(char* str)  
  124. {  
  125.     while(*str)  
  126.     {  
  127.         printch(*str++);  
  128.     }  
  129. }  
[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. #include "setup.h"  
  2.   
  3. extern void nand_init();  
  4. extern void init_uart();  
  5. extern void clear_bss();  
  6. extern void printstr(char* str);  
  7. static struct tag *params;  
  8. void (*theKernel)(int zero, int arch, unsigned int params);  
  9.   
  10. int strlen(const char *s)  
  11. {  
  12.     const char *sc;  
  13.   
  14.     for (sc = s; *sc != '\0'; ++sc)  
  15.         /* nothing */;  
  16.     return sc - s;  
  17. }  
  18.   
  19. char *strcpy(char *dest, const char *src)  
  20. {  
  21.     char *tmp = dest;  
  22.   
  23.     while ((*dest++ = *src++) != '\0')  
  24.         /* nothing */;  
  25.     return tmp;  
  26. }  
  27.   
  28. static void setup_start_tag (void)  
  29. {  
  30.     params = (struct tag *) 0x30000100;  
  31.   
  32.     params->hdr.tag = ATAG_CORE;  
  33.     params->hdr.size = tag_size (tag_core);  
  34.   
  35.     params->u.core.flags = 0;  
  36.     params->u.core.pagesize = 0;  
  37.     params->u.core.rootdev = 0;  
  38.   
  39.     params = tag_next (params);  
  40. }  
  41.   
  42. static void setup_memory_tags ()  
  43. {  
  44.     params->hdr.tag = ATAG_MEM;  
  45.     params->hdr.size = tag_size (tag_mem32);  
  46.     params->u.mem.start = 0x30000000;    //内存起始地址  
  47.     params->u.mem.size  = 0x4000000; //64m  
  48.     params = tag_next (params);  
  49. }  
  50.   
  51. static void setup_commandline_tag (char *commandline)  
  52. {  
  53.     char *p = commandline;  
  54.   
  55.     params->hdr.tag = ATAG_CMDLINE;  
  56.     params->hdr.size =  
  57.         (sizeof (struct tag_header) + strlen (p) + 1 + 3) >> 2;  
  58.   
  59.     strcpy (params->u.cmdline.cmdline, p);  
  60.     params = tag_next (params);  
  61. }  
  62.   
  63. static void setup_end_tag ()  
  64. {  
  65.     params->hdr.tag = ATAG_NONE;  
  66.     params->hdr.size = 0;  
  67. }  
  68.   
  69. int main(){  
  70.     init_uart();  
  71.     printstr("uart init ok \n\r");  
  72.     setup_start_tag ();  
  73.     setup_memory_tags ();  
  74.     setup_commandline_tag ("noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0");  
  75.     setup_end_tag ();  
  76.     printstr("set up tag ok \n\r");  
  77.     nand_init();  
  78.     // 将内核从 nandflash 读出  
  79.     nand_read((unsigned char *)0x30007fc0, (unsigned long)(0x60000), 0x300000);  
  80.     printstr("image read ok \n\r");  
  81.       
  82.     theKernel = (void (*)(intint, unsigned int))0x30008000;  
  83.     theKernel (0, 1999, 0x30000100);  
  84.       
  85.     printstr("error \n\r");  
  86.     return -1;  
  87. }  
[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. #ifndef     __S3C2440_H_  
  2. #define     __S3C2440_H_  
  3.   
  4. /* WOTCH DOG register */  
  5. #define     WTCON           (*(volatile unsigned long *)0x53000000)  
  6. #define     WTDAT           (*(volatile unsigned long *)0x53000004)  
  7. #define     WTCNT           (*(volatile unsigned long *)0x53000008)  
  8.   
  9. /* NAND Flash registers */  
  10. #define NFCONF              (*(volatile unsigned int *)0x4E000000)  
  11. #define NFCONT              (*(volatile unsigned int *)0x4E000004)  //bit 0     chip select  0disable 1able  
  12. #define NFCMD               (*(volatile unsigned int *)0x4E000008)  //8bit  
  13. #define NFADDR              (*(volatile unsigned int *)0x4E00000C)  //8bit  
  14. #define NFDATA              (*(volatile unsigned char *)0x4E000010) //32bit  
  15. #define NFSTAT              (*(volatile unsigned int *)0x4E000020)  //bit 0    0 busy 1 notbusy  
  16. /* GPIO registers */  
  17. #define GPACON              (*(volatile unsigned long *)0x56000000)  
  18. #define GPADAT              (*(volatile unsigned long *)0x56000004)  
  19.   
  20. #define GPBCON              (*(volatile unsigned long *)0x56000010)  
  21. #define GPBDAT              (*(volatile unsigned long *)0x56000014)  
  22. #define GPBUP               (*(volatile unsigned long *)0x56000018)  
  23.   
  24. #define GPCCON              (*(volatile unsigned long *)0x56000020)  
  25. #define GPCDAT              (*(volatile unsigned long *)0x56000024)  
  26. #define GPCUP               (*(volatile unsigned long *)0x56000028)  
  27.   
  28. #define GPDCON              (*(volatile unsigned long *)0x56000030)  
  29. #define GPDDAT              (*(volatile unsigned long *)0x56000034)  
  30. #define GPDUP               (*(volatile unsigned long *)0x56000038)  
  31.   
  32. #define GPECON              (*(volatile unsigned long *)0x56000040)  
  33. #define GPEDAT              (*(volatile unsigned long *)0x56000044)  
  34. #define GPEUP               (*(volatile unsigned long *)0x56000048)  
  35.   
  36. #define GPFCON              (*(volatile unsigned long *)0x56000050)  
  37. #define GPFDAT              (*(volatile unsigned long *)0x56000054)  
  38. #define GPFUP               (*(volatile unsigned long *)0x56000058)  
  39.   
  40. #define GPGCON              (*(volatile unsigned long *)0x56000060)  
  41. #define GPGDAT              (*(volatile unsigned long *)0x56000064)  
  42. #define GPGUP               (*(volatile unsigned long *)0x56000068)  
  43.   
  44. #define GPHCON              (*(volatile unsigned long *)0x56000070)  
  45. #define GPHDAT              (*(volatile unsigned long *)0x56000074)  
  46. #define GPHUP               (*(volatile unsigned long *)0x56000078)  
  47.   
  48. /*UART registers*/  
  49. #define ULCON0              (*(volatile unsigned long *)0x50000000)  
  50. #define UCON0               (*(volatile unsigned long *)0x50000004)  
  51. #define UFCON0              (*(volatile unsigned long *)0x50000008)  
  52. #define UMCON0              (*(volatile unsigned long *)0x5000000c)  
  53. #define UTRSTAT0            (*(volatile unsigned long *)0x50000010)  
  54. #define UTXH0               (*(volatile unsigned char *)0x50000020)  
  55. #define URXH0               (*(volatile unsigned char *)0x50000024)  
  56. #define UBRDIV0             (*(volatile unsigned long *)0x50000028)  
  57.   
  58. /*interrupt registes*/  
  59. #define SRCPND              (*(volatile unsigned long *)0x4A000000)  
  60. #define INTMOD              (*(volatile unsigned long *)0x4A000004)  
  61. #define INTMSK              (*(volatile unsigned long *)0x4A000008)  
  62. #define PRIORITY            (*(volatile unsigned long *)0x4A00000c)  
  63. #define INTPND              (*(volatile unsigned long *)0x4A000010)  
  64. #define INTOFFSET           (*(volatile unsigned long *)0x4A000014)  
  65. #define SUBSRCPND           (*(volatile unsigned long *)0x4A000018)  
  66. #define INTSUBMSK           (*(volatile unsigned long *)0x4A00001c)  
  67.   
  68. /*external interrupt registers*/  
  69. #define EINTMASK            (*(volatile unsigned long *)0x560000a4)  
  70. #define EINTPEND            (*(volatile unsigned long *)0x560000a8)  
  71.   
  72. /*clock registers*/  
  73. #define LOCKTIME            (*(volatile unsigned long *)0x4c000000)  
  74. #define MPLLCON             (*(volatile unsigned long *)0x4c000004)  
  75. #define UPLLCON             (*(volatile unsigned long *)0x4c000008)  
  76. #define CLKCON              (*(volatile unsigned long *)0x4c00000c)  
  77. #define CLKSLOW             (*(volatile unsigned long *)0x4c000010)  
  78. #define CLKDIVN             (*(volatile unsigned long *)0x4c000014)  
  79.   
  80. /*PWM & Timer registers*/  
  81. #define TCFG0               (*(volatile unsigned long *)0x51000000)  
  82. #define TCFG1               (*(volatile unsigned long *)0x51000004)  
  83. #define TCON                (*(volatile unsigned long *)0x51000008)  
  84. #define TCNTB0              (*(volatile unsigned long *)0x5100000c)  
  85. #define TCMPB0              (*(volatile unsigned long *)0x51000010)  
  86. #define TCNTO0              (*(volatile unsigned long *)0x51000014)  
  87.   
  88. /* I2C registers */  
  89. #define IICCON              (*(volatile unsigned char *)0x54000000) // IIC control  
  90. #define IICSTAT             (*(volatile unsigned char *)0x54000004) // IIC status  
  91. #define IICADD              (*(volatile unsigned char *)0x54000008) // IIC address  
  92. #define IICDS               (*(volatile unsigned char *)0x5400000c) // IIC data shift  
  93.   
  94. // LCD CONTROLLER  
  95. #define LCDCON1             (*(volatile unsigned long *)0x4d000000) //LCD control 1  
  96. #define LCDCON2             (*(volatile unsigned long *)0x4d000004) //LCD control 2  
  97. #define LCDCON3             (*(volatile unsigned long *)0x4d000008) //LCD control 3  
  98. #define LCDCON4             (*(volatile unsigned long *)0x4d00000c) //LCD control 4  
  99. #define LCDCON5             (*(volatile unsigned long *)0x4d000010) //LCD control 5  
  100. #define LCDSADDR1           (*(volatile unsigned long *)0x4d000014) //STN/TFT Frame buffer start address 1  
  101. #define LCDSADDR2           (*(volatile unsigned long *)0x4d000018) //STN/TFT Frame buffer start address 2  
  102. #define LCDSADDR3           (*(volatile unsigned long *)0x4d00001c) //STN/TFT Virtual screen address set  
  103. #define REDLUT              (*(volatile unsigned long *)0x4d000020) //STN Red lookup table  
  104. #define GREENLUT            (*(volatile unsigned long *)0x4d000024) //STN Green lookup table   
  105. #define BLUELUT             (*(volatile unsigned long *)0x4d000028) //STN Blue lookup table  
  106. #define DITHMODE            (*(volatile unsigned long *)0x4d00004c) //STN Dithering mode  
  107. #define TPAL                (*(volatile unsigned long *)0x4d000050) //TFT Temporary palette  
  108. #define LCDINTPND           (*(volatile unsigned long *)0x4d000054) //LCD Interrupt pending  
  109. #define LCDSRCPND           (*(volatile unsigned long *)0x4d000058) //LCD Interrupt source  
  110. #define LCDINTMSK           (*(volatile unsigned long *)0x4d00005c) //LCD Interrupt mask  
  111. #define LPCSEL              (*(volatile unsigned long *)0x4d000060) //LPC3600 Control  
  112.   
  113. #endif    /*#ifndef __PRINT_H_*/  
[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. /* 
  2.  *  linux/include/asm/setup.h 
  3.  * 
  4.  *  Copyright (C) 1997-1999 Russell King 
  5.  * 
  6.  * This program is free software; you can redistribute it and/or modify 
  7.  * it under the terms of the GNU General Public License version 2 as 
  8.  * published by the Free Software Foundation. 
  9.  * 
  10.  *  Structure passed to kernel to tell it about the 
  11.  *  hardware it's running on.  See linux/Documentation/arm/Setup 
  12.  *  for more info. 
  13.  * 
  14.  * NOTE: 
  15.  *  This file contains two ways to pass information from the boot 
  16.  *  loader to the kernel. The old struct param_struct is deprecated, 
  17.  *  but it will be kept in the kernel for 5 years from now 
  18.  *  (2001). This will allow boot loaders to convert to the new struct 
  19.  *  tag way. 
  20.  */  
  21. #ifndef __ASMARM_SETUP_H  
  22. #define __ASMARM_SETUP_H  
  23.   
  24. /* 
  25.  * Usage: 
  26.  *  - do not go blindly adding fields, add them at the end 
  27.  *  - when adding fields, don't rely on the address until 
  28.  *    a patch from me has been released 
  29.  *  - unused fields should be zero (for future expansion) 
  30.  *  - this structure is relatively short-lived - only 
  31.  *    guaranteed to contain useful data in setup_arch() 
  32.  */  
  33. #define COMMAND_LINE_SIZE 1024  
  34.   
  35. #define u32     unsigned long     
  36. #define u16     unsigned short    
  37. #define u8      unsigned char  
  38.       
  39. /* This is the old deprecated way to pass parameters to the kernel */  
  40. struct param_struct {  
  41.     union {  
  42.     struct {  
  43.         unsigned long page_size;        /*  0 */  
  44.         unsigned long nr_pages;     /*  4 */  
  45.         unsigned long ramdisk_size;     /*  8 */  
  46.         unsigned long flags;        /* 12 */  
  47. #define FLAG_READONLY   1  
  48. #define FLAG_RDLOAD 4  
  49. #define FLAG_RDPROMPT   8  
  50.         unsigned long rootdev;      /* 16 */  
  51.         unsigned long video_num_cols;   /* 20 */  
  52.         unsigned long video_num_rows;   /* 24 */  
  53.         unsigned long video_x;      /* 28 */  
  54.         unsigned long video_y;      /* 32 */  
  55.         unsigned long memc_control_reg; /* 36 */  
  56.         unsigned char sounddefault;     /* 40 */  
  57.         unsigned char adfsdrives;       /* 41 */  
  58.         unsigned char bytes_per_char_h; /* 42 */  
  59.         unsigned char bytes_per_char_v; /* 43 */  
  60.         unsigned long pages_in_bank[4]; /* 44 */  
  61.         unsigned long pages_in_vram;    /* 60 */  
  62.         unsigned long initrd_start;     /* 64 */  
  63.         unsigned long initrd_size;      /* 68 */  
  64.         unsigned long rd_start;     /* 72 */  
  65.         unsigned long system_rev;       /* 76 */  
  66.         unsigned long system_serial_low;    /* 80 */  
  67.         unsigned long system_serial_high;   /* 84 */  
  68.         unsigned long mem_fclk_21285;       /* 88 */  
  69.     } s;  
  70.     char unused[256];  
  71.     } u1;  
  72.     union {  
  73.     char paths[8][128];  
  74.     struct {  
  75.         unsigned long magic;  
  76.         char n[1024 - sizeof(unsigned long)];  
  77.     } s;  
  78.     } u2;  
  79.     char commandline[COMMAND_LINE_SIZE];  
  80. };  
  81.   
  82.   
  83. /* 
  84.  * The new way of passing information: a list of tagged entries 
  85.  */  
  86.   
  87. /* The list ends with an ATAG_NONE node. */  
  88. #define ATAG_NONE   0x00000000  
  89.   
  90. struct tag_header {  
  91.     u32 size;  
  92.     u32 tag;  
  93. };  
  94.   
  95. /* The list must start with an ATAG_CORE node */  
  96. #define ATAG_CORE   0x54410001  
  97.   
  98. struct tag_core {  
  99.     u32 flags;      /* bit 0 = read-only */  
  100.     u32 pagesize;  
  101.     u32 rootdev;  
  102. };  
  103.   
  104. /* it is allowed to have multiple ATAG_MEM nodes */  
  105. #define ATAG_MEM    0x54410002  
  106.   
  107. struct tag_mem32 {  
  108.     u32 size;  
  109.     u32 start;  /* physical start address */  
  110. };  
  111.   
  112. /* VGA text type displays */  
  113. #define ATAG_VIDEOTEXT  0x54410003  
  114.   
  115. struct tag_videotext {  
  116.     u8      x;  
  117.     u8      y;  
  118.     u16     video_page;  
  119.     u8      video_mode;  
  120.     u8      video_cols;  
  121.     u16     video_ega_bx;  
  122.     u8      video_lines;  
  123.     u8      video_isvga;  
  124.     u16     video_points;  
  125. };  
  126.   
  127. /* describes how the ramdisk will be used in kernel */  
  128. #define ATAG_RAMDISK    0x54410004  
  129.   
  130. struct tag_ramdisk {  
  131.     u32 flags;  /* bit 0 = load, bit 1 = prompt */  
  132.     u32 size;   /* decompressed ramdisk size in _kilo_ bytes */  
  133.     u32 start;  /* starting block of floppy-based RAM disk image */  
  134. };  
  135.   
  136. /* describes where the compressed ramdisk image lives (virtual address) */  
  137. /* 
  138.  * this one accidentally used virtual addresses - as such, 
  139.  * its depreciated. 
  140.  */  
  141. #define ATAG_INITRD 0x54410005  
  142.   
  143. /* describes where the compressed ramdisk image lives (physical address) */  
  144. #define ATAG_INITRD2    0x54420005  
  145.   
  146. struct tag_initrd {  
  147.     u32 start;  /* physical start address */  
  148.     u32 size;   /* size of compressed ramdisk image in bytes */  
  149. };  
  150.   
  151. /* board serial number. "64 bits should be enough for everybody" */  
  152. #define ATAG_SERIAL 0x54410006  
  153.   
  154. struct tag_serialnr {  
  155.     u32 low;  
  156.     u32 high;  
  157. };  
  158.   
  159. /* board revision */  
  160. #define ATAG_REVISION   0x54410007  
  161.   
  162. struct tag_revision {  
  163.     u32 rev;  
  164. };  
  165.   
  166. /* initial values for vesafb-type framebuffers. see struct screen_info 
  167.  * in include/linux/tty.h 
  168.  */  
  169. #define ATAG_VIDEOLFB   0x54410008  
  170.   
  171. struct tag_videolfb {  
  172.     u16     lfb_width;  
  173.     u16     lfb_height;  
  174.     u16     lfb_depth;  
  175.     u16     lfb_linelength;  
  176.     u32     lfb_base;  
  177.     u32     lfb_size;  
  178.     u8      red_size;  
  179.     u8      red_pos;  
  180.     u8      green_size;  
  181.     u8      green_pos;  
  182.     u8      blue_size;  
  183.     u8      blue_pos;  
  184.     u8      rsvd_size;  
  185.     u8      rsvd_pos;  
  186. };  
  187.   
  188. /* command line: \0 terminated string */  
  189. #define ATAG_CMDLINE    0x54410009  
  190.   
  191. struct tag_cmdline {  
  192.     char    cmdline[1]; /* this is the minimum size */  
  193. };  
  194.   
  195. /* acorn RiscPC specific information */  
  196. #define ATAG_ACORN  0x41000101  
  197.   
  198. struct tag_acorn {  
  199.     u32 memc_control_reg;  
  200.     u32 vram_pages;  
  201.     u8 sounddefault;  
  202.     u8 adfsdrives;  
  203. };  
  204.   
  205. /* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */  
  206. #define ATAG_MEMCLK 0x41000402  
  207.   
  208. struct tag_memclk {  
  209.     u32 fmemclk;  
  210. };  
  211.   
  212. struct tag {  
  213.     struct tag_header hdr;  
  214.     union {  
  215.         struct tag_core     core;  
  216.         struct tag_mem32    mem;  
  217.         struct tag_videotext    videotext;  
  218.         struct tag_ramdisk  ramdisk;  
  219.         struct tag_initrd   initrd;  
  220.         struct tag_serialnr serialnr;  
  221.         struct tag_revision revision;  
  222.         struct tag_videolfb videolfb;  
  223.         struct tag_cmdline  cmdline;  
  224.   
  225.         /* 
  226.          * Acorn specific 
  227.          */  
  228.         struct tag_acorn    acorn;  
  229.   
  230.         /* 
  231.          * DC21285 specific 
  232.          */  
  233.         struct tag_memclk   memclk;  
  234.     } u;  
  235. };  
  236.   
  237. struct tagtable {  
  238.     u32 tag;  
  239.     int (*parse)(const struct tag *);  
  240. };  
  241.   
  242. #define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))  
  243. #define tag_size(type)  ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)  
  244.   
  245. /* 
  246.  * Memory map description 
  247.  */  
  248. #define NR_BANKS 8  
  249.   
  250. struct meminfo {  
  251.     int nr_banks;  
  252.     unsigned long end;  
  253.     struct {  
  254.         unsigned long start;  
  255.         unsigned long size;  
  256.         int           node;  
  257.     } bank[NR_BANKS];  
  258. };  
  259.   
  260. extern struct meminfo meminfo;  
  261.   
  262. #endif  
转载请注明出处 http://blog.csdn.net/lizuobin2/
0 0