zoukankan      html  css  js  c++  java
  • AM335x(TQ335x)学习笔记——u-boot-2014.10移植

    根据最近移植u-boot-2014.10至TQ335x,基于这样的假设am335x evm移植。不是很多地方需要改变。

    因为TI的am335x evm开发了使用eeprom船上保存配置信息。它使用不同类型的电路板来区分,和TQ335x如果没有这个eeprom。因此。须要改动eeprom相关的部分,使u-boot适应TQ335x开发板。

    使用source insight查看代码,非常easy发现,全部获取板载配置的部分都是通过读取eeprom获得的,因此,首选改动read_eeprom(board/ti/am335x/board.c)函数。详细的改动例如以下:

    static int read_eeprom(struct am335x_baseboard_id *header)
    {
    #if 1
    	strcpy(header->name, "TQ335x");
    #else
    	/* Check if baseboard eeprom is available */
    	if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) {
    		puts("Could not probe the EEPROM; something fundamentally "
    			"wrong on the I2C bus.
    ");
    		return -ENODEV;
    	}
    
    	/* read the eeprom using i2c */
    	if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 2, (uchar *)header,
    		     sizeof(struct am335x_baseboard_id))) {
    		puts("Could not read the EEPROM; something fundamentally"
    			" wrong on the I2C bus.
    ");
    		return -EIO;
    	}
    
    	if (header->magic != 0xEE3355AA) {
    		/*
    		 * read the eeprom using i2c again,
    		 * but use only a 1 byte address
    		 */
    		if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 1, (uchar *)header,
    			     sizeof(struct am335x_baseboard_id))) {
    			puts("Could not read the EEPROM; something "
    				"fundamentally wrong on the I2C bus.
    ");
    			return -EIO;
    		}
    
    		if (header->magic != 0xEE3355AA) {
    			printf("Incorrect magic number (0x%x) in EEPROM
    ",
    					header->magic);
    			return -EINVAL;
    		}
    	}
    #endif
    
    	return 0;
    }
    通过上述改动,u-boot不去读取eeprom,而是直接将header的name赋值为"TQ335x",后面能够依据这一配置区分是否为TQ335x开发板。

    然后是改动get_dpll_ddr_params(board/ti/am335x/board.c)函数,详细的改动内容例如以下:

    const struct dpll_params *get_dpll_ddr_params(void)
    {
    	struct am335x_baseboard_id header;
    
    	enable_i2c0_pin_mux();
    	i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
    	if (read_eeprom(&header) < 0)
    		puts("Could not get board ID.
    ");
    
    	if (board_is_tq335x(&header) || board_is_evm_sk(&header))
    		return &dpll_ddr_evm_sk;
    	else if (board_is_bone_lt(&header))
    		return &dpll_ddr_bone_black;
    	else if (board_is_evm_15_or_later(&header))
    		return &dpll_ddr_evm_sk;
    	else
    		return &dpll_ddr;
    }
    然后是改动sdram_init(board/ti/am335x/board.c)函数,详细的改动内容例如以下:
    void sdram_init(void)
    {
    	__maybe_unused struct am335x_baseboard_id header;
    
    	if (read_eeprom(&header) < 0)
    		puts("Could not get board ID.
    ");
    
    	if (board_is_evm_sk(&header)) {
    		/*
    		 * EVM SK 1.2A and later use gpio0_7 to enable DDR3.
    		 * This is safe enough to do on older revs.
    		 */
    		gpio_request(GPIO_DDR_VTT_EN, "ddr_vtt_en");
    		gpio_direction_output(GPIO_DDR_VTT_EN, 1);
    	}
    
    	if (board_is_evm_sk(&header) || board_is_tq335x(&header))
    		config_ddr(303, &ioregs_evmsk, &ddr3_data,
    			   &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);
    	else if (board_is_bone_lt(&header))
    		config_ddr(400, &ioregs_bonelt,
    			   &ddr3_beagleblack_data,
    			   &ddr3_beagleblack_cmd_ctrl_data,
    			   &ddr3_beagleblack_emif_reg_data, 0);
    	else if (board_is_evm_15_or_later(&header))
    		config_ddr(303, &ioregs_evm15, &ddr3_evm_data,
    			   &ddr3_evm_cmd_ctrl_data, &ddr3_evm_emif_reg_data, 0);
    	else
    		config_ddr(266, &ioregs, &ddr2_data,
    			   &ddr2_cmd_ctrl_data, &ddr2_emif_reg_data, 0);
    }
    然后加入board_is_tq335x函数的详细实现,參考其他类似函数实现就可以,因为我们的read_eeprom仅读到了name,其内容是"TQ335x",故可例如以下实现。在board/ti/am335x/board.h中加入例如以下内容:
    static inline int board_is_tq335x(struct am335x_baseboard_id *header)
    {
    	return !strncmp(header->name, "TQ335x", HDR_NAME_LEN);
    }
    最后是改动enable_board_pin_mux(board/ti/am335x/mux.c)函数,详细的改动内容例如以下:
    void enable_board_pin_mux(struct am335x_baseboard_id *header)
    {
    	/* Do board-specific muxes. */
    	if (board_is_bone(header) || board_is_tq335x(header)) {
    		/* Beaglebone pinmux */
    		configure_module_pin_mux(i2c1_pin_mux);
    		configure_module_pin_mux(mii1_pin_mux);
    		configure_module_pin_mux(mmc0_pin_mux);
    #if defined(CONFIG_NAND)
    		configure_module_pin_mux(nand_pin_mux);
    #elif defined(CONFIG_NOR)
    		configure_module_pin_mux(bone_norcape_pin_mux);
    #else
    		configure_module_pin_mux(mmc1_pin_mux);
    #endif
    	} else if (board_is_gp_evm(header)) {
    		/* General Purpose EVM */
    		unsigned short profile = detect_daughter_board_profile();
    		configure_module_pin_mux(rgmii1_pin_mux);
    		configure_module_pin_mux(mmc0_pin_mux);
    		/* In profile #2 i2c1 and spi0 conflict. */
    		if (profile & ~PROFILE_2)
    			configure_module_pin_mux(i2c1_pin_mux);
    		/* Profiles 2 & 3 don't have NAND */
    #ifdef CONFIG_NAND
    		if (profile & ~(PROFILE_2 | PROFILE_3))
    			configure_module_pin_mux(nand_pin_mux);
    #endif
    		else if (profile == PROFILE_2) {
    			configure_module_pin_mux(mmc1_pin_mux);
    			configure_module_pin_mux(spi0_pin_mux);
    		}
    	} else if (board_is_idk(header)) {
    		/* Industrial Motor Control (IDK) */
    		configure_module_pin_mux(mii1_pin_mux);
    		configure_module_pin_mux(mmc0_no_cd_pin_mux);
    	} else if (board_is_evm_sk(header)) {
    		/* Starter Kit EVM */
    		configure_module_pin_mux(i2c1_pin_mux);
    		configure_module_pin_mux(gpio0_7_pin_mux);
    		configure_module_pin_mux(rgmii1_pin_mux);
    		configure_module_pin_mux(mmc0_pin_mux_sk_evm);
    	} else if (board_is_bone_lt(header)) {
    		/* Beaglebone LT pinmux */
    		configure_module_pin_mux(i2c1_pin_mux);
    		configure_module_pin_mux(mii1_pin_mux);
    		configure_module_pin_mux(mmc0_pin_mux);
    #if defined(CONFIG_NAND)
    		configure_module_pin_mux(nand_pin_mux);
    #elif defined(CONFIG_NOR)
    		configure_module_pin_mux(bone_norcape_pin_mux);
    #else
    		configure_module_pin_mux(mmc1_pin_mux);
    #endif
    	} else {
    		puts("Unknown board, cannot configure pinmux.");
    		hang();
    	}
    }

    另外,这个版本号的u-boot有个bug。须要改动fat_register_device(fs/fat/fat.c)函数:

    int fat_register_device(block_dev_desc_t *dev_desc, int part_no)
    {
    	disk_partition_t info;
    
    	/* First close any currently found FAT filesystem */
    	cur_dev = NULL;
    
    	/* Read the partition table, if present */
    	if (get_partition_info(dev_desc, part_no, &info)) {
    		/*if (part_no != 0) {
    			printf("** Partition %d not valid on device %d **
    ",
    					part_no, dev_desc->dev);
    			return -1;
    		}*/
    
    		info.start = 0;
    		info.size = dev_desc->lba;
    		info.blksz = dev_desc->blksz;
    		info.name[0] = 0;
    		info.type[0] = 0;
    		info.bootable = 0;
    #ifdef CONFIG_PARTITION_UUIDS
    		info.uuid[0] = 0;
    #endif
    	}
    
    	return fat_set_blk_dev(dev_desc, &info);
    }
    至此,u-boot就已经能够启动了,可是有多余的步骤和log。只是能够去掉。改动file_fat_read_at(fs/fat/fat.c)函数:

    long file_fat_read_at(const char *filename, unsigned long pos, void *buffer,
    		      unsigned long maxsize)
    {
    	debug("reading %s
    ", filename);
    	return do_fat_read_at(filename, pos, buffer, maxsize, LS_NO, 0);
    }
    最后,TQ335x是MLO启动u-boot。然后u-boot去启动内核。故能够去掉配置项CONFIG_SPL_OS_BOOT,详细的改动文件include/configs/ti_armv7_common.h:

    #if defined(CONFIG_SPL_OS_BOOT_ENABLE)
    #define CONFIG_SPL_OS_BOOT
    #endif

    至此,u-boot的移植工作就完毕了,编译方法例如以下:

    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- am335x_evm_defconfig
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j8

    当中,arm-linux-gnueabi-须要依据自己的交叉编译工具链前缀进行改动。完毕u-boot的移植工作后我们来研究怎样启动内核。


    源代码下载地址:

    u-boot-2014.10 for TQ335x/TQ3358(SD卡启动)


    本文作者:girlkoo

    本文链接:http://blog.csdn.net/girlkoo/article/details/41183217

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    PyQt(Python+Qt)学习随笔:QDial刻度盘部件功能简介
    PyQt(Python+Qt)学习随笔:QSlider滑动条部件功能简介
    PyQt(Python+Qt)学习随笔:QScrollBar以及QAbstractSlider滚动条部件功能详解
    第15.43节、PyQt输入部件:QAbstractSpinBox派生类QSpinBox、 QDoubleSpinBox、QDateTimeEdit、QDateEdit和QTimeEdit功能简介
    第三十六章、PyQt输入部件:QAbstractSpinBox派生类QSpinBox、 QDoubleSpinBox、QDateTimeEdit、QDateEdit和QTimeEdit
    PyQt(Python+Qt)学习随笔:QDateEdit日期编辑部件和QTimeEdit时间编辑部件
    程序员求职之道(《程序员面试笔试宝典》)之面试官箴言?
    程序员求职之道(《程序员面试笔试宝典》)之面试心得交流?
    程序员求职之道(《程序员面试笔试宝典》)之企业面试笔试攻略(互联网)?
    程序员求职之道(《程序员面试笔试宝典》)之面试笔试技巧?
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4642053.html
Copyright © 2011-2022 走看看