TQ335x的uboot移植(一)

来源:互联网 发布:国际软件学院英文 编辑:程序博客网 时间:2024/06/05 14:54

最近打算移植uboot2015.07到TQ3358平台,在下面这个帖子里看到了如何移植uboot的介绍,这对于uboot2015后续的版本也有帮助,在此留个记录,这个帖子的下面还有些回复也值得参考。

http://blog.csdn.NET/girlkoo/article/details/41183217

最近移植了下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)函数,具体的修改如下:

[cpp] view plain copy
在CODE上查看代码片派生到我的代码片

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.\n");          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.\n");          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.\n");              return -EIO;          }          if (header->magic != 0xEE3355AA) {              printf("Incorrect magic number (0x%x) in EEPROM\n",                      header->magic);              return -EINVAL;          }      }  #endif      return 0;  }  

通过上述修改,u-boot不去读取eeprom,而是直接将header的name赋值为”TQ335x”,后面可以根据这一配置区分是否为TQ335x开发板。

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

[cpp] view plain copy
在CODE上查看代码片派生到我的代码片

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.\n");      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)函数,具体的修改内容如下:
[cpp] view plain copy
在CODE上查看代码片派生到我的代码片

void sdram_init(void)  {      __maybe_unused struct am335x_baseboard_id header;      if (read_eeprom(&header) < 0)          puts("Could not get board ID.\n");      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中添加如下内容:
[cpp] view plain copy
在CODE上查看代码片派生到我的代码片

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)函数,具体的修改内容如下:
[cpp] view plain copy
在CODE上查看代码片派生到我的代码片

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)函数:

[cpp] view plain copy
在CODE上查看代码片派生到我的代码片

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 **\n",                     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)函数:

[cpp] view plain copy
在CODE上查看代码片派生到我的代码片

long file_fat_read_at(const char *filename, unsigned long pos, void *buffer,                unsigned long maxsize)  {      debug("reading %s\n", 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:

[cpp] view plain copy
在CODE上查看代码片派生到我的代码片

#if defined(CONFIG_SPL_OS_BOOT_ENABLE)  #define CONFIG_SPL_OS_BOOT  #endif  

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

[cpp] view plain copy
在CODE上查看代码片派生到我的代码片

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的移植工作后我们来研究如何启动内核。

0 0
原创粉丝点击