1.看看开发板的介绍
1 品牌: 天嵌 2 CPU型号: NXP i.MX6Q 3 架构: Cortex_A9 4 主频: 4*1GHz 5 内存: 2GB DDR3 6 存储: 8GB eMMC FLA(64GB可扩)
2. 看看相关的驱动。
| emmc/sdcard 驱动 |
drivers/mmc/host:sdhci-esdhc-imx.c
sdhci.c
sdhci-platform.c
sdhci-pltfm.c
|
/dev/mmcblk* |
| LCD 与 LVDS 驱动 | drivers/video/mxc/ldb.c
mxc_dispdrv.c
mxc_dvi.c
mxc_ipuv3_fb.c
mxc_lcdif.c
|
/dev/fb* |
| 电阻触摸屏驱动 | drivers/input/touchscreen/tsc2007.module | dev/input/event* |
| 电容式触摸屏驱动 | drivers/input/touchscreen/gt811.module | dev/input/event* |
| USB otg 驱动 | drivers/usb/otg/fsl_otg.c | |
| 有线网络驱动 | drivers/net/fec.module | eth0 |
| 串口驱动 |
drivers/tty/serial/imx.c
mxc_uart_early.c
serial_core.c
|
/dev/ttySAC* |
| sgtl5000声卡驱动 | sound/soc/imx/* | /dev/snd/* |
| I2C 驱动 | drivers/i2c/busses/i2c-imx.c | |
| 按键驱动 | drivers/input/keyboard/gpio_keys.c | dev/input/event* |
| 红外驱动 | drivers/input/keyboard/tq_hs0038.module | dev/input/event* |
| 背光灯驱动 | drivers/video/backlight/pwm_bl.c drivers/video/backlight/backlight.c | |
| pwm 驱动 | arch/arm/plat-mxc/pwm.c | |
| RTC 驱动 | drivers/rtc/rtc-pcf8563.c | /dev/rtc0 |
| 看门狗驱动 | drivers/watchdog/imx2_wdt.c | /dev/watchdog |
| 多媒体摄像头驱动 | drivers/media/video/mxc/capture/* | /dev/video* |
3. 下载信息,在淘宝上找到
| TQIMX6_android_V3.12.part01 | http://pan.baidu.com/s/1slA1doD 密码:vpad |
| TQIMX6_android_V3.12.part02 | http://pan.baidu.com/s/1mikSS1E 密码:cac7 |
| TQIMX6_android_V3.12.part03 | http://pan.baidu.com/s/1kVmqJKb 密码:x5yj |
| TQIMX6_android_V3.12.part04 | http://pan.baidu.com/s/1eR9RvRO 密码:vwra |
| TQIMX6_android_V3.12.part05 | http://pan.baidu.com/s/1hrIAHOK 密码:nhfe |
| TQIMX6_android_V3.12.part06 | http://pan.baidu.com/s/1gfLAL4R 密码:qyu6 |
| TQIMX6_android_V3.12.part07 | http://pan.baidu.com/s/1hsgXpwK 密码:l7h7 |
| TQIMX6_android_V3.12.part08 | http://pan.baidu.com/s/1dFniWmP 密码:bo8r |
| TQIMX6_android_V3.12.part09 | http://pan.baidu.com/s/1bo7p7f5 密码:nva2 |
| TQIMX6_adroid_V3.12.part10 | http://pan.baidu.com/s/1mhRqdQw 密码:hawo |
| Android镜像(6.0) | http://pan.baidu.com/s/1qXEWAxm 密码:pljv |
| Linux镜像(4.1) | http://pan.baidu.com/s/1dFpQUNv 密码:2b8l |
| Linux文件系统镜像.part1 | http://pan.baidu.com/s/1jHPYnBK 密码:3t0h |
| Linux文件系统镜像.part2 | http://pan.baidu.com/s/1bo9XzD9 密码:pgim |
| Linux平台工具 | http://pan.baidu.com/s/1miGGWPU 密码:5fhr |
| Linux资源 | http://pan.baidu.com/s/1skS1Oc9 密码:g1ud |
| Windows平台工具 | http://pan.baidu.com/s/1pLMG23x 密码:hihw |
| 配套电路图 | http://pan.baidu.com/s/1hsw6ulm 密码:92ym |
| 配套教材集 | https://pan.baidu.com/s/1nvQj4N3 密码:g9v7 |
| 配套芯片手册 | http://pan.baidu.com/s/1dEUSeL7 密码:sx1b |
| TQIMX6Q(V3) QT5.5开发境搭建 | http://pan.baidu.com/s/1i4Q3hTb 密码:vh9f |
| Qt快速入门攻略 | http://www.armbbs.net/forum.php?mod=viewthread&tid=21338&extra= |
4. 看下uboot的源码,根据手册是
1 ./build_sh 编译
5. 是的,你比较厉害,-j8用8个线程去编译。
1 export ARCH=arm 2 export CROSS_COMPILE=arm-linux- 3 make mx6q_sabresd_android_config 4 make -j8
6. 找到mx6q_sabresd_android_config,没搞明白,2个make可以放在一起?打开IMX6_CoreC_CD\Linux 源码包\uboot源码\uboot_IMX6_CoreC_1.3.4_for_Linux\Makefile
1 mx6q_sabresd_config \
2 mx6q_sabresd_android_config \
3 mx6q_sabresd_mfg_config \
4 mx6q_sabresd_iram_config : unconfig
5 @[ -z "$(findstring iram_,$@)" ] || \
6 { echo "TEXT_BASE = 0x00907000" >$(obj)board/freescale/mx6q_sabresd/config.tmp ; \
7 echo "... with iram configuration" ; \
8 }
9 @$(MKCONFIG) $(@:_config=) arm arm_cortexa8 mx6q_sabresd freescale mx6
7. 上面的几个参数,arm是构架 arm_cortexa8是CPU型号 mx6q_sabresd是板子的型号 freescale mx6
8. 找到链接文件uboot_IMX6_CoreC_1.3.4_for_Linux\board\freescale\mx6q_sabresd\u-boot.lds
1 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
2 OUTPUT_ARCH(arm)
3 ENTRY(_start)
4 SECTIONS
5 {
6 . = 0x00000000; //放置的起始位置
7
8 . = ALIGN(4); //4字节对齐
9 .text : //代码段
10 {
11 /* WARNING - the following is hand-optimized to fit within */
12 /* the sector layout of our flash chips! XXX FIXME XXX */
13 board/freescale/mx6q_sabresd/flash_header.module (.text.flasheader) //天嵌定制?
14 cpu/arm_cortexa8/start.o //启动文件
15 board/freescale/mx6q_sabresd/libmx6q_sabresd.a (.text)
16 lib_arm/libarm.a (.text)
17 net/libnet.a (.text)
18 drivers/mtd/libmtd.a (.text)
19 drivers/mmc/libmmc.a (.text)
20
21 . = DEFINED(env_offset) ? env_offset : .;
22 common/env_embedded.o(.text)
23
24 *(.text)
25 }
26
27 . = ALIGN(4); //只读数据段,ROM
28 .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
29
30 . = ALIGN(4); //数据段
31 .data : { *(.data) }
32
33 . = ALIGN(4);
34 .got : { *(.got) }
35
36 . = .;
37 __u_boot_cmd_start = .;
38 .u_boot_cmd : { *(.u_boot_cmd) }
39 __u_boot_cmd_end = .;
40
41 . = ALIGN(4);
42 _end_of_copy = .; /* end_of ROM copy code here */
43
44 /* Extend to align to 0x1000, then put the Hab Data */
45 . = ALIGN(0x1000);
46 __hab_data = .;
47 . = . + 0x2000;
48 __data_enc_key = .;
49 /* actually, only 64bytes are needed, but this generates
50 a size multiple of 512bytes, which is optimal for SD boot */
51 . = . + 0x200;
52 __hab_data_end = .;
53 /* End of Hab Data, Place it before BSS section */
54
55 __bss_start = .;
56 .bss : { *(.bss) }
57 _end = .;
58 }
9. 第一行,这个不清楚是啥,天嵌定制的?
board/freescale/mx6q_sabresd/flash_header.module (.text.flasheader)
10.第2个链接的文件是start.c
#include <config.h>
#include <version.h>
.globl _start //定义一个全局可见的变量
_start: b reset //问题,哪里算是_start的结束?下一个冒号的位置
ldr pc, _undefined_instruction //未定义指令
ldr pc, _software_interrupt //软件中断向量
ldr pc, _prefetch_abort //预取指令中断向量
ldr pc, _data_abort//数据操作异常向量
ldr pc, _not_used /、未使用
ldr pc, _irq//慢速中断向量
ldr pc, _fiq//快速中断向量
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
_pad: .word 0x12345678 /* now 16*4=64 */
.global _end_vect
_end_vect:
11. 上面的.wordirq说是是什么意思,点是什么意思?加点的是伪指令,不会被编译的,理解如下.word是一个汇编伪指令,表示是一个字节,.word是伪操作,用于分配一小段字内存单元
1 _software_interrupt: .word software_interrupt //_software_interrupt = software_interrupt
12. 下面是reset的代码
1 reset: 2 /* 3 * set the cpu to SVC32 mode 4 *//ARM有7种模式,SVC是特权模式,可以访问所有寄存器 5 mrs r0, cpsr 6 bic r0, r0, #0x1f 7 orr r0, r0, #0xd3 8 msr cpsr,r0 33 /* the mask ROM code should have PLL and others stable */ 34 #ifndef CONFIG_SKIP_LOWLEVEL_INIT 35 bl cpu_init_crit 36 #endif
13.首先会将CPU的工作模式设置为svc32模式,然后便调用 cpu_init_crit ,需要注意的是,这里使用的是 bl 指令,也就是说在运行完 cpu_init_crit 标号处的代码之后,会通过这个指令返回来
1 mov pc, lr @ back to my caller
14. 跳转到cpu_init_crit
1 cpu_init_crit: 2 /* 3 * Invalidate L1 I/D 4 */ 5 mov r0, #0 @ set up for MCR 6 mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs 7 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache 8 9 /* 10 * disable MMU stuff and caches 11 */ 12 mrc p15, 0, r0, c1, c0, 0 13 bic r0, r0, #0x00002000 @ clear bits 13 (--V-) 14 bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) 15 orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align 16 orr r0, r0, #0x00000800 @ set bit 12 (Z---) BTB 17 mcr p15, 0, r0, c1, c0, 0 18 19 /* 20 * Jump to board specific initialization... 21 * The Mask ROM will have already initialized 22 * basic memory. Go here to bump up clock rate and handle 23 * wake up conditions. 24 */ 25 mov ip, lr @ persevere link reg across call 26 bl lowlevel_init @ go setup pll,mux,memory 27 mov lr, ip @ restore link 28 mov pc, lr @ back to my caller
15.找到lowlevel_init这个函数,E:\arm_a\IMX6_CoreC_CD\Linux 源码包\uboot源码\uboot_IMX6_CoreC_1.3.4_for_Linux\board\freescale\mx6q_sabresd\lowlevel_init.S
1 .globl lowlevel_init 2 lowlevel_init: 3 inv_dcache 4 init_l2cc 5 init_aips 6 init_clock 7 mov pc, lr
16. 接下来一个尴尬的问题,不知道程序接下来往哪里走了!!假设汇编代码是顺序执行的,那么接下来是relocate
1 relocate: @ relocate U-Boot to RAM
2 adr r0, _start @ r0 <- current position of code
3 ldr r1, _TEXT_BASE @ test if we run from flash or RAM
4 cmp r0, r1 @ don't reloc during debug
5 beq stack_setup
6
7 ldr r2, _armboot_start
8 ldr r3, _bss_start
9 sub r2, r3, r2 @ r2 <- size of armboot
10 add r2, r0, r2 @ r2 <- source end address
11
12 copy_loop: @ copy 32 bytes at a time
13 ldmia r0!, {r3 - r10} @ copy from source address [r0]
14 stmia r1!, {r3 - r10} @ copy to target address [r1]
15 cmp r0, r2 @ until source end addreee [r2]
16 ble copy_loop
17 #endif /* CONFIG_SKIP_RELOCATE_UBOOT */
18
19 /* Set up the stack */
20 stack_setup:
21 ldr r0, _TEXT_BASE @ upper 128 KiB: relocated uboot
22 sub r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area
23 sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo
24 #ifdef CONFIG_USE_IRQ
25 sub r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ)
26 #endif
27 sub sp, r0, #12 @ leave 3 words for abort-stack
28 and sp, sp, #~7 @ 8 byte alinged for (ldr/str)d
29
30 /* Clear BSS (if any). Is below tx (watch load addr - need space) */
31 clear_bss:
32 ldr r0, _bss_start @ find start of bss segment
33 ldr r1, _bss_end @ stop here
34 mov r2, #0x00000000 @ clear value
35 clbss_l:
36 str r2, [r0] @ clear BSS location
37 cmp r0, r1 @ are we at the end yet
38 add r0, r0, #4 @ increment clear index pointer
39 bne clbss_l @ keep clearing till at end
40
41 #ifdef CONFIG_ARCH_MMU
42 bl board_mmu_init
43 #endif
44 ldr pc, _start_armboot @ jump to C code
45
46 _start_armboot: .word start_armboot
17. 跳入到C语言函数中start_armboot,但是这个函数在哪里?还好在书中找到了答案。uboot_IMX6_CoreC_1.3.4_for_Linux\lib_arm\board.c
1 void start_armboot (void)
2 {
3 init_fnc_t **init_fnc_ptr;
4 char *s;
5 #if defined(CONFIG_VFD) || defined(CONFIG_LCD)
6 unsigned long addr;
7 #endif
8
9 /* Pointer is writable since we allocated a register for it */
10 gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));
11 /* compiler optimization barrier needed for GCC >= 3.4 */
12 __asm__ __volatile__("": : :"memory");
13
14 memset ((void*)gd, 0, sizeof (gd_t));
15 gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
16 memset (gd->bd, 0, sizeof (bd_t));
17
18 gd->flags |= GD_FLG_RELOC;
19
20 monitor_flash_len = _bss_start - _armboot_start;
21
22 for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
23 if ((*init_fnc_ptr)() != 0) {
24 hang ();
25 }
26 }
27
28 /* armboot_start is defined in the board-specific linker script */
29 mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN);
30
31 #ifndef CONFIG_SYS_NO_FLASH
32 /* configure available FLASH banks */
33 display_flash_config (flash_init ());
34 #endif /* CONFIG_SYS_NO_FLASH */
35
36 #ifdef CONFIG_VFD
37 # ifndef PAGE_SIZE
38 # define PAGE_SIZE 4096
39 # endif
40 /*
41 * reserve memory for VFD display (always full pages)
42 */
43 /* bss_end is defined in the board-specific linker script */
44 addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
45 vfd_setmem (addr);
46 gd->fb_base = addr;
47 #endif /* CONFIG_VFD */
48
49 #ifdef CONFIG_LCD
50 /* board init may have inited fb_base */
51 if (!gd->fb_base) {
52 # ifndef PAGE_SIZE
53 # define PAGE_SIZE 4096
54 # endif
55 /*
56 * reserve memory for LCD display (always full pages)
57 */
58 /* bss_end is defined in the board-specific linker script */
59 addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
60 lcd_setmem (addr);
61 gd->fb_base = addr;
62 }
63 #endif /* CONFIG_LCD */
64
65 #if defined(CONFIG_CMD_NAND)
66 puts ("NAND: ");
67 nand_init(); /* go init the NAND */
68 #endif
69
70 #if defined(CONFIG_CMD_ONENAND)
71 onenand_init();
72 #endif
73
74 #ifdef CONFIG_HAS_DATAFLASH
75 AT91F_DataflashInit();
76 dataflash_print_info();
77 #endif
78
79 #ifdef CONFIG_GENERIC_MMC
80 #ifndef CONFIG_DIS_BOARD_INFO
81 puts ("MMC: ");
82 #endif
83 mmc_initialize (gd->bd);
84 #endif
85
86 /* initialize environment */
87 env_relocate ();
88
89 #ifdef CONFIG_VFD
90 /* must do this after the framebuffer is allocated */
91 drv_vfd_init();
92 #endif /* CONFIG_VFD */
93
94 #ifdef CONFIG_SERIAL_MULTI
95 serial_initialize();
96 #endif
97
98 /* IP Address */
99 gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
100
101 #if defined CONFIG_SPLASH_SCREEN && defined CONFIG_VIDEO_MX5
102 setup_splash_image();
103 #endif
104
105 stdio_init (); /* get the devices list going. */
106
107 jumptable_init ();
108
109 #if defined(CONFIG_API)
110 /* Initialize API */
111 api_init ();
112 #endif
113
114 console_init_r (); /* fully init console as a device */
115
116 #if defined(CONFIG_ARCH_MISC_INIT)
117 /* miscellaneous arch dependent initialisations */
118 arch_misc_init ();
119 #endif
120 #if defined(CONFIG_MISC_INIT_R)
121 /* miscellaneous platform dependent initialisations */
122 misc_init_r ();
123 #endif
124
125 /* enable exceptions */
126 enable_interrupts ();
127
128 /* Perform network card initialisation if necessary */
129 #ifdef CONFIG_DRIVER_TI_EMAC
130 /* XXX: this needs to be moved to board init */
131 extern void davinci_eth_set_mac_addr (const u_int8_t *addr);
132 if (getenv ("ethaddr")) {
133 uchar enetaddr[6];
134 eth_getenv_enetaddr("ethaddr", enetaddr);
135 davinci_eth_set_mac_addr(enetaddr);
136 }
137 #endif
138
139 #ifdef CONFIG_DRIVER_CS8900
140 /* XXX: this needs to be moved to board init */
141 cs8900_get_enetaddr ();
142 #endif
143
144 #if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)
145 /* XXX: this needs to be moved to board init */
146 if (getenv ("ethaddr")) {
147 uchar enetaddr[6];
148 eth_getenv_enetaddr("ethaddr", enetaddr);
149 smc_set_mac_addr(enetaddr);
150 }
151 #endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */
152
153 #if defined(CONFIG_ENC28J60_ETH) && !defined(CONFIG_ETHADDR)
154 extern void enc_set_mac_addr (void);
155 enc_set_mac_addr ();
156 #endif /* CONFIG_ENC28J60_ETH && !CONFIG_ETHADDR*/
157
158 /* Initialize from environment */
159 if ((s = getenv ("loadaddr")) != NULL) {
160 load_addr = simple_strtoul (s, NULL, 16);
161 }
162 #if defined(CONFIG_CMD_NET)
163 if ((s = getenv ("bootfile")) != NULL) {
164 copy_filename (BootFile, s, sizeof (BootFile));
165 }
166 #endif
167
168 #ifdef BOARD_LATE_INIT
169 board_late_init ();
170 #endif
171
172 #ifdef CONFIG_ANDROID_RECOVERY
173 check_recovery_mode();
174 #endif
175
176 #if defined(CONFIG_CMD_NET)
177 #if defined(CONFIG_NET_MULTI)
178 #ifndef CONFIG_DIS_BOARD_INFO
179 puts ("Net: ");
180 #endif
181 #endif
182 eth_initialize(gd->bd);
183 #if defined(CONFIG_RESET_PHY_R)
184 debug ("Reset Ethernet PHY\n");
185 reset_phy();
186 #endif
187 #endif
188 #ifdef CONFIG_FASTBOOT
189 check_fastboot_mode();
190 #endif
191 /* main_loop() can return to retry autoboot, if so just run it again. */
192 for (;;) {
193 main_loop ();
194 }
195
196 /* NOTREACHED - no way out of command loop except booting */
197 } //结束