本项目以freescale最新开发板mx6q_sabresd(CPU为Cortex-A9)为基础进行系统开发。新板中DDR3及网络芯片等主要设备接口等基本与开发板设计类似,新增了FPGA连接到ARM上,更改了串口等。本文主要记录串口的更改,导致系统移植过程中,源代码的修改问题。开发板上使用是串口1,项目新板改为串口2。
系统移植包括uboot、kernel及rootfs的移植。串口更改共4个部分:
1. uboot启动打印及操作台通信串口;
2. 内核解压信息输出打印串口;
3. 内核调试串口;
4. 文件系统操作台终端串口。
下面具体介绍各部分更改的位置,抛砖引玉,以供有类似需求的朋友参考自己项目中需要做的修改。
uboot中需要更改两处串口设置,分别在板级文件mx6q_sabresd.c和uboot启动配置文件configs中。
文件u-boot-2009.08\board\freescale\mx6q_sabresd\mx6q_sabresd.c中主要集中了u-boot针对板子复用管脚功能设置的修改,该文件主要对板级外设做初始化工作。
289: //mxc_iomux_v3_setup_pad(MX6Q_PAD_CSI0_DAT10__UART1_TXD);
293: //mxc_iomux_v3_setup_pad(MX6Q_PAD_CSI0_DAT11__UART1_RXD);
改为:
mxc_iomux_v3_setup_pad(MX6Q_PAD_GPIO_7__UART2_TXD);
mxc_iomux_v3_setup_pad(MX6Q_PAD_GPIO_8__UART2_RXD);
文件u-boot-2009.08\include\configs中主要是uboot启动配置,uboot启动信息打印串口的选择就在此文件配置。
67://#defineCONFIG_UART_BASE_ADDR UART1_BASE_ADDR
改为:
#defineCONFIG_UART_BASE_ADDR UART2_BASE_ADDR
该句配置串口寄存器基址,在基址宏定义在include/asm/arch/mx6.h文件中。
72://#define CONFIG_CONS_INDEX 1
改为:
#define CONFIG_CONS_INDEX 2
此句指定使用的串口索引号。
118:下面第7行配置操作台信息回传递到内核中(此处包含ttymxc0)。
#define CONFIG_EXTRA_ENV_SETTINGS \
"netdev=eth0\0" \
"ethprime=FEC0\0" \
"uboot=u-boot.bin\0" \
"kernel=uImage\0" \
"nfsroot=/opt/eldk/arm\0" \
"bootargs_base=setenvbootargs console=ttymxc1,115200\0"\ "bootargs_nfs=setenvbootargs ${bootargs} root=/dev/nfs "\
"ip=dhcpnfsroot=${serverip}:${nfsroot},v3,tcp\0"\
"bootcmd_net=runbootargs_base bootargs_nfs; " \
"tftpboot${loadaddr} ${kernel}; bootm\0" \
"bootargs_mmc=setenvbootargs ${bootargs} ip=dhcp " \
"root=/dev/mmcblk0p1rootwait\0" \
"bootcmd_mmc=runbootargs_base bootargs_mmc; " \
"mmcdev 3; " \
"mmcread ${loadaddr} 0x800 0x2000; bootm\0" \
"bootcmd=runbootcmd_net\0"
内核解压缩信息打印使用的串口定义在linux内核源码程序中,/arch/arm/plat_mxc/include/mach/uncompress.h文件下。
//#defineUCR1_UARTEN 1
改为:
#defineUCR1_UARTEN 2
由于设备管脚的变更,需要在kernel源文件中修改相应管脚功能。该部分设置在文件<linux source code directory>/arch/arm/mach-mx6/board-mx6q_sabresd.c及头文件<linux source code directory>/arch/arm/mach-mx6/board-mx6q_sabresd.h中。其中在前者中修改串口添加代码:
236 //imx6q_add_imx_uart(2, NULL);
//imx6q_add_imx_uart(0,NULL);
imx6q_add_imx_uart(1,NULL);
1684 //early_console_setup(UART1_BASE_ADDR,uart_clk);
early_console_setup(UART2_BASE_ADDR, uart_clk);
复用管脚的功能设定在该头文件中。例如:board-mx6q_sabresd.h
/* UART2 , DEBUG */
MX6Q_PAD_GPIO_7__UART2_TXD,
MX6Q_PAD_GPIO_8__UART2_RXD,
其他相关参考文件有:
linux/arch/arm/plat-mxc/include/mach/iomux-mx6x.h
linux/arch/arm/mach-mx6/board-mx6x_<referenceboardname>.h
通常,linux内核的启动可以分为两个阶段。
第一阶段,完成硬件检测、初始化和内核的引导。此阶段,系统按照BIOS中设置的启动设备启动,接着利用Lilo/Grub程序来进行内核的引导工作,内核被解压并装入内存后,开始初试化硬件和设备驱动程序。
第二阶段,开始执行init初始化进行。init进程,是一个由内核启动的用户进程,也是系统上运行的所有其他进程的父进程,创建并监听其他子进程,并在需要的时候启动、停止、重启子进程,主要用来完成系统的各项配置。init创建进程的信息从/etc/inittab获取。init程序通常放在/sbin或/bin下。因此,文件系统的登录终端就有inittab这个文件里的信息决定。
系统第一个进程init的配置文件inittab内容如下:
#see busybox-1.00rc2/examples/inittab formore examples
::sysinit:/etc/rc.d/rcS
::respawn:/sbin/getty –L ttymxc1 115200vt100
::ctrlaltdel:/sbin/reboot
::shutdown:/etc/rc.d/rcS stop
::restart:/sbin/init
其中第二句命令中终端名ttymxc*修改成对应的接口。本项目中系统信息输出由串口2操作台输出,将之确定为ttymxc1,方可通信。
一个串口贯穿整个系统移植,很费力,但对初学者来说各处依次深究一下会了解不少东西。不过本人至今还有很多没有弄太明白,比如uboot之前是不是都有一段程序,那个程序是否需要开发人员了解等等。总之,不断学习,总结,希望对其他人有用!