自己写bootloader

来源:互联网 发布:app上传图片java代码 编辑:程序博客网 时间:2024/05/16 01:00

按照前面分析的u-boot的启动流程,自己写一个简单的Bootloader。这是参考韦东山老师的视频写的。

1、初始化硬件:关看门狗、设置时钟、设置SDRAM、初始化NAND Flash

2、如果Bootloader比较大,要重定位到SDRAM

3、把内核从NAND FLASH读入SDRAM

4、设置“要传给内核的参数”

5、跳转执行内核

start.S代码如下:

[cpp] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. #define S3C2440_MPLL_200MHZ     ((0x5c<<12)|(0x01<<4)|(0x02))  
  2. #define MEM_CTL_BASE    0x48000000  
  3.   
  4. .text  
  5. .global _start  
  6. _start:  
  7.   
  8. /* 1. 关看门狗 */  
  9.     ldr r0, =0x53000000  
  10.     mov r1, #0  
  11.     str r1, [r0]  
  12.   
  13. /* 2. 设置时钟 */  
  14.     ldr r0, =0x4c000014  
  15.     mov r1, #0x03;            // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1  
  16.     str r1, [r0]  
  17.   
  18.     /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */  
  19.     mrc p15, 0, r1, c1, c0, 0       /* 读出控制寄存器 */   
  20.     orr r1, r1, #0xc0000000         /* 设置为“asynchronous bus mode” */  
  21.     mcr p15, 0, r1, c1, c0, 0       /* 写入控制寄存器 */  
  22.   
  23.     /* MPLLCON = S3C2440_MPLL_200MHZ */  
  24.     ldr r0, =0x4c000004  
  25.     ldr r1, =S3C2440_MPLL_200MHZ  
  26.     str r1, [r0]  
  27.   
  28. /* 3. 初始化SDRAM */  
  29.     ldr r0, =MEM_CTL_BASE  
  30.     adr r1, sdram_config     /* sdram_config的当前地址 */  
  31.     add r3, r0, #(13*4)  
  32. 1:  
  33.     ldr r2, [r1], #4  
  34.     str r2, [r0], #4  
  35.     cmp r0, r3  
  36.     bne 1b  
  37.   
  38. /* 4. 重定位 : 把bootloader本身的代码从flash复制到它的链接地址去 */  
  39.     ldr sp, =0x34000000  
  40.   
  41.     bl nand_init  
  42.   
  43.     mov r0, #0  
  44.     ldr r1, =_start  
  45.     ldr r2, =__bss_start  
  46.     sub r2, r2, r1  
  47.       
  48.     bl copy_code_to_sdram  
  49.     bl clear_bss  
  50.       
  51. /* 5. 执行main */  
  52.     ldr lr, =halt  
  53.     ldr pc, =main  
  54. halt:  
  55.     b halt  
  56.   
  57. sdram_config:  
  58.     .long 0x22011110     //BWSCON  
  59.     .long 0x00000700     //BANKCON0  
  60.     .long 0x00000700     //BANKCON1  
  61.     .long 0x00000700     //BANKCON2  
  62.     .long 0x00000700     //BANKCON3    
  63.     .long 0x00000700     //BANKCON4  
  64.     .long 0x00000700     //BANKCON5  
  65.     .long 0x00018005     //BANKCON6  
  66.     .long 0x00018005     //BANKCON7  
  67.     .long 0x008C04F4     // REFRESH  
  68.     .long 0x000000B1     //BANKSIZE  
  69.     .long 0x00000030     //MRSRB6  
  70.     .long 0x00000030     //MRSRB7  
init.c
[cpp] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. /* NAND FLASH控制器 */  
  2. #define NFCONF (*((volatile unsigned long *)0x4E000000))  
  3. #define NFCONT (*((volatile unsigned long *)0x4E000004))  
  4. #define NFCMMD (*((volatile unsigned char *)0x4E000008))  
  5. #define NFADDR (*((volatile unsigned char *)0x4E00000C))  
  6. #define NFDATA (*((volatile unsigned char *)0x4E000010))  
  7. #define NFSTAT (*((volatile unsigned char *)0x4E000020))  
  8.   
  9. /* GPIO */  
  10. #define GPHCON              (*(volatile unsigned long *)0x56000070)  
  11. #define GPHUP               (*(volatile unsigned long *)0x56000078)  
  12.   
  13. /* UART registers*/  
  14. #define ULCON0              (*(volatile unsigned long *)0x50000000)  
  15. #define UCON0               (*(volatile unsigned long *)0x50000004)  
  16. #define UFCON0              (*(volatile unsigned long *)0x50000008)  
  17. #define UMCON0              (*(volatile unsigned long *)0x5000000c)  
  18. #define UTRSTAT0            (*(volatile unsigned long *)0x50000010)  
  19. #define UTXH0               (*(volatile unsigned char *)0x50000020)  
  20. #define URXH0               (*(volatile unsigned char *)0x50000024)  
  21. #define UBRDIV0             (*(volatile unsigned long *)0x50000028)  
  22.   
  23. #define TXD0READY   (1<<2)  
  24.   
  25.   
  26. void nand_read(unsigned int addr, unsigned char *buf, unsigned int len);  
  27.   
  28.   
  29. int isBootFromNorFlash(void)  
  30. {  
  31.     volatile int *p = (volatile int *)0;  
  32.     int val;  
  33.   
  34.     val = *p;  
  35.     *p = 0x12345678;  
  36.     if (*p == 0x12345678)  
  37.     {  
  38.         /* 写成功, 是nand启动 */  
  39.         *p = val;  
  40.         return 0;  
  41.     }  
  42.     else  
  43.     {  
  44.         /* NOR不能像内存一样写 */  
  45.         return 1;  
  46.     }  
  47. }  
  48.   
  49. void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)  
  50. {     
  51.     int i = 0;  
  52.       
  53.     /* 如果是NOR启动 */  
  54.     if (isBootFromNorFlash())  
  55.     {  
  56.         while (i < len)  
  57.         {  
  58.             dest[i] = src[i];  
  59.             i++;  
  60.         }  
  61.     }  
  62.     else  
  63.     {  
  64.         //nand_init();  
  65.         nand_read((unsigned int)src, dest, len);  
  66.     }  
  67. }  
  68.   
  69. void clear_bss(void)  
  70. {  
  71.     extern int __bss_start, __bss_end;  
  72.     int *p = &__bss_start;  
  73.       
  74.     for (; p < &__bss_end; p++)  
  75.         *p = 0;  
  76. }  
  77.   
  78. void nand_init(void)  
  79. {  
  80. #define TACLS   0  
  81. #define TWRPH0  1  
  82. #define TWRPH1  0  
  83.     /* 设置时序 */  
  84.     NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);  
  85.     /* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */  
  86.     NFCONT = (1<<4)|(1<<1)|(1<<0);      
  87. }  
  88.   
  89. void nand_select(void)  
  90. {  
  91.     NFCONT &= ~(1<<1);      
  92. }  
  93.   
  94. void nand_deselect(void)  
  95. {  
  96.     NFCONT |= (1<<1);   
  97. }  
  98.   
  99. void nand_cmd(unsigned char cmd)  
  100. {  
  101.     volatile int i;  
  102.     NFCMMD = cmd;  
  103.     for (i = 0; i < 10; i++);  
  104. }  
  105.   
  106. void nand_addr(unsigned int addr)  
  107. {  
  108.     unsigned int col  = addr % 2048;  
  109.     unsigned int page = addr / 2048;  
  110.     volatile int i;  
  111.   
  112.     NFADDR = col & 0xff;  
  113.     for (i = 0; i < 10; i++);  
  114.     NFADDR = (col >> 8) & 0xff;  
  115.     for (i = 0; i < 10; i++);  
  116.       
  117.     NFADDR  = page & 0xff;  
  118.     for (i = 0; i < 10; i++);  
  119.     NFADDR  = (page >> 8) & 0xff;  
  120.     for (i = 0; i < 10; i++);  
  121.     NFADDR  = (page >> 16) & 0xff;  
  122.     for (i = 0; i < 10; i++);      
  123. }  
  124.   
  125. void nand_wait_ready(void)  
  126. {  
  127.     while (!(NFSTAT & 1));  
  128. }  
  129.   
  130. unsigned char nand_data(void)  
  131. {  
  132.     return NFDATA;  
  133. }  
  134.   
  135. void nand_read(unsigned int addr, unsigned char *buf, unsigned int len)  
  136. {  
  137.     int col = addr % 2048;  
  138.     int i = 0;  
  139.           
  140.     /* 1. 选中 */  
  141.     nand_select();  
  142.   
  143.     while (i < len)  
  144.     {  
  145.         /* 2. 发出读命令00h */  
  146.         nand_cmd(0x00);  
  147.   
  148.         /* 3. 发出地址(分5步发出) */  
  149.         nand_addr(addr);  
  150.   
  151.         /* 4. 发出读命令30h */  
  152.         nand_cmd(0x30);  
  153.   
  154.         /* 5. 判断状态 */  
  155.         nand_wait_ready();  
  156.   
  157.         /* 6. 读数据 */  
  158.         for (; (col < 2048) && (i < len); col++)  
  159.         {  
  160.             buf[i] = nand_data();  
  161.             i++;  
  162.             addr++;  
  163.         }  
  164.           
  165.         col = 0;  
  166.     }  
  167.   
  168.     /* 7. 取消选中 */         
  169.     nand_deselect();  
  170. }  
  171.   
  172. #define PCLK            50000000    // init.c中的clock_init函数设置PCLK为50MHz  
  173. #define UART_CLK        PCLK        //  UART0的时钟源设为PCLK  
  174. #define UART_BAUD_RATE  115200      // 波特率  
  175. #define UART_BRD        ((UART_CLK  / (UART_BAUD_RATE * 16)) - 1)  
  176.   
  177. /* 
  178.  * 初始化UART0 
  179.  * 115200,8N1,无流控 
  180.  */  
  181. void uart0_init(void)  
  182. {  
  183.     GPHCON  |= 0xa0;    // GPH2,GPH3用作TXD0,RXD0  
  184.     GPHUP   = 0x0c;     // GPH2,GPH3内部上拉  
  185.   
  186.     ULCON0  = 0x03;     // 8N1(8个数据位,无较验,1个停止位)  
  187.     UCON0   = 0x05;     // 查询方式,UART时钟源为PCLK  
  188.     UFCON0  = 0x00;     // 不使用FIFO  
  189.     UMCON0  = 0x00;     // 不使用流控  
  190.     UBRDIV0 = UART_BRD; // 波特率为115200  
  191. }  
  192.   
  193. /* 
  194.  * 发送一个字符 
  195.  */  
  196. void putc(unsigned char c)  
  197. {  
  198.     /* 等待,直到发送缓冲区中的数据已经全部发送出去 */  
  199.     while (!(UTRSTAT0 & TXD0READY));  
  200.       
  201.     /* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */  
  202.     UTXH0 = c;  
  203. }  
  204.   
  205. void puts(char *str)  
  206. {  
  207.     int i = 0;  
  208.     while (str[i])  
  209.     {  
  210.         putc(str[i]);  
  211.         i++;  
  212.     }  
  213. }  
  214.   
  215. void puthex(unsigned int val)  
  216. {  
  217.     /* 0x1234abcd */  
  218.     int i;  
  219.     int j;  
  220.       
  221.     puts("0x");  
  222.   
  223.     for (i = 0; i < 8; i++)  
  224.     {  
  225.         j = (val >> ((7-i)*4)) & 0xf;  
  226.         if ((j >= 0) && (j <= 9))  
  227.             putc('0' + j);  
  228.         else  
  229.             putc('A' + j - 0xa);  
  230.           
  231.     }  
  232.       
  233. }  
boot.c
[cpp] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. #include "setup.h"  
  2.   
  3. extern void uart0_init(void);  
  4. extern void nand_read(unsigned int addr, unsigned char *buf, unsigned int len);  
  5. extern void puts(char *str);  
  6. extern void puthex(unsigned int val);  
  7.   
  8.   
  9. static struct tag *params;  
  10.   
  11. void setup_start_tag(void)  
  12. {  
  13.     params = (struct tag *)0x30000100;  
  14.   
  15.     params->hdr.tag = ATAG_CORE;  
  16.     params->hdr.size = tag_size (tag_core);  
  17.   
  18.     params->u.core.flags = 0;  
  19.     params->u.core.pagesize = 0;  
  20.     params->u.core.rootdev = 0;  
  21.   
  22.     params = tag_next (params);  
  23. }  
  24.   
  25. void setup_memory_tags(void)  
  26. {  
  27.     params->hdr.tag = ATAG_MEM;  
  28.     params->hdr.size = tag_size (tag_mem32);  
  29.       
  30.     params->u.mem.start = 0x30000000;  
  31.     params->u.mem.size  = 64*1024*1024;  
  32.       
  33.     params = tag_next (params);  
  34. }  
  35.   
  36. int strlen(char *str)  
  37. {  
  38.     int i = 0;  
  39.     while (str[i])  
  40.     {  
  41.         i++;  
  42.     }  
  43.     return i;  
  44. }  
  45.   
  46. void strcpy(char *dest, char *src)  
  47. {  
  48.     while ((*dest++ = *src++) != '\0');  
  49. }  
  50.   
  51. void setup_commandline_tag(char *cmdline)  
  52. {  
  53.     int len = strlen(cmdline) + 1;  
  54.       
  55.     params->hdr.tag  = ATAG_CMDLINE;  
  56.     params->hdr.size = (sizeof (struct tag_header) + len + 3) >> 2;  
  57.   
  58.     strcpy (params->u.cmdline.cmdline, cmdline);  
  59.   
  60.     params = tag_next (params);  
  61. }  
  62.   
  63. void setup_end_tag(void)  
  64. {  
  65.     params->hdr.tag = ATAG_NONE;  
  66.     params->hdr.size = 0;  
  67. }  
  68.   
  69.   
  70. int main(void)  
  71. {  
  72.     void (*theKernel)(int zero, int arch, unsigned int params);  
  73.     volatile unsigned int *p = (volatile unsigned int *)0x30008000;  
  74.   
  75.     /* 0. 帮内核设置串口: 内核启动的开始部分会从串口打印一些信息,但是内核一开始没有初始化串口 */  
  76.     uart0_init();  
  77.       
  78.     /* 1. 从NAND FLASH里把内核读入内存 */  
  79.     puts("Copy kernel from nand\n\r");  
  80.     nand_read(0x60000+64, (unsigned char *)0x30008000, 0x200000);  
  81.     puthex(0x1234ABCD);  
  82.     puts("\n\r");  
  83.     puthex(*p);  
  84.     puts("\n\r");  
  85.   
  86.     /* 2. 设置参数 */  
  87.     puts("Set boot params\n\r");  
  88.     setup_start_tag();  
  89.     setup_memory_tags();  
  90.     setup_commandline_tag("noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0");  
  91.     setup_end_tag();  
  92.   
  93.     /* 3. 跳转执行 */  
  94.     puts("Boot kernel\n\r");  
  95.     theKernel = (void (*)(intint, unsigned int))0x30008000;  
  96.     theKernel(0, 362, 0x30000100);    
  97.     /*  
  98.      *  mov r0, #0 
  99.      *  ldr r1, =362 
  100.      *  ldr r2, =0x30000100 
  101.      *  mov pc, #0x30008000  
  102.      */  
  103.   
  104.     puts("Error!\n\r");  
  105.     /* 如果一切正常, 不会执行到这里 */  
  106.   
  107.     return -1;  
  108. }  
boot.lds
[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. }  
setup.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. #define u8  unsigned char  
  25. #define u16 unsigned short  
  26. #define u32 unsigned long  
  27.   
  28. /* 
  29.  * Usage: 
  30.  *  - do not go blindly adding fields, add them at the end 
  31.  *  - when adding fields, don't rely on the address until 
  32.  *    a patch from me has been released 
  33.  *  - unused fields should be zero (for future expansion) 
  34.  *  - this structure is relatively short-lived - only 
  35.  *    guaranteed to contain useful data in setup_arch() 
  36.  */  
  37. #define COMMAND_LINE_SIZE 1024  
  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.   
  243. #define tag_member_present(tag,member)              \  
  244.     ((unsigned long)(&((struct tag *)0L)->member + 1)    \  
  245.         <= (tag)->hdr.size * 4)  
  246.   
  247. #define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))  
  248. #define tag_size(type)  ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)  
  249.   
  250. #define for_each_tag(t,base)        \  
  251.     for (t = base; t->hdr.size; t = tag_next(t))  
  252.   
  253. /* 
  254.  * Memory map description 
  255.  */  
  256. #define NR_BANKS 8  
  257.   
  258. struct meminfo {  
  259.     int nr_banks;  
  260.     unsigned long end;  
  261.     struct {  
  262.         unsigned long start;  
  263.         unsigned long size;  
  264.         int           node;  
  265.     } bank[NR_BANKS];  
  266. };  
  267.   
  268. extern struct meminfo meminfo;  
  269.   
  270. #endif  
Makefile
[cpp] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. CC      = arm-linux-gcc  
  2. LD      = arm-linux-ld  
  3. AR      = arm-linux-ar  
  4. OBJCOPY = arm-linux-objcopy  
  5. OBJDUMP = arm-linux-objdump  
  6.   
  7. CFLAGS      := -Wall -O2  
  8. CPPFLAGS    := -nostdinc -nostdlib -fno-builtin  
  9.   
  10. objs := start.o init.o boot.o  
  11.   
  12. boot.bin: $(objs)  
  13.     ${LD} -Tboot.lds -o boot.elf $^  
  14.     ${OBJCOPY} -O binary -S boot.elf $@  
  15.     ${OBJDUMP} -D -m arm boot.elf > boot.dis  
  16.       
  17. %.o:%.c  
  18.     ${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<  
  19.   
  20. %.o:%.S  
  21.     ${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<  
  22.   
  23. clean:  
  24.     rm -f *.o *.bin *.elf *.dis  
  25.      
0 0
原创粉丝点击