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_android_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_,[email protected])" ] || 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 }
//结束