zoukankan      html  css  js  c++  java
  • AM335x(TQ335x)学习笔记——u-boot-2014.10移植 分类: TI-AM335X 2015-05-22 08:41 307人阅读 评论(0) 收藏

    最近移植了下u-boot-2014.10到TQ335x,如果基于am335x evm进行移植,需要修改的地方并不多。

    由于TI的am335x evm开发使用了一个eeprom保存了板载配置信息,用来区分不同板子的型号的,而TQ335x没有这个eeprom,因此,需要修改eeprom相关的部分,使u-boot适应TQ335x开发板。

    使用source insight查看代码,很容易发现,所有获取板载配置的部分都是通过读取eeprom获得的,因此,首选修改read_eeprom(board/ti/am335x/board.c)函数,具体的修改如下:

    1. static int read_eeprom(struct am335x_baseboard_id *header)  
    2. {  
    3. #if 1  
    4.     strcpy(header->name, "TQ335x");  
    5. #else  
    6.     /* Check if baseboard eeprom is available */  
    7.     if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) {  
    8.         puts("Could not probe the EEPROM; something fundamentally "  
    9.             "wrong on the I2C bus. ");  
    10.         return -ENODEV;  
    11.     }  
    12.   
    13.     /* read the eeprom using i2c */  
    14.     if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 2, (uchar *)header,  
    15.              sizeof(struct am335x_baseboard_id))) {  
    16.         puts("Could not read the EEPROM; something fundamentally"  
    17.             " wrong on the I2C bus. ");  
    18.         return -EIO;  
    19.     }  
    20.   
    21.     if (header->magic != 0xEE3355AA) {  
    22.         /* 
    23.          * read the eeprom using i2c again, 
    24.          * but use only a 1 byte address 
    25.          */  
    26.         if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 1, (uchar *)header,  
    27.                  sizeof(struct am335x_baseboard_id))) {  
    28.             puts("Could not read the EEPROM; something "  
    29.                 "fundamentally wrong on the I2C bus. ");  
    30.             return -EIO;  
    31.         }  
    32.   
    33.         if (header->magic != 0xEE3355AA) {  
    34.             printf("Incorrect magic number (0x%x) in EEPROM ",  
    35.                     header->magic);  
    36.             return -EINVAL;  
    37.         }  
    38.     }  
    39. #endif  
    40.   
    41.     return 0;  
    42. }  
    通过上述修改,u-boot不去读取eeprom,而是直接将header的name赋值为"TQ335x",后面可以根据这一配置区分是否为TQ335x开发板。

    然后是修改get_dpll_ddr_params(board/ti/am335x/board.c)函数,具体的修改内容如下:

    1. const struct dpll_params *get_dpll_ddr_params(void)  
    2. {  
    3.     struct am335x_baseboard_id header;  
    4.   
    5.     enable_i2c0_pin_mux();  
    6.     i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);  
    7.     if (read_eeprom(&header) < 0)  
    8.         puts("Could not get board ID. ");  
    9.   
    10.     if (board_is_tq335x(&header) || board_is_evm_sk(&header))  
    11.         return &dpll_ddr_evm_sk;  
    12.     else if (board_is_bone_lt(&header))  
    13.         return &dpll_ddr_bone_black;  
    14.     else if (board_is_evm_15_or_later(&header))  
    15.         return &dpll_ddr_evm_sk;  
    16.     else  
    17.         return &dpll_ddr;  
    18. }  
    然后是修改sdram_init(board/ti/am335x/board.c)函数,具体的修改内容如下:
    1. void sdram_init(void)  
    2. {  
    3.     __maybe_unused struct am335x_baseboard_id header;  
    4.   
    5.     if (read_eeprom(&header) < 0)  
    6.         puts("Could not get board ID. ");  
    7.   
    8.     if (board_is_evm_sk(&header)) {  
    9.         /* 
    10.          * EVM SK 1.2A and later use gpio0_7 to enable DDR3. 
    11.          * This is safe enough to do on older revs. 
    12.          */  
    13.         gpio_request(GPIO_DDR_VTT_EN, "ddr_vtt_en");  
    14.         gpio_direction_output(GPIO_DDR_VTT_EN, 1);  
    15.     }  
    16.   
    17.     if (board_is_evm_sk(&header) || board_is_tq335x(&header))  
    18.         config_ddr(303, &ioregs_evmsk, &ddr3_data,  
    19.                &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);  
    20.     else if (board_is_bone_lt(&header))  
    21.         config_ddr(400, &ioregs_bonelt,  
    22.                &ddr3_beagleblack_data,  
    23.                &ddr3_beagleblack_cmd_ctrl_data,  
    24.                &ddr3_beagleblack_emif_reg_data, 0);  
    25.     else if (board_is_evm_15_or_later(&header))  
    26.         config_ddr(303, &ioregs_evm15, &ddr3_evm_data,  
    27.                &ddr3_evm_cmd_ctrl_data, &ddr3_evm_emif_reg_data, 0);  
    28.     else  
    29.         config_ddr(266, &ioregs, &ddr2_data,  
    30.                &ddr2_cmd_ctrl_data, &ddr2_emif_reg_data, 0);  
    31. }  
    然后添加board_is_tq335x函数的具体实现,参考其它类似函数实现即可,由于我们的read_eeprom仅读到了name,其内容是"TQ335x",故可如下实现,在board/ti/am335x/board.h中添加如下内容:
    1. static inline int board_is_tq335x(struct am335x_baseboard_id *header)  
    2. {  
    3.     return !strncmp(header->name, "TQ335x", HDR_NAME_LEN);  
    4. }  
    最后是修改enable_board_pin_mux(board/ti/am335x/mux.c)函数,具体的修改内容如下:
    1. void enable_board_pin_mux(struct am335x_baseboard_id *header)  
    2. {  
    3.     /* Do board-specific muxes. */  
    4.     if (board_is_bone(header) || board_is_tq335x(header)) {  
    5.         /* Beaglebone pinmux */  
    6.         configure_module_pin_mux(i2c1_pin_mux);  
    7.         configure_module_pin_mux(mii1_pin_mux);  
    8.         configure_module_pin_mux(mmc0_pin_mux);  
    9. #if defined(CONFIG_NAND)  
    10.         configure_module_pin_mux(nand_pin_mux);  
    11. #elif defined(CONFIG_NOR)  
    12.         configure_module_pin_mux(bone_norcape_pin_mux);  
    13. #else  
    14.         configure_module_pin_mux(mmc1_pin_mux);  
    15. #endif  
    16.     } else if (board_is_gp_evm(header)) {  
    17.         /* General Purpose EVM */  
    18.         unsigned short profile = detect_daughter_board_profile();  
    19.         configure_module_pin_mux(rgmii1_pin_mux);  
    20.         configure_module_pin_mux(mmc0_pin_mux);  
    21.         /* In profile #2 i2c1 and spi0 conflict. */  
    22.         if (profile & ~PROFILE_2)  
    23.             configure_module_pin_mux(i2c1_pin_mux);  
    24.         /* Profiles 2 & 3 don't have NAND */  
    25. #ifdef CONFIG_NAND  
    26.         if (profile & ~(PROFILE_2 | PROFILE_3))  
    27.             configure_module_pin_mux(nand_pin_mux);  
    28. #endif  
    29.         else if (profile == PROFILE_2) {  
    30.             configure_module_pin_mux(mmc1_pin_mux);  
    31.             configure_module_pin_mux(spi0_pin_mux);  
    32.         }  
    33.     } else if (board_is_idk(header)) {  
    34.         /* Industrial Motor Control (IDK) */  
    35.         configure_module_pin_mux(mii1_pin_mux);  
    36.         configure_module_pin_mux(mmc0_no_cd_pin_mux);  
    37.     } else if (board_is_evm_sk(header)) {  
    38.         /* Starter Kit EVM */  
    39.         configure_module_pin_mux(i2c1_pin_mux);  
    40.         configure_module_pin_mux(gpio0_7_pin_mux);  
    41.         configure_module_pin_mux(rgmii1_pin_mux);  
    42.         configure_module_pin_mux(mmc0_pin_mux_sk_evm);  
    43.     } else if (board_is_bone_lt(header)) {  
    44.         /* Beaglebone LT pinmux */  
    45.         configure_module_pin_mux(i2c1_pin_mux);  
    46.         configure_module_pin_mux(mii1_pin_mux);  
    47.         configure_module_pin_mux(mmc0_pin_mux);  
    48. #if defined(CONFIG_NAND)  
    49.         configure_module_pin_mux(nand_pin_mux);  
    50. #elif defined(CONFIG_NOR)  
    51.         configure_module_pin_mux(bone_norcape_pin_mux);  
    52. #else  
    53.         configure_module_pin_mux(mmc1_pin_mux);  
    54. #endif  
    55.     } else {  
    56.         puts("Unknown board, cannot configure pinmux.");  
    57.         hang();  
    58.     }  
    59. }  

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

    1. int fat_register_device(block_dev_desc_t *dev_desc, int part_no)  
    2. {  
    3.     disk_partition_t info;  
    4.   
    5.     /* First close any currently found FAT filesystem */  
    6.     cur_dev = NULL;  
    7.   
    8.     /* Read the partition table, if present */  
    9.     if (get_partition_info(dev_desc, part_no, &info)) {  
    10.         /*if (part_no != 0) { 
    11.             printf("** Partition %d not valid on device %d ** ", 
    12.                     part_no, dev_desc->dev); 
    13.             return -1; 
    14.         }*/  
    15.   
    16.         info.start = 0;  
    17.         info.size = dev_desc->lba;  
    18.         info.blksz = dev_desc->blksz;  
    19.         info.name[0] = 0;  
    20.         info.type[0] = 0;  
    21.         info.bootable = 0;  
    22. #ifdef CONFIG_PARTITION_UUIDS  
    23.         info.uuid[0] = 0;  
    24. #endif  
    25.     }  
    26.   
    27.     return fat_set_blk_dev(dev_desc, &info);  
    28. }  
    至此,u-boot就已经可以启动了,但是有多余的步骤和log,不过可以去掉,修改file_fat_read_at(fs/fat/fat.c)函数:

    1. long file_fat_read_at(const char *filename, unsigned long pos, void *buffer,  
    2.               unsigned long maxsize)  
    3. {  
    4.     debug("reading %s ", filename);  
    5.     return do_fat_read_at(filename, pos, buffer, maxsize, LS_NO, 0);  
    6. }  
    最后,TQ335x是MLO启动u-boot,然后u-boot去启动内核,故可以去掉配置项CONFIG_SPL_OS_BOOT,具体的修改文件include/configs/ti_armv7_common.h:

    1. #if defined(CONFIG_SPL_OS_BOOT_ENABLE)  
    2. #define CONFIG_SPL_OS_BOOT  
    3. #endif  

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

    1. make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- am335x_evm_defconfig  
    2. make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j8  

    其中,arm-linux-gnueabi-需要根据自己的交叉编译工具链前缀进行修改。完成u-boot的移植工作后我们来研究如何启动内核。


    源码下载地址:

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

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    Linux实用命令之git-svn
    Linux实用命令之xdg-open
    记一个logrotate的配置文件权限问题
    日常开发技巧:x11-forward,使用远程机器的gui程序
    【机器学习】PCA
    【PyTorch】Tricks 集锦
    【Python】itertools之product函数
    强化学习——值迭代和策略迭代
    PyTorch中MaxPool的ceil_mode属性
    猫狗识别——PyTorch
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706422.html
Copyright © 2011-2022 走看看