author:tianming1992
E-mail: [email protected]
採用QNX7.0和sabreARD BSP,主要工作在於製作bootloader。
1.IPL製作
IPL時QNX特有的bootloader,類似於u-boot。
mx6x BSP的IPL代碼位於src/ipl/boards/mx6x-sabreARD目錄下,觀察其main函數,基本可以理解爲一個裸奔的單片機程序,作用是初始化串口,SD卡,比通過讀取SD卡文件,將系統鏡像讀入內存中,並最終將控制權交給鏡像的start-up模塊。
int main()
{
unsigned image = QNX_LOAD_ADDR;
init_aips();
init_clocks();
init_regulator_settings();
if ( get_imx6_type() == MX6_CHIP_TYPE_QUAD_OR_DUAL)
{
if ( get_imx6_rev() == MX6_CHIP_REV_2_0 )
{
//DDR配置相關
apply_mx6_sdl_dcd_values((unsigned long) &dcd_hdr_quadplus);
}
else
{
apply_mx6_sdl_dcd_values((unsigned long) &dcd_hdr_quad);
}
//pin mux set!! 引腳配置
init_pinmux_quad_dual();
}
else if (get_imx6_type() == MX6_CHIP_TYPE_DUAL_LITE_OR_SOLO)
{
apply_mx6_sdl_dcd_values((unsigned long) &dcd_hdr_solo);
init_pinmux_dual_lite_solo();
}
else
{
apply_mx6_sdl_dcd_values((unsigned long) &dcd_hdr_quad);
init_pinmux_quad_dual();
}
/* Init serial interface 串口配置*/
init_serial_mx6x();
ser_putstr("\nQNX Neutrino Initial Program Loader for the NXP i.MX6 Quad/Dual/DualLite/Solo/QuadPlus Sabre-ARD RevB (ARM Cortex-A9 MPCore)\n");
ser_putstr("BeiJing Leadgen.AI\n");
if ( get_imx6_type() == MX6_CHIP_TYPE_QUAD_OR_DUAL)
{
if ( get_imx6_rev() == MX6_CHIP_REV_2_0)
{
ser_putstr("\ni.MX6 Quad Plus CPU detected.\n\n");
}
else
{
ser_putstr("\ni.MX6 Quad or Dual CPU detected.\n\n");
}
}
else if (get_imx6_type() == MX6_CHIP_TYPE_DUAL_LITE_OR_SOLO)
{
ser_putstr("\ni.MX6 Dual Lite or Solo CPU detected.\n\n");
}
else
{
ser_putstr("\ni.MX6 unknown CPU type.\n\n");
ser_putstr("CHIP ID = ");
ser_puthex(get_imx6_type());
}
ser_putstr("SDMMC download...\n");
if (sdmmc_load_file(image, "QNX-IFS") == 0) {
ser_putstr("load image done.\n");
/* Proceed to image scan */
image = image_scan(image, image + 0x200);
if (image != 0xffffffff) {
ser_putstr("Found image @ 0x");
ser_puthex(image);
ser_putstr("\n");
image_setup(image);
ser_putstr("Jumping to startup @ 0x");
ser_puthex(startup_hdr.startup_vaddr);
ser_putstr("\n\n");
image_start(image);
/* Never reach here */
return 0;
}
}
while (1) {
ser_putstr("Command:\n");
ser_putstr("Press 'D' for serial download, using the 'sendnto' utility\n");
ser_putstr("Press 'M' for SDMMC download, IFS filename MUST be 'QNX-IFS'.\n");
switch (ser_getchar()) {
case 'D':
case 'd':
ser_putstr("send image now...\n");
if (image_download_ser(image)) {
ser_putstr("download failed...\n");
continue;
}
else
ser_putstr("download OK...\n");
break;
case 'M':
case 'm':
ser_putstr("SDMMC download...\n");
if (sdmmc_load_file(image, "QNX-IFS") == 0) {
ser_putstr("load image done.\n");
/* Proceed to image scan */
break;
}
else
{
ser_putstr("Load image failed.\n");
continue;
}
default:
ser_putstr("Unknown command.\n");
continue;
}
image = image_scan(image, image + 0x200);
if (image != 0xffffffff) {
ser_putstr("Found image @ 0x");
ser_puthex(image);
ser_putstr("\n");
image_setup(image);
ser_putstr("Jumping to startup @ 0x");
ser_puthex(startup_hdr.startup_vaddr);
ser_putstr("\n\n");
image_start(image);
/* Never reach here */
return 0;
}
ser_putstr("Image_scan failed...\n");
}
return 0;
}
對於IPL移植,最重要的在引腳配置部分,根據TQIMX6Q原理圖,修改如下
init_pinmux_quad_dual()
{
//tqimx6 -----uart1-------------------------
//tx
set_mux_cfg(SWMUX_SD3_DAT7, MUX_CTL_MUX_MODE_ALT1);
set_pad_cfg(SWPAD_SD3_DAT7, MX6Q_PAD_SETTINGS_UART);
set_pin_as_input(SWINPUT_UART1_IPP_UART_RXD_MUX, 0x02);
//RX
set_mux_cfg(SWMUX_SD3_DAT6, MUX_CTL_MUX_MODE_ALT1);
set_pad_cfg(SWPAD_SD3_DAT6, MX6Q_PAD_SETTINGS_UART);
set_pin_as_input(SWINPUT_UART1_IPP_UART_RXD_MUX, 0x03);
//cts
set_mux_cfg(SWMUX_EIM_D19, MUX_CTL_MUX_MODE_ALT4);
set_pad_cfg(SWPAD_EIM_D19, MX6Q_PAD_SETTINGS_UART);
set_pin_as_input(SWINPUT_UART1_IPP_UART_RTS_B, 0x00);
//rts
set_mux_cfg(SWMUX_EIM_D20, MUX_CTL_MUX_MODE_ALT4);
set_pad_cfg(SWPAD_EIM_D20, MX6Q_PAD_SETTINGS_UART);
set_pin_as_input(SWINPUT_UART1_IPP_UART_RTS_B, 0x01);
}
/* SD2 CLK */
set_mux_cfg(SWMUX_SD2_CLK, MUX_CTL_MUX_MODE_ALT0);
set_pad_cfg(SWPAD_SD2_CLK, MX6Q_PAD_SETTINGS_USDHC);
/* SD1 CMD */
set_mux_cfg(SWMUX_SD2_CMD, MUX_CTL_MUX_MODE_ALT0 | MUX_CTL_SION);
set_pad_cfg(SWPAD_SD2_CMD, MX6Q_PAD_SETTINGS_USDHC);
/* SD1 DAT0 */
set_mux_cfg(SWMUX_SD2_DAT0, MUX_CTL_MUX_MODE_ALT0);
set_pad_cfg(SWPAD_SD2_DAT0, MX6Q_PAD_SETTINGS_USDHC);
/* SD1 DAT1 */
set_mux_cfg(SWMUX_SD2_DAT1, MUX_CTL_MUX_MODE_ALT0);
set_pad_cfg(SWPAD_SD2_DAT1, MX6Q_PAD_SETTINGS_USDHC);
/* SD1 DAT2 */
set_mux_cfg(SWMUX_SD2_DAT2, MUX_CTL_MUX_MODE_ALT0);
set_pad_cfg(SWPAD_SD2_DAT2, MX6Q_PAD_SETTINGS_USDHC);
/* SD1 DAT3 */
set_mux_cfg(SWMUX_SD2_DAT3, MUX_CTL_MUX_MODE_ALT0);
set_pad_cfg(SWPAD_SD2_DAT3, MX6Q_PAD_SETTINGS_USDHC);
/* SD2 Card Detect - configure GPIO4[1] as an input */
set_mux_cfg(SWMUX_GPIO_4, MUX_CTL_MUX_MODE_ALT5);
out32(MX6X_GPIO4_BASE + MX6X_GPIO_GDIR, in32(MX6X_GPIO4_BASE + MX6X_GPIO_GDIR) & ~(1<<1));
/* SD2 Write Protect - configure GPIO5[20] as an input */
set_mux_cfg(SWMUX_GPIO_2, MUX_CTL_MUX_MODE_ALT5);
out32(MX6X_GPIO2_BASE + MX6X_GPIO_GDIR, in32(MX6X_GPIO2_BASE + MX6X_GPIO_GDIR) & ~(1<<20));
此外,串口配置的宏也要更改
#define MXC_CONSOLE_BASE MX6X_UART1_BASE
SD卡部分類似。
2.SD卡燒寫
這個部分都是通用的,製作一張FAT32的活動主分區SD卡,利用
sudo dd if=ipl-mx6q-sabresmart.bin of=/dev/sdd bs=512 seek=2
skip=2
將IPL寫入SD中即可。
3.其他坑
在前面改IPL源碼的時候,發現不管怎麼改,最終生成的IPL竟然時一樣的,最終發現這個BSP根目錄下的makefile竟然遺漏了make install,如下:
install: $(if $(wildcard prebuilt/*),prebuilt)
$(MAKE) -Csrc hinstall
$(MAKE) -Csrc
增加install後,總算正常了:
install: $(if $(wildcard prebuilt/*),prebuilt)
$(MAKE) -Csrc hinstall
$(MAKE) -Csrc install
結結實實被QNX工程師坑了一把。