一、bootloader 目标:启动内核

基本功能:

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

  ②image比较大需要重定位到SDRAM

  ②将内核从NAND FLASH读到 SDRAM

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

  ④跳转执行内核

启动时间优化:

  ①提高CPU频率:

       1,FCLKCPU提供的时钟信号。
          2,HCLK是为AHB总线提供的时钟信号, Advanced High-performance Bus,主要用于高速外设,比如内存控制器,中断控制器,LCD控制器, DMA 等。
          3,PCLK是为APB总线提供的时钟信号,Advanced Peripherals Bus,主要用于低速外设,比如看门狗,UART控制器, IIS, I2C, SDI/MMC, GPIO,RTC and SPI等。

  ②启动ICACHE: 

    CPU将多条指令一次装入ICACHE,不用每次到SDRAM中去取指。
           另外,DCACHE主要用来取数据,需要启用MMU.

    

1.start.S

  1. #define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02))
  2. #define S3C2440_MPLL_400MHZ ((0x5c<<12)|(0x01<<4)|(0x01))
  3. #define MEM_CTL_BASE 0x48000000
  4.  
  5. .text
  6. .global _start
  7. _start:
  8.  
  9. /* 1. 关看门狗 */
  10. ldr r0, =0x53000000
  11. mov r1, #
  12. str r1, [r0]
  13.  
  14. /* 2. 设置时钟 */
  15. ldr r0, =0x4c000014
  16. // mov r1, #0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
  17. mov r1, #0x05; // FCLK:HCLK:PCLK=1:4:8
  18. str r1, [r0]
  19.  
  20. /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
  21. mrc p15, , r1, c1, c0, /* 读出控制寄存器 */
  22. orr r1, r1, #0xc0000000 /* 设置为“asynchronous bus mode” */
  23. mcr p15, , r1, c1, c0, /* 写入控制寄存器 */
  24.  
  25. /* MPLLCON = S3C2440_MPLL_200MHZ */
  26. ldr r0, =0x4c000004
  27. ldr r1, =S3C2440_MPLL_400MHZ
  28. str r1, [r0]
  29.  
  30. /* 启动ICACHE */
  31. mrc p15, , r0, c1, c0, @ read control reg 读协处理器
  32. orr r0, r0, #(<<)
  33. mcr p15, , r0, c1, c0, @ write it back 写入协处理器
  34.  
  35. /* 3. 初始化SDRAM */
  36. ldr r0, =MEM_CTL_BASE
  37. adr r1, sdram_config /* sdram_config的当前地址 */
  38. add r3, r0, #(*)
  39. :
  40. ldr r2, [r1], #
  41. str r2, [r0], #
  42. cmp r0, r3
  43. bne 1b
  44.  
  45. /* 4. 重定位 : 把bootloader本身的代码从flash复制到它的链接地址去 */
  46. ldr sp, =0x34000000
  47.  
  48. bl nand_init

  49.   /* r0 r1 r2 表示给之后调用C函数传入的参数 */
  50. mov r0, #
  51. ldr r1, =_start
  52. ldr r2, =__bss_start /*通过伪汇编获取bss段的结束地址*/
  53. sub r2, r2, r1
  54.  
  55. bl copy_code_to_sdram
  56. bl clear_bss
  57.  
  58. /* 5. 执行main */
  59. ldr lr, =halt
  60. ldr pc, =main
  61. halt:
  62. b halt
  63.  
  64. sdram_config:
  65. .long 0x22011110 //BWSCON
  66. .long 0x00000700 //BANKCON0
  67. .long 0x00000700 //BANKCON1
  68. .long 0x00000700 //BANKCON2
  69. .long 0x00000700 //BANKCON3
  70. .long 0x00000700 //BANKCON4
  71. .long 0x00000700 //BANKCON5
  72. .long 0x00018005 //BANKCON6
  73. .long 0x00018005 //BANKCON7
  74. .long 0x008C04F4 // REFRESH
  75. .long 0x000000B1 //BANKSIZE
  76. .long 0x00000030 //MRSRB6
  77. .long 0x00000030 //MRSRB7

2.init.c

  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 (*((puthexvolatile 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. void nand_read(unsigned int addr, unsigned char *buf, unsigned int len);
  26.  
  27. int isBootFromNorFlash(void)
  28. {
  29. volatile int *p = (volatile int *);
  30. int val;
  31.  
  32. val = *p;
  33. *p = 0x12345678;
  34. if (*p == 0x12345678)
  35. {
  36. /* 写成功, 是nand启动 */
  37. *p = val;
  38. return ;
  39. }
  40. else
  41. {
  42. /* NOR不能像内存一样写 */
  43. return ;
  44. }
  45. }
  46.  
  47. void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
  48. {
  49. int i = ;
  50.  
  51. /* 如果是NOR启动 */
  52. if (isBootFromNorFlash())
  53. {
  54. while (i < len)
  55. {
  56. dest[i] = src[i];
  57. i++;
  58. }
  59. }
  60. else
  61. {
  62. //nand_init();
  63. nand_read((unsigned int)src, dest, len);
  64. }
  65. }
  66.  
  67. void clear_bss(void)
  68. {
  69. extern int __bss_start, __bss_end;
  70. int *p = &__bss_start;
  71.  
  72. for (; p < &__bss_end; p++)
  73. *p = ;
  74. }
  75.  
  76. void nand_init(void)
  77. {
  78. #define TACLS 0
  79. #define TWRPH0 1
  80. #define TWRPH1 0
  81. /* 设置时序 */
  82. NFCONF = (TACLS<<)|(TWRPH0<<)|(TWRPH1<<);
  83. /* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */
  84. NFCONT = (<<)|(<<)|(<<);
  85. }
  86.  
  87. void nand_select(void)
  88. {
  89. NFCONT &= ~(<<);
  90. }
  91.  
  92. void nand_deselect(void)
  93. {
  94. NFCONT |= (<<);
  95. }
  96.  
  97. void nand_cmd(unsigned char cmd)
  98. {
  99. volatile int i;
  100. NFCMMD = cmd;
  101. for (i = ; i < ; i++);
  102. }
  103.  
  104. void nand_addr(unsigned int addr)
  105. {
  106. unsigned int col = addr % ;
  107. unsigned int page = addr / ;
  108. volatile int i;
  109.  
  110. NFADDR = col & 0xff;
  111. for (i = ; i < ; i++);
  112. NFADDR = (col >> ) & 0xff;
  113. for (i = ; i < ; i++);
  114.  
  115. NFADDR = page & 0xff;
  116. for (i = ; i < ; i++);
  117. NFADDR = (page >> ) & 0xff;
  118. for (i = ; i < ; i++);
  119. NFADDR = (page >> ) & 0xff;
  120. for (i = ; i < ; i++);
  121. }
  122.  
  123. void nand_wait_ready(void)
  124. {
  125. while (!(NFSTAT & ));
  126. }
  127.  
  128. unsigned char nand_data(void)
  129. {
  130. return NFDATA;
  131. }
  132.  
  133. void nand_read(unsigned int addr, unsigned char *buf, unsigned int len)
  134. {
  135. int col = addr % ;
  136. int i = ;
  137.  
  138. /* 1. 选中 */
  139. nand_select();
  140.  
  141. while (i < len)
  142. {
  143. /* 2. 发出读命令00h */
  144. nand_cmd(0x00);
  145.  
  146. /* 3. 发出地址(分5步发出) */
  147. nand_addr(addr);
  148.  
  149. /* 4. 发出读命令30h */
  150. nand_cmd(0x30);
  151.  
  152. /* 5. 判断状态 */
  153. nand_wait_ready();
  154.  
  155. /* 6. 读数据 */
  156. for (; (col < ) && (i < len); col++)
  157. {
  158. buf[i] = nand_data();
  159. i++;
  160. addr++;
  161. }
  162.  
  163. col = ;
  164. }
  165.  
  166. /* 7. 取消选中 */
  167. nand_deselect();
  168. }
  169.  
  170. #define PCLK 50000000 // init.c中的clock_init函数设置PCLK为50MHz
  171. #define UART_CLK PCLK // UART0的时钟源设为PCLK
  172. #define UART_BAUD_RATE 115200 // 波特率
  173. #define UART_BRD ((UART_CLK / (UART_BAUD_RATE * 16)) - 1)
  174.  
  175. /*
  176. * 初始化UART0
  177. * 115200,8N1,无流控
  178. */
  179. void uart0_init(void)
  180. {
  181. GPHCON |= 0xa0; // GPH2,GPH3用作TXD0,RXD0
  182. GPHUP = 0x0c; // GPH2,GPH3内部上拉
  183.  
  184. ULCON0 = 0x03; // 8N1(8个数据位,无较验,1个停止位)
  185. UCON0 = 0x05; // 查询方式,UART时钟源为PCLK
  186. UFCON0 = 0x00; // 不使用FIFO
  187. UMCON0 = 0x00; // 不使用流控
  188. UBRDIV0 = UART_BRD; // 波特率为115200
  189. }
  190.  
  191. /*
  192. * 发送一个字符
  193. */
  194. void putc(unsigned char c)
  195. {
  196. /* 等待,直到发送缓冲区中的数据已经全部发送出去 */
  197. while (!(UTRSTAT0 & TXD0READY));
  198.  
  199. /* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */
  200. UTXH0 = c;
  201. }
  202.  
  203. void puts(char *str)
  204. {
  205. int i = ;
  206. while (str[i])
  207. {
  208. putc(str[i]);
  209. i++;
  210. }
  211. }
  212.  
  213. void puthex(unsigned int val)
  214. {
  215. /* 0x1234abcd */
  216. int i;
  217. int j;
  218.  
  219. puts("0x");
  220.  
  221. for (i = ; i < ; i++)
  222. {
  223. j = (val >> ((-i)*)) & 0xf;
  224. if ((j >= ) && (j <= ))
  225. putc('' + j);
  226. else
  227. putc('A' + j - 0xa);
  228.  
  229. }
  230.  
  231. }

3.boot.c

  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. static struct tag *params;
  9.  
  10. void setup_start_tag(void)
  11. {
  12. params = (struct tag *)0x30000100;
  13.  
  14. params->hdr.tag = ATAG_CORE; //0x54410001,表示参数的开始
  15. params->hdr.size = tag_size (tag_core); //5个
  16.  
  17. params->u.core.flags = ;
  18. params->u.core.pagesize = ; 
  19. params->u.core.rootdev = ;
  20.  
  21. params = tag_next (params);
  22. }
  23.  
  24. void setup_memory_tags(void)
  25. {
  26. params->hdr.tag = ATAG_MEM;
  27. params->hdr.size = tag_size (tag_mem32);
  28.  
  29. params->u.mem.start = 0x30000000;
  30. params->u.mem.size = **; //64M
  31.  
  32. params = tag_next (params); //如分多个内存存放tag,用tag_next查找
  33. }
  34.  
  35. int strlen(char *str)
  36. {
  37. int i = ;
  38. while (str[i])
  39. {
  40. i++;
  41. }
  42. return i;
  43. }
  44.  
  45. void strcpy(char *dest, char *src)
  46. {
  47. while ((*dest++ = *src++) != '\0');
  48. }
  49.  
  50. void setup_commandline_tag(char *cmdline)
  51. {
  52. int len = strlen(cmdline) + ;
  53.  
  54. params->hdr.tag = ATAG_CMDLINE;
  55. params->hdr.size = (sizeof (struct tag_header) + len + ) >> ; //向4取整
  56.  
  57. strcpy (params->u.cmdline.cmdline, cmdline); 
  58.  
  59. params = tag_next (params);
  60. }
  61.  
  62. void setup_end_tag(void)
  63. {
  64. params->hdr.tag = ATAG_NONE;
  65. params->hdr.size = ;
  66. }
  67.  
  68. int main(void)
  69. {
  70. void (*theKernel)(int zero, int arch, unsigned int params);
  71. volatile unsigned int *p = (volatile unsigned int *)0x30008000;
  72.  
  73. /* 0. 帮内核设置串口: 内核启动的开始部分会从串口打印一些信息,但是内核一开始没有初始化串口 */
  74. uart0_init();
  75.  
  76. /* 1. 从NAND FLASH里把内核读入内存 */
  77. puts("Copy kernel from nand\n\r");
  78. nand_read(0x60000+, (unsigned char *)0x30008000, 0x200000);
  79. puthex(0x1234ABCD);
  80. puts("\n\r");
  81. puthex(*p);
  82. puts("\n\r");
  83.  
  84. /* 2. 设置参数 ,与内核约定参数存放地址,Uboot写个内核的遗嘱^^*/
  85. puts("Set boot params\n\r");
  86. setup_start_tag();
  87. setup_memory_tags();
  88. setup_commandline_tag("noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0");
  89. setup_end_tag();
  90.  
  91. /* 3. 跳转执行 */
  92. puts("Boot kernel\n\r");
  93. theKernel = (void (*)(int, int, unsigned int))0x30008000;
  94. theKernel(, , 0x30000100); //362:arm
  95. /*
  96. * mov r0, #0
  97. * ldr r1, =362
  98. * ldr r2, =0x30000100
  99. * mov pc, #0x30008000
  100. */
  101.  
  102. puts("Error!\n\r");
  103. /* 如果一切正常, 不会执行到这里 */
  104.  
  105. return -;
  106. }

4.boot.lds  :   指定代码存放的位置

  1. SECTIONS {
  2. . = 0x33f80000; #与最高地址差512K
  3. .text : { *(.text) }
  4.  
  5. . = ALIGN();
  6. .rodata : {*(.rodata*)}
  7.  
  8. . = ALIGN();
  9. .data : { *(.data) }
  10.  
  11. . = ALIGN();
  12. __bss_start = .; #bss段指向当前地址,保存未初始化或为0的全局变量
  13. .bss : { *(.bss) *(COMMON) }
  14. __bss_end = .;   #bss段设定起始和结束地址,程序启动时统一初始化保存的变量
  15. }

5.setup.h

  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[]; /* 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[];
  71. } u1;
  72. union {
  73. char paths[][];
  74. struct {
  75. unsigned long magic;
  76. char n[ - sizeof(unsigned long)];
  77. } s;
  78. } u2;
  79. char commandline[COMMAND_LINE_SIZE];
  80. };
  81.  
  82. /*
  83. * The new way of passing information: a list of tagged entries
  84. */
  85.  
  86. /* The list ends with an ATAG_NONE node. */
  87. #define ATAG_NONE 0x00000000
  88.  
  89. struct tag_header {
  90. u32 size;
  91. u32 tag;
  92. };
  93.  
  94. /* The list must start with an ATAG_CORE node */
  95. #define ATAG_CORE 0x54410001
  96.  
  97. struct tag_core {
  98. u32 flags; /* bit 0 = read-only */
  99. u32 pagesize;
  100. u32 rootdev;
  101. };
  102.  
  103. /* it is allowed to have multiple ATAG_MEM nodes */
  104. #define ATAG_MEM 0x54410002
  105.  
  106. struct tag_mem32 {
  107. u32 size;
  108. u32 start; /* physical start address */
  109. };
  110.  
  111. /* VGA text type displays */
  112. #define ATAG_VIDEOTEXT 0x54410003
  113.  
  114. struct tag_videotext {
  115. u8 x;
  116. u8 y;
  117. u16 video_page;
  118. u8 video_mode;
  119. u8 video_cols;
  120. u16 video_ega_bx;
  121. u8 video_lines;
  122. u8 video_isvga;
  123. u16 video_points;
  124. };
  125.  
  126. /* describes how the ramdisk will be used in kernel */
  127. #define ATAG_RAMDISK 0x54410004
  128.  
  129. struct tag_ramdisk {
  130. u32 flags; /* bit 0 = load, bit 1 = prompt */
  131. u32 size; /* decompressed ramdisk size in _kilo_ bytes */
  132. u32 start; /* starting block of floppy-based RAM disk image */
  133. };
  134.  
  135. /* describes where the compressed ramdisk image lives (virtual address) */
  136. /*
  137. * this one accidentally used virtual addresses - as such,
  138. * its depreciated.
  139. */
  140. #define ATAG_INITRD 0x54410005
  141.  
  142. /* describes where the compressed ramdisk image lives (physical address) */
  143. #define ATAG_INITRD2 0x54420005
  144.  
  145. struct tag_initrd {
  146. u32 start; /* physical start address */
  147. u32 size; /* size of compressed ramdisk image in bytes */
  148. };
  149.  
  150. /* board serial number. "64 bits should be enough for everybody" */
  151. #define ATAG_SERIAL 0x54410006
  152.  
  153. struct tag_serialnr {
  154. u32 low;
  155. u32 high;
  156. };
  157.  
  158. /* board revision */
  159. #define ATAG_REVISION 0x54410007
  160.  
  161. struct tag_revision {
  162. u32 rev;
  163. };
  164.  
  165. /* initial values for vesafb-type framebuffers. see struct screen_info
  166. * in include/linux/tty.h
  167. */
  168. #define ATAG_VIDEOLFB 0x54410008
  169.  
  170. struct tag_videolfb {
  171. u16 lfb_width;
  172. u16 lfb_height;
  173. u16 lfb_depth;
  174. u16 lfb_linelength;
  175. u32 lfb_base;
  176. u32 lfb_size;
  177. u8 red_size;
  178. u8 red_pos;
  179. u8 green_size;
  180. u8 green_pos;
  181. u8 blue_size;
  182. u8 blue_pos;
  183. u8 rsvd_size;
  184. u8 rsvd_pos;
  185. };
  186.  
  187. /* command line: \0 terminated string */
  188. #define ATAG_CMDLINE 0x54410009
  189.  
  190. struct tag_cmdline {
  191. char cmdline[]; /* this is the minimum size */
  192. };
  193.  
  194. /* acorn RiscPC specific information */
  195. #define ATAG_ACORN 0x41000101
  196.  
  197. struct tag_acorn {
  198. u32 memc_control_reg;
  199. u32 vram_pages;
  200. u8 sounddefault;
  201. u8 adfsdrives;
  202. };
  203.  
  204. /* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */
  205. #define ATAG_MEMCLK 0x41000402
  206.  
  207. struct tag_memclk {
  208. u32 fmemclk;
  209. };
  210.  
  211. struct tag {
  212. struct tag_header hdr;
  213. union {
  214. struct tag_core core;
  215. struct tag_mem32 mem;
  216. struct tag_videotext videotext;
  217. struct tag_ramdisk ramdisk;
  218. struct tag_initrd initrd;
  219. struct tag_serialnr serialnr;
  220. struct tag_revision revision;
  221. struct tag_videolfb videolfb;
  222. struct tag_cmdline cmdline;
  223.  
  224. /*
  225. * Acorn specific
  226. */
  227. struct tag_acorn acorn;
  228.  
  229. /*
  230. * DC21285 specific
  231. */
  232. struct tag_memclk memclk;
  233. } u;
  234. };
  235.  
  236. struct tagtable {
  237. u32 tag;
  238. int (*parse)(const struct tag *);
  239. };
  240.  
  241. #define tag_member_present(tag,member) \
  242. ((unsigned long)(&((struct tag *)0L)->member + ) \
  243. <= (tag)->hdr.size * )
  244.  
  245. #define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))
  246. #define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
  247.  
  248. #define for_each_tag(t,base) \
  249. for (t = base; t->hdr.size; t = tag_next(t))
  250.  
  251. /*
  252. * Memory map description
  253. */
  254. #define NR_BANKS 8
  255.  
  256. struct meminfo {
  257. int nr_banks;
  258. unsigned long end;
  259. struct {
  260. unsigned long start;
  261. unsigned long size;
  262. int node;
  263. } bank[NR_BANKS];
  264. };
  265.  
  266. extern struct meminfo meminfo;
  267.  
  268. #endif

6.Makefile

  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 - -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

Linux学习 : 自己写bootloader的更多相关文章

  1. 【Linux学习】 写一个简单的Makefile编译源码获取当前系统时间

    打算学习一下Linux,这两天先看了一下gcc的简单用法以及makefile的写法,今天是周末,天气闷热超市,早晨突然发现住处的冰箱可以用了,于是先出去吃了点东西,然后去超市买了一坨冰棍,老冰棍居多, ...

  2. Linux 学习笔记

    Linux学习笔记 请切换web视图查看,表格比较大,方法:视图>>web板式视图 博客园不能粘贴图片吗 http://wenku.baidu.com/view/bda1c3067fd53 ...

  3. 【转】嵌入式Linux学习笔记

    一  嵌入式系统定义: 应用于特定环境的硬件体系. 二  两样非常重要的能力: 1.  掌握各种新概念的能力 2.  调试的能力( 包括软件, 硬件 ) 三  需要的基础知识: 1.  操作系统理论基 ...

  4. 实验楼 linux 学习

    实验楼 linux 学习     一.Linux 用户管理 1.查看用户 who am i // who mom likes whoami   ====--------====== 输入的第一列表示打 ...

  5. linux学习笔记2-linux的常用命令

    第一篇博客:linux学习笔记1-ubuntu的安装与基本设置 之中,已经介绍了如何安装linux操作系统,以及一些基本的设置修改. 本篇博客主要介绍linux中的一些常用的终端命令 ======== ...

  6. Linux学习历程(持续更新整理中)

    1.文件目录操作命令 (1) ls   显示文件和目录列表 a ls -l  显示文件的详细信息 b ls -a 列出当前目录的所有文件,包含隐藏文件. c stat '目录/文件'   显示指定目录 ...

  7. [转] Linux学习之CentOS(十三)--CentOS6.4下Mysql数据库的安装与配置

    from:  http://www.cnblogs.com/xiaoluo501395377/archive/2013/04/07/3003278.html 如果要在Linux上做j2ee开发,首先得 ...

  8. Linux学习之CentOS--CentOS6.4下Mysql数据库的安装与配置【转】

      如果要在Linux上做j2ee开发,首先得搭建好j2ee的开发环境,包括了jdk.tomcat.eclipse的安装(这个在之前的一篇随笔中已经有详细讲解了Linux学习之CentOS(七)--C ...

  9. Linux学习之CentOS(十三)--CentOS6.4下Mysql数据库的安装与配置

    原文:http://www.cnblogs.com/xiaoluo501395377/archive/2013/04/07/3003278.html 如果要在Linux上做j2ee开发,首先得搭建好j ...

  10. linux学习书籍推荐linux学习书籍推荐

    引用地址:http://www.cnblogs.com/notepi/archive/2013/06/15/3137103.html Linux 学习书目推荐 Linux基础 1.<Linux与 ...

随机推荐

  1. HTML 在安卓手机端软键盘弹出顶起页面布局的解决办法

    $('body').height($('body')[0].clientHeight); 以上是背景即BODY被顶起的解决办法. 如果是footer被顶起,则可以用判断解决, $('input').f ...

  2. 元素定义了position:fixed;后怎么居中

    div{ position:fixed; width:1200px; margin:0 auto; top:0; bottom:0; left:0; right:0; }

  3. Markdown学习和插件介绍

    markdown能干啥 亲们github上的项目首页的 内容+样式,都是项目中README.md文件控制的.将md风格的代码,转化成html. 而且markdown语法非常简单,5-10分钟即可学会! ...

  4. linux网卡混杂模式

    混杂模式就是接收所有经过网卡的数据包,包括不是发给本机的包,即不验证MAC地址.普通模式下网卡只接收发给本机的包(包括广播包)传递给上层程序,其它的包一律丢弃.一般来说,混杂模式不会影响网卡的正常工作 ...

  5. Android 四大组件之四(ContentProvider)

    ContentProvider调用关系: ContentProvider(数据提供者)是应用程序之间共享数据的一种接口机制,是一种更为高级的数据共享方法. ContentProvider可以指定需要共 ...

  6. PBS 安装

    How to install PBS Pro using the configure script. . Install the prerequisite packages for building ...

  7. R语言实战(一)介绍、数据集与图形初阶

    本文对应<R语言实战>前3章,因为里面大部分内容已经比较熟悉,所以在这里只是起一个索引的作用. 第1章       R语言介绍 获取帮助函数 help(), ? 查看函数帮助 exampl ...

  8. App开发三种模式

    APP开发三种模式 现在App开发的模式包含以下三种: Native App 原生开发AppWeb App 网页AppHybrid App 混合原生和Web技术开发的App 详细介绍: http:// ...

  9. 【转】Expire Google Drive Files 让Google Docs云盘共享连接在指定时间后自动失效

    最近在清理Google Docs中之前共享过的文件链接,发现Google Docs多人协作共享过的链接会一直存在,在实际操作中较不灵活.正好订阅的RSS推送了Pseric写的这篇文章 - Expire ...

  10. Sphinx Search 学习 (一)

    参考资料一:(中文)http://www.coreseek.cn/docs/coreseek_3.2-sphinx_0.9.9.html (官方)http://sphinxsearch.com/doc ...