【免费下载】am335x uboot移植
am335x_linux-3.14.43内核移植笔记
本文主要描述在EVB335X-II以Device Tree的方式移植新TI官网AM335X系列最新的linux-3.14.43版本内核以及移植Debian文件系统的过程及遇到的一些问题。
整个Device Tree牵涉面比较广,即增加了新的用于描述设备硬件信息的文本格式(即.dts文件),又增加了编译这一文本的工具,同时Bootloader也需要支持将编译后的Device Tree传递给Linux内核。
以下是修改步骤:一、修改uboot,支持Device TreeEVB335X-II在linux-3.2版本内核移植的时候已经有uboot,因此只需在该uboot上增加Device Tree支持即可,以下是修改步骤:1、修改include/configs/com335x.h文件,增加支持DT的宏定义:/* Flattened Device Tree */#define CONFIG_OF_LIBFDT2、修改uboot启动参数,增加dtb文件的加载和启动(由于目前只是移植EMMC版本的EVB335X-II,因此只需修改EMMC的启动参数即可,大概在405行),修改如下:#elif defined(CONFIG_EMMC_BOOT)#define CONFIG_BOOTCOMMAND \"run mmcboot;"#define CONFIG_EXTRA_ENV_SETTINGS \"lcdtype=AUO_AT070TN94\0" \"console=ttyO0,115200n8\0" \"mmcroot=/dev/mmcblk0p2 rw\0" \"mmcrootfstype=ext4 rootwait\0" \"mmcargs=setenv bootargs console=${console} noinitrd root=${mmcroot} rootfstype=${mmcrootfstype} lcdtype=${lcdtype} consoleblank=0\0" \"mmcdev=" MMCDEV "\0" \"loadaddr=0x81000000\0" \"dtbfile=evb335x-ii-emmc.dtb\0" \"bootenv=uEnv.txt\0" \"bootpart=" BOOTPART "\0" \"loadbootenv=load mmc ${mmcdev} ${loadaddr} ${bootenv}\0" \"importbootenv=echo Importing environment from mmc ...; " \"env import -t $loadaddr ${filesize}\0" \"loadaddr-dtb=0x82000000\0" \"loadimage=load mmc ${bootpart} ${loadaddr} uImage\0" \"loaddtb=load mmc ${bootpart} ${loadaddr-dtb} ${dtbfile}\0" \"mmcboot=mmc dev ${mmcdev}; " \"if mmc rescan; then " \"echo SD/MMC found on device ${mmcdev};" \"if run loadbootenv; then " \"echo Loaded environment from ${bootenv};" \"run importbootenv;" \"fi;" \"run mmcargs;" \"if run loadimage; then " \"run loaddtb;" \"bootm ${loadaddr} - ${loadaddr-dtb};" \"fi;" \"fi; \0"#endif以上,红色为修改部分。
AM335x 处理器 SDK RTOS 板库端口和启动说明书
Board Porting\Bring up using Processor SDK RTOS for AM335xProcessor SDK RTOS component known as board library consolidates all the board-specific information so that all the modifications made when moving to a new custom platform using the SOC can be made in the source of this library.There are three different components in PRSDK that help in porting and bring up of a custom board:∙Board library updatesa.PLL Clocking and PRCMb.Pin mux Updatec.DDR Configurationd.Peripheral instances updates∙Diagnostics tests∙Boot loader updatesBoard Library Updates in Processor SDK RTOS:PLL ClockingThere are two places where the device PLL configurations are performed when using Processor SDK RTOS and CCS.Debug environment:Debug environment refers to development setup where code is debugged using JTAG emulator on the SOC. The PRSDK software relies on the GEL file that is part of the target configuration to setup the clocks and the DDR for the device. The CCS GEL file for AM335x platforms is located in the CCS package at the location ccsv7\ccs_base\emulation\boards\<boardName>For example for beagle bone black, the files can be found atccsv7\ccs_base\emulation\boards\beaglebone\gelThe GEL is the first piece of software that should be brought up on a custom board.Production environment:Production environment refers to the setup when the base application is booted from a boot media like a flash memory or host interface. In this environment, the bootloader sets performs all the SOC and board initialization and copies the application from flash memory to the device memory.The clock setup in the bootloader code can be located atpdk_am335x_x_x_x\packages\ti\starterware\bootloader\src\am335xUsers can choose to use the platform clocking similar to one of TI reference platforms or can modify them as per their application requirements. By default the PLL settings are setup for OPP_NOM settings (MPU= 600 MHz.)TI provides Clock Tree tool to allow users to simulate the clocking on the SOC. For quick reference of the multiplier and divider settings to change the PLL setting is provided in the spreadsheetAM335x_DPLL_CALCv3.xlsx.After modifying the clocking in the bootloader, users need to rebuild the bootloader using instructions provided in Processor_SDK_RTOS_BOOT_AM335x/AM437xPRCM Modules Enable:PRCM Module Enable is required to turn on the power domain and the clocking to each of the modules on the SOC. The PRCM Enable calls to enable each module are made from the functionBoard_moduleClockInit which is found in the location.pdk_am335x_1_0_9\packages\ti\board\src\bbbAM335x\bbbAM335x.cCheck every instance and peripheral required in the application platform and enable the module in the board library.For example to use three UARTs 0, 1 and 4, ensure that you have the following code as part of the board library setup:/* UART */status = PRCMModuleEnable(CHIPDB_MOD_ID_UART, 0U, 0U);status = PRCMModuleEnable(CHIPDB_MOD_ID_UART, 1U, 0U);status = PRCMModuleEnable(CHIPDB_MOD_ID_UART, 4U, 0U);Note: PRCMEnable function is defined in pdk_am335x_1_0_9\packages\ti\starterware\soc\am335x Pinmux updates in the Board library:Generating a New PinMux Configuration Using the PinMux Utility: This procedure uses the cloud-based pinmux utilityNavigate to ${PDK_INSTALL_DIR}\packages\ti\starterware\tools\pinmux_config\am335x and Load beaglebone_black_configAdd and remove peripheral instances and select the appropriate use cases required for development based on the application platform requirements and resolve all conflicts.Refer Pin_Mux_Utility_for_ARM_MPU_ProcessorsPost Processing steps:1.Change the Category filter to starterware and download the pinmux files am335x_pimnmux.hand am335x_pinmux_data.c2.At the bottom of am335x_pinmux.h change extern pinmuxBoardCfg_t gAM335xPinmuxData[];to extern pinmuxBoardCfg_t gBbbPinmuxData[];3.Change am335x_pinmux_data.c to am335x_beagleboneblack_pinmux_data.c.4.Change gAM335xPinmuxData to gBbbPinmuxData at the end of the file in file5.am335x_beagleboneblack_pinmux_data.c.Replace the existing files with the new files and rebuild the board library using the instructions in the section Rebuilding board Library in Processor SDK RTOS:Updating DDR settings:Similar to clock and PLL settings, DDR initialization is configured in the Debug environment through GEL files and in production environment using bootloader source files.TI provides AM335x_EMIF_Configuration_tips which contains a spreadsheet to enter the timing from the DDR datasheet to compute the EMIF timing number required to initialize DDR.We strongly recommend changing the value and testing using GEL files before using them in the bootloader software. For Sanity test, you can perform read/write tests using CCS Memory Browser or run the diagnostic memory read/write test that we provide in diagnostics package here:PDK_INSTALL_PATH\packages\ti\board\diag\memOnce the DDR timings have been confirmed, you can use the settings in the file:PDK_INSTALL_PATH \packages\ti\starterware\bootloader\src\am335x\sbl_am335x_platform_ddr.c Peripheral initialization:The board library is responsible for most of the SOC initialization but it also setup some board level components such as ethernet PHY and debug UART and I2C for reading board ID from EEPROM. All of the other peripheral instances and initialization needs to be done from the application level.For example for beagleboneblack, the peripheral initialization are performed from the source filepdk_am335x_1_0_9\packages\ti\board\src\bbbAM335x\bbbAM335x_lld_init.cThe debug UART instance, I2C Addresses are set using the file board_cfg.h found under:pdk_am335x_1_0_9\packages\ti\board\src\bbbAM335x\includeDefault UART instance is set to 0 in the board library. The Board initialization will configure the UART instance 0 to send binary log data to serial console using the Board_UARTInit function. If you wish to use more UART instances then we recommend linking in the UART driver in the application and using UART_open() and UART_stdioInit API calls from the application.Each peripheral driver in the Processor SDK RTOS has a SOC configuration that provides the interrupt numbers, base address, EDMA channels which can be updated using the file <peripheral>_soc.c file. This is used as default setup for initializing the driver instance. It can be overridden from the application using peripheral_getSOCInitCfg() and peripheral_setSOCInitCfg()For Example: All instances of UART for AM335x have been mapped in the filepdk_am335x_1_0_9\packages\ti\drv\uart\soc\am335x\UART_soc.cSystem integrators need to ensure that no interrupt numbers and EDMA resource conflicts exist in the SOC configuration for all drivers used in the system.To exercise three UARTs in the system, users can use the following code://Setup Debug UARTboardCfg = BOARD_INIT_PINMUX_CONFIG |BOARD_INIT_MODULE_CLOCK |BOARD_INIT_UART_STDIO;Board_init(boardCfg);// Open Additional UART Instances:/* UART SoC init configuration */UART_initConfig(false);/* Initialize the default configuration params. */UART_Params_init(&uartParams);// Open UART Instance 1uartTestInstance =1;uart1 = UART_open(uartTestInstance, &uartParams);//Open UART Instance 4uartTestInstance = 4;uart4 = UART_open(uartTestInstance, &uartParams);BoardID Detect:TI supports multiple evaluation and reference platforms for AM335x hence the hardware platforms are populated with an EEPROM which contains information that identifies the hardware and its revision. The board library and software components read the boardID and initialize the platform based on the boardID. The BoardID_detect function can be found in the source in the file bbbAM335x_info.c in the board library and board_am335x.c in the bootloader source at:<PDK_INSTALL_PATH>\packages\ti\starterware\board\am335xRebuilding board Library in Processor SDK RTOS:While Creating a new folder for the custom board is an option users can explore, TI recommends that users make there changes in existing board package using either bbbAM335x, evmAM335x oriceAM335x folder to avoid spending additional effort to modify the build files for including the customBord.Once all the update to the board library are completed, the board library can be updated using the following instructions.Instructions to rebuild board library:Setup Processor SDK build environment before following steps provided below.cd pdk_am335x_1_0_9\packagesgmake board_libFor a specific board users are required to provide the LIMIT_BOARDS argument.LIMIT_BOARDS : evmAM335x icev2AM335x iceAMIC110 bbbAM335x skAM335xFor Example for beagleboneblack, users can use the following build option:gmake board_lib LIMIT_BOARDS=bbbAM335xDiagnostics:After the board library is built, we highly recommend that you create a diagnostics package similar to one provided in board library to test different interfaces functionally during board bring up.The diagnostics package can be located at pdk_am335x_1_0_9\packages\ti\board\diag. These are simple bare-metal tests that use peripheral drivers to help functionally validate the pins and interfaces.Documentation for all available diagnostic tests is provided here:/index.php/Processor_SDK_RTOS_DIAGBootloader in Processor SDK RTOS:As part of the production flow, users are required to develop/port flashing and booting utilities so the application can be launched on the custom board with JTAG. TI provides a bootloader mechanism where the ROM bootloader loads a secondary bootloader on the onchip memory that initializes the SOC and DDR and then copies the application into DDR memory.The boot process and flashing tools have been described in detail in the following article that is part of processor SDK RTOS Software developer`s guide:/index.php/Processor_SDK_RTOS_BOOT_AM335x/AM437x#Building_the_B ootloader。
AM335xU-BootUsersGuide中文手册
AM335xU-BootUsersGuide中⽂⼿册AM335x U-Boot User's Guide /****************************************************************** * author: 卢浩* time: 2012.09.12* environment: ubuntu10.04LTS +TI AM3359* kernel version: linux-3.2* Official Website:/doc/783206ed551810a6f5248646.html/doc/783206ed551810a6f5248646.html* QQ Group For Technology Exchange:122879839******************************************************************/ 风核科技出品—AM3359系列搭建uboot开发环境进⼊官⽅提供的SDK包的uboot⽬录$ cd ./AM335x-LINUX-PSP-MM.mm.pp.bb/src/u-boot/u-boot-MM.mm.pp.bb编译⼝令$ [ -d ./am335x ] && rm -rf ./am335x$ make O=am335x CROSS_COMPILE=arm-arago-linux-gnueabi- ARCH=arm am335x_evm编译完成将会⽣成可执⾏性⽂件MLO和u-boot.img。
主机配置:⽤串⼝线把主机和EVM板连接起来,设置超级终端参数如下:*Baud rate: 115,200*Data bits: 8*Parity: None*Stop bits: 1*Flow control: None开发板配置:设置启动⽅式:请注意,红⾊位置为off,绿⾊位置为on Nand启动,请设置拨码开关如下:SPI启动,请设置拨码开关如下:UART启动,请设置拨码开关如下:SD启动,请设置拨码开关如下:CPSW启动,请设置拨码开关如下:注意,从CPSW启动这样设置是因为EVM板⽤的是RGMII mode。
AM335x uboot spl分析
AM335x uboot spl分析芯片到uboot启动流程ROM → SPL→ uboot.img简介在335x 中ROM code是第一级的bootlader。
mpu上电后将会自动执行这里的代码,完成部分初始化和引导第二级的bootlader,第二级的bootlader引导第三级bootader,在ti官方上对于第二级和第三级的bootlader由uboot提供。
SPLTo unify all existing implementations for a secondary program loader (SPL) and to allow simply adding of new implementations this generic SPL framework has been created. With this framework almost all source files for a board can be reused. No code duplication or symlinking is necessary anymore.1> Basic ARM initialization2> UART console initialization3> Clocks and DPLL locking (minimal)4> SDRAM initialization5> Mux (minimal)6> BootDevice initialization(based on where we are bootingfrom.MMC1/MMC2/Nand/Onenand)7> Bootloading real u-boot from the BootDevice and passing control to it.uboot spl源代码分析一、makefile分析打开spl文件夹只有一个makefile 可见spl都是复用uboot原先的代码。
AM335x Flash Tool -- UniFlash 烧写工具使用简介及问题解决方案汇总
AM335x Flash Tool -- UniFlash 烧写工具使用简介及问题解决方案汇总大家好,目前很多人都在关注AM335x flash tool(UniFlash)的进展情况,这篇文章会对当前的进展情况进行汇总,并就客户使用过程中遇到的一些问题,给出了相应的解决方案。
目前的UniFlash官方发布的版本中,仅支持NAND FLASH的烧录,近期版本中将会更新对eMMC烧录功能的支持。
UniFlash的下载地址:/index.php/NowFlash%E2%84%A2_Programming_ToolUniFlash的主机端安装用户指南:/index.php/Sitara_Uniflash_Quick_Start_GuideUniFlash的image编译,脚本编译使用指南(Linux环境下):/index.php/Sitara_Linux_AM335x_Flash_Programming_Linux_Developmen t使用注意事项及问答:1.使用该Uniflash进行NAND FLASH烧写时,Uniflash会先将u-boot-spl-restore.bin和u-boot-restore.img下载到开发板中,启动开发板进入到UBOOT阶段,从而调用脚本文件进行FLASH的烧写,所以需要先对SDK6.0开发包进行UBOOT的移植。
移植时,一定要加入UBOOT 的patch:/index.php/Sitara_Linux_AM335x_Flash_Programming_Linux_Dev elopment#Build_SPL_.28MLO.29_and_U-Boot_for_Flashing2.请注意,制作用于NAND flash烧写的启动image时,确认使用的编译选项为:am335x_evm_restore_flash_usbspl3.在Uniflash进行u-boot-spl-restore.bin的下载时,如果出现usb网络反应超时,请确认是否已经安装我们的usb patch:0001-u-boot-Change-default-cdc_connect_timeout-to-15s.patch。
uboot——官网下载直接移植(一)
uboot——官⽹下载直接移植(⼀)1:uboot下载地址:ftp://ftp.denx.de/pub/u-boot/我们下载的版本是:u-boot-2013.10.tar.bz2;2:下载好以后,删除⾥⾯的相关⽂件因为三星是的s5pv1XX这个cpu做了很多个板⼦,我们在移植的时候虽然与三星的开发板不同但是⽤的cpu是相同的,所以我们再选择cpu相关⽂件的时候,要确定好哪个cpu与我们⽤的cpu是相同的,u-boot-2013.10\arch\arm\cpu\armv7\s5pc1xx 在⽬录下有s5pc1xx相关的配置⽂件;这就是我们要选⽤的cpu⽂件;3:相较与我们直接移植三星移植好的uboot,新版的uboot编译配置时有所不同;把主Makefile与board有关的配置信息⽂件分开了;我们可以根据board.cfg⽂件中的配置信息来确定我们⽤的是哪个开发板;打开board.cfg⽂件搜索s5pc1xx我们可以看到两个相关的开发板,goni、smdk100,我们先⽤goni开发板来进⾏移植;⾸先删除其它的⽆关⽂件:arch⽬录下:只保留arm⽂件夹;arm/cpu⽬录下的出armv7⽂件夹以外其他删除;arm/cpu/armv7⽬录下保留s5pc1xx 以及s5p_common这两个⽂件夹,其他的删除;board⽬录下:board⽬录下只保留samsung⽂件夹samsung⽬录下只保留goni、common⽂件夹之后⽤sourceinsight创建项⽬4:对主Makefile进⾏分析,之前我们make的时候⾸先要进⾏配置:make x210_sd_config,⽽在新uboot中的配置依赖于下⾯这个规则:我们进⾏配置的时候make s5p_goni_config 然后执⾏下⾯这段脚本相当于执⾏ ./mkcofig -A s5p_goniMKCONFIG变量还是mkconfig脚本,下⾯我们看⼀下mkconfig脚本如何⼯作:下⾯这段代码的作⽤:1if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then2 # Automatic mode3 line=`awk '($0 !~ /^#/ && $7 ~ /^'"$2"'$/) { print $1, $2, $3, $4, $5, $6, $7, $8 }' boards.cfg`4if [ -z "$line" ] ; then5 echo "make: *** No rule to make target \`$2_config'. Stop." >&26 exit 17 fi89set ${line}10 # add default board name if needed11 [ $# = 3 ] && set ${line} ${1}12 fi判断传参是否两个且第⼀个参数为 -A,如果是则对line赋值,line的值是通过在boards.cfg⽂件中查找第⼆个参数$2,并把这⼀⾏赋值给line,从前⾯内容我们可以看出line = Active arm armv7 s5pc1xx samsung goni s5p_goni -并且把这些由空格分开的字符赋值给$1-$8所以这段代码执⾏完以后的结果是:$1 = Active$2 = arm$3 = armv7$4 = s5pv1xx$5 = samsung$6 = goni$7 = s5p_goni$8 = -继续分析下⾯代码:这段代码实际中没有起到什么作⽤可忽略1while [ $# -gt 0 ] ; do2case"$1"in3 --) shift ; break ;;4 -a) shift ; APPEND=yes ;;5 -n) shift ; BOARD_NAME="${7%_config}" ; shift ;;6 -t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;;7 *) break ;;8 esac9 done1011 [ $# -lt 7 ] && exit 112 [ $# -gt 8 ] && exit 1下⾯代码:CONFIG_NAME="${7%_config}"[ "${BOARD_NAME}" ] || BOARD_NAME="${7%_config}"arch="$2"cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $1}'`spl_cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $2}'`if [ "$6" = "-" ] ; thenboard=${BOARD_NAME}elseboard="$6"fi[ "$5" != "-" ] && vendor="$5"[ "$4" != "-" ] && soc="$4"[ $# -gt 7 ] && [ "$8" != "-" ] && {# check if we have a board config name in the options field# the options field mave have a board config name and a list# of options, both separated by a colon (':'); the options are# separated by commas (',').## Check for board nametmp="${8%:*}"if [ "$tmp" ] ; thenCONFIG_NAME="$tmp"fi# Check if we only have a colon...if [ "${tmp}" != "$8" ] ; thenoptions=${8#*:}TARGETS="`echo ${options} | sed 's:,: :g'` ${TARGETS}"fi}config_name = s5p_goni_configBOARD_NAME = s5p_goni_configarch = armcpu = armv7spl_cpu = " "board = gonivendor = samsungsoc = s5pc1xx看下⾯信息:在这⾥第⼀打印出信息:Configuring for s5p_goni_config board...if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; thenecho "Failed: \$ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}"1>&2exit 1fiif [ "$options" ] ; thenecho "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${options}" elseecho "Configuring for ${BOARD_NAME} board..."fi创建头⽂件的符号连接:if [ "$SRCTREE" != "$OBJTREE" ] ; thenmkdir -p ${OBJTREE}/includemkdir -p ${OBJTREE}/include2cd ${OBJTREE}/include2rm -f asmln -s ${SRCTREE}/arch/${arch}/include/asm asmLNPREFIX=${SRCTREE}/arch/${arch}/include/asm/cd ../includemkdir -p asmelsecd ./includerm -f asmln -s ../arch/${arch}/include/asm asmfirm -f asm/archif [ -z "${soc}" ] ; thenln -s ${LNPREFIX}arch-${cpu} asm/archelseln -s ${LNPREFIX}arch-${soc} asm/archfiif [ "${arch}" = "arm" ] ; thenrm -f asm/procln -s ${LNPREFIX}proc-armv asm/procfi符号连接1:/include/asm 连接到 /arch/arm/include/asm符号连接2: /include/asm/arch链接到 /arch/arm/include/asm/arch-s5pc1xx 符号链接3: /include/asm/proc链接到/arch/arm/include/asm/proc-armv看⼀下下⾯的代码:## Create include file for Make#( echo "ARCH = ${arch}"if [ ! -z "$spl_cpu" ] ; thenecho 'ifeq ($(CONFIG_SPL_BUILD),y)'echo "CPU = ${spl_cpu}"echo "else"echo "CPU = ${cpu}"echo "endif"elseecho "CPU = ${cpu}"fiecho "BOARD = ${board}"[ "${vendor}" ] && echo "VENDOR = ${vendor}"[ "${soc}" ] && echo "SOC = ${soc}"exit 0 ) > config.mk这段代码的作⽤是把ARCH = armCPU = armv7BOARD = gonivendor = samsungsoc = s5pc1xx 输出config.mk⽂件中看下⾯代码:# Assign board directory to BOARDIR variableif [ -z "${vendor}" ] ; thenBOARDDIR=${board}elseBOARDDIR=${vendor}/${board}fiBOARDDIR = samsung/goni再看最后⼀段代码:# Create board specific header file#if [ "$APPEND" = "yes" ] # Append to existing config file thenecho >> config.helse> config.h # Create new config filefiecho "/* Automatically generated - do not edit */" >>config.hfor i in ${TARGETS} ; doi="`echo ${i} | sed '/=/ {s/=/ /;q; } ; { s/$/ 1/; }'`"echo "#define CONFIG_${i}" >>config.h ;doneecho "#define CONFIG_SYS_ARCH \"${arch}\"" >> config.hecho "#define CONFIG_SYS_CPU \"${cpu}\"" >> config.hecho "#define CONFIG_SYS_BOARD \"${board}\"" >> config.h [ "${vendor}" ] && echo "#define CONFIG_SYS_VENDOR \"${vendor}\"" >> config.h [ "${soc}" ] && echo "#define CONFIG_SYS_SOC \"${soc}\"" >> config.hcat << EOF >> config.h#define CONFIG_BOARDDIR board/$BOARDDIR#include <config_cmd_defaults.h>#include <config_defaults.h>#include <configs/${CONFIG_NAME}.h>#include <asm/config.h>#include <config_fallbacks.h>#include <config_uncmd_spl.h>EOFexit 0上⾯这段代码的作⽤就是添加⼀些宏定义到config.h⽂件中:/* Automatically generated - do not edit */TARGETS为空所以不执⾏#define CONFIG_SYS_ARCH arm#define CONFIG_SYS_CPU armv7#define CONFIG_SYS_BOARD goni#define CONFIG_SYS_SOC s5pc1xxcat << EOF >> config.h 这句代码的作⽤是把下⾯内容写⼊config.h中,直到EOF;。
AM335X UBIFS NandFlash Programming Guide v1.1
return omap_bootmode[0]; } } /* End */
修改完后重新编译。
Linux Kernel:
由于 SDK 是 3.2 的内核,需要打以下补丁,关于该补丁的描述参见 https:///patch/1245721/,并且该补丁已融入 3.4.7 内核中 /pub/linux/kernel/v3.x/ChangeLog-3.4.7:
至此,mtd-utils 编译完成。
制作 UBI Filesystem
打开终端,输入: cd [your base dirctory]/mtd-utils-1.5.0 mkfs.ubifs/mkfs.ubifs -r [your filesystem directory]/ -F -o ubifs.img -m 2048 -e 126976 -c 1580
编译 mtd-utils..........................................................................................................................3 制作 UBI Filesystem.................................................................................................................4
或通过 Git 获取源码: git:///mtd-utils.git
推荐使用 mtd-utils 1.4.8 以上
AM335x UBOOT移植记录
board_init_r 第 2 阶段的初始化,在 board.c 文件中
enable_caches 这个函数没有做什么内容
board_init
第 2 次初始化平台,这里可以初始化其他内容了,和平台相关
mem_malloc_init 初始化 malloc 内存
nanபைடு நூலகம்_init
初始化 NAND(CONFIG_CMD_NAND 需要定义)
uboot 的代码运行流程 u-boot-2011.09-psp04.06.00.08/arch/arm/cpu/armv7 start.s 入口运行文件
bl save_boot_params 跳转到 lowlevel_init.S 该 文 件 在 (arch\arm\cpu\armv7\omap-common) , 如 果 是 MLO 则 会 定 义
1、.boards.depend 2、include/config.h
/* Automatically generated - do not edit */ #define CONFIG_BOARDDIR board/ti/am335x #include <config_cmd_defaults.h> #include <config_defaults.h> #include <configs/am335x_evm.h> #include <asm/config.h> 3、include/config.mk ARCH = arm CPU = armv7 BOARD = am335x VENDOR = ti SOC = ti81xx
这个目录下的几个文件,start.s 这个是程序的入口执行文件 u-boot-2011.09-psp04.06.00.08/arch/arm/cpu/armv7/omap-common u-boot-2011.09-psp04.06.00.08/arch/arm/cpu/armv7/ti81xx
uuboot 移植流程
uuboot 移植流程U-Boot 移植流程介绍U-Boot是一个开源的引导加载程序,常用于嵌入式系统中。
移植U-Boot可以将其适配到不同的硬件平台上,以满足特定需求。
本文将详细说明U-Boot移植的流程。
准备工作1.硬件选型:根据项目需求,选择适合的硬件平台。
2.获取源代码:从U-Boot官方网站或仓库下载最新版本的源代码。
3.安装交叉编译工具链:根据目标硬件平台的指令集架构,选择合适的交叉编译工具链,并进行安装。
4.了解目标硬件平台:熟悉目标硬件平台的架构、引导方式、存储器布局等相关信息。
移植流程1.配置编译环境:设置交叉编译工具链的环境变量,以确保正确编译U-Boot源代码。
2.配置U-Boot:修改U-Boot源代码中的配置文件,根据目标硬件平台的特性和需求进行相应配置。
–配置目标硬件平台的处理器类型、存储器布局等基本信息。
–配置启动方式,如通过网络(TFTP)或存储介质(SD卡、NAND Flash)等进行启动。
–配置启动流程,如引导加载程序的加载顺序、启动脚本等。
3.添加适配代码:根据目标硬件平台的需求,编写适配代码,包括引导加载程序和设备驱动等。
–引导加载程序:为目标硬件平台选择合适的程序入口点,配置启动参数,加载适配的设备驱动等。
–设备驱动:根据目标硬件平台的外设,编写相应的设备驱动代码,以支持外设的初始化和操作。
4.编译U-Boot:使用交叉编译工具链,编译修改后的U-Boot源代码。
–执行make clean清除之前的编译结果。
–执行make命令编译U-Boot源代码。
5.烧录和运行:将编译生成的U-Boot镜像烧录到目标硬件平台,并进行测试。
–根据目标硬件平台的烧录方式(串口、JTAG等),将U-Boot镜像烧录到目标设备。
–启动目标设备,观察U-Boot的启动信息是否正常输出,检查设备驱动是否正常加载。
6.调试和优化:根据实际情况,进行U-Boot的调试和性能优化。
–使用调试工具进行调试,如调试器、串口打印信息等。
AM335x U-Boot User's Guide中文手册
AM335x U-Boot User's Guide /****************************************************************** * author: 卢浩* time: 2012.09.12* environment: ubuntu10.04LTS +TI AM3359* kernel version: linux-3.2* Official Website: * QQ Group For Technology Exchange:122879839******************************************************************/ 风核科技出品—AM3359系列搭建uboot开发环境进入官方提供的SDK包的uboot目录$ cd ./AM335x-LINUX-PSP-MM.mm.pp.bb/src/u-boot/u-boot-MM.mm.pp.bb编译口令$ [ -d ./am335x ] && rm -rf ./am335x$ make O=am335x CROSS_COMPILE=arm-arago-linux-gnueabi- ARCH=arm am335x_evm编译完成将会生成可执行性文件MLO和u-boot.img。
主机配置:用串口线把主机和EVM板连接起来,设置超级终端参数如下:*Baud rate: 115,200*Data bits: 8*Parity: None*Stop bits: 1*Flow control: None开发板配置:设置启动方式:请注意,红色位置为off,绿色位置为on Nand启动,请设置拨码开关如下:SPI启动,请设置拨码开关如下:UART启动,请设置拨码开关如下:SD启动,请设置拨码开关如下:CPSW启动,请设置拨码开关如下:注意,从CPSW启动这样设置是因为EVM板用的是RGMII mode。
AM335x的linux内核移植
摘要随着时代的发展,人们的生活越来越离不开电子产品,特别是嵌入式电子产品。
嵌入式的发展越来越好,得益于硬件的发展和各类嵌入式系统的进步。
在众多的嵌入式系统中,最为让人熟悉的就是linux了。
所以,这次的课题就以linux 内核为主题,使用的开发板是TI的beaglebone white。
关键词:Linux移植,嵌入式,arm目录1.嵌入式系统的概念 (4)1.1嵌入式系统定义 (4)1.2ATMEL9200开发平台 (4)2.BootLoader简介 (4)2.1 Boot Loader概念 (4)2.2 Boot Loader启动过程 (5)2.3 常用的Bootloader…………………………………………… .52.4 u-boot移植…………………………………………………… .53.嵌入式linux操作系统 (7)3.1 嵌入式Linux (7)3.2 嵌入式Linux的特点 (7)3.3 从Linux到嵌入式Linux (8)4. 基于BeagleBone的嵌入式linux系统移植 (9)4.1 移植概念 (9)4.2 Linux与移植相关内核结构 (9)4.3 嵌入式Linux 操作系统移植 (9)5 文件系统构建 (9)6 把u-boot、linux内核、文件系统下载到SD卡中 (11)7启动开发板,链接pc,查看效果 (11)8 参考文献 (13)1.嵌入式系统的概念1.1嵌入式系统定义在信息科学技术爆炸式增长的今天,嵌入式系统早已经融入了我们生活的方方面面。
美国汽车大王福特公司的高级经理曾宣称,“福特出售的‘计算能力’已超过了IBM”。
这并不是一个哗众取宠或者夸张的说法,在真正感受这句话的震撼力之前,让我们先了解一下嵌入式系统(Embedded Systems)的定义:以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。
am335xu-boot启动过程分析
am335xu-boot启动过程分析 u-boot属于两阶段的bootloader,第⼀阶段的⽂件为 arch/arm/cpu/armv7/start.S 和 arch/arm/cpu/armv7/lowlevel_init.S,前者是平台相关的,后者是开发板相关的。
1. u-boot第⼀阶段代码分析 (1)硬件设备初始化 将CPU的⼯作模式设为管理模式(SVC); 关闭中断; 禁⽤MMU,TLB ; 板级初始化; (2)为加载Bootloader的第⼆阶段代码准备RAM空间 加载u-boot.img,跳转到u-boot.img; 上述⼯作,也就是uboot-spl代码流程的核⼼。
代码如下:arch/arm/cpu/armv7/start.S1/*2 * the actual reset code3*/4reset:5 bl save_boot_params6/*7 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,8 * except if in HYP mode already9*/10 mrs r0, cpsr11 and r1, r0, #0x1f @ mask mode bits12 teq r1, #0x1a @ test for HYP mode13 bicne r0, r0, #0x1f @ clear all mode bits14 orrne r0, r0, #0x13 @ set SVC mode15 orr r0, r0, #0xc0 @ disable FIQ and IRQ16 msr cpsr,r017@@ 以上通过设置CPSR寄存器⾥设置CPU为SVC模式,禁⽌中断18@@ 具体操作可以参考《[kernel 启动流程] (第⼆章)第⼀阶段之——设置SVC、关闭中断》的分析1920/* the mask ROM code should have PLL and others stable */21#ifndef CONFIG_SKIP_LOWLEVEL_INIT22 bl cpu_init_cp1523@@ 调⽤cpu_init_cp15,初始化协处理器CP15,从⽽禁⽤MMU和TLB。
UBoot移植详解
u-boot 移植步骤详解1 U-Boot简介U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目。
从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。
其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。
但是U-Boot不仅仅支持嵌入式Linux系统的引导,当前,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统。
其目前要支持的目标操作系统是OpenBSD, NetBSD, FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS。
这是U-Boot中Universal的一层含义,另外一层含义则是U-Boot除了支持PowerPC系列的处理器外,还能支持MIPS、x86、ARM、NIOS、XScale等诸多常用系列的处理器。
这两个特点正是U-Boot项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作系统。
就目前来看,U-Boot对PowerPC系列处理器支持最为丰富,对Linux的支持最完善。
其它系列的处理器和操作系统基本是在2002年11 月PPCBOOT 改名为U-Boot后逐步扩充的。
从PPCBOOT向U-Boot的顺利过渡,很大程度上归功于U-Boot的维护人德国DENX软件工程中心Wolfgang Denk[以下简称W.D]本人精湛专业水平和持着不懈的努力。
当前,U-Boot项目正在他的领军之下,众多有志于开放源码BOOT LOADER移植工作的嵌入式开发人员正如火如荼地将各个不同系列嵌入式处理器的移植工作不断展开和深入,以支持更多的嵌入式操作系统的装载与引导。
AM335x_Boot_From_SPI_Flash__Jffs2_FS_
TI AM335x 对从SPI Flash 启动做了很多的支持,在TI WiKi 上有很多详细的资料关于如何从SPI Flash 启动的步骤和具体做法。
如果需要在AM335x 上评估从SPI FLASH 启动,只要是有过Linux 嵌入式系统开发经验的工程师,在参考TI 的WIKI 上的资料后,可以很容易就启动对AM335x boot from SPI FLASH 的评估。
评估AM335x 从SPI FLASH 启动,从TI WIKI 上给出的资料,思路是这样的,实际验证过也是没有问题的:●编译能从SPI 启动的SPL 和U-boot,生成MLO.spi 和u-boot.bin.make ARCH=arm CROSS_COMPILE=arm-arago-linux-gnueabi- am335x_evm_spiboot注:用am335x_evm_spiboot 替代am335x_evm 编译区别主要是将环境变量存储在SPI FLASH 中而不是NAND FLASH 中。
编译u-boot 具体方法参考/index.php/AM335x_U-Boot_User%27s_Guide#Building_U-Boo t●下载MLO.spi 和u-boot.bin 到SPI FLASH 中,可以通过网口、串口、USB 口、SD Card将上一步骤中编译好的文件下载到SDRAM 中,然后通过运行的u-boot 将程序烧写到SPI FLASH 中。
(以从UART boot 为例,当将Boot Switch 切换到从UART 启动后,重新上电,串口中断会收到CCCCCCC 的提示,然后通过Teraterm 或其他串口工具将文件u-boot-spl.bin 传输给Int RAM,内部的RBL 会执行这段代码并初始化SDRAM ,然后再下载u-boot.img 到SDRAM 并执行U-Boot.)具体下载方法参考:/index.php/AM335x_U-Boot_User%27s_Guide#Flashing_image s_to_NAND_in_UART_boot_mode上面是是以Uboot 烧写Nand 为例的,但烧写SPI FLASH 的方法是一样的,只不过命令由NAND Write 改为SF Write.关于用u-boot 烧写SPI FLASH 的方法,还可参考:/index.php/AM335x_U-Boot_User%27s_Guide#SPI_2●配置Linux Kernel McSPI 接口的驱动,MTD 相关配置,以及对filesystem (Jffs2)的支持。
UBOOT移植操作
UBOOT移植操作1. 确定目标平台和硬件:首先需要了解目标平台的硬件架构、处理器类型、存储设备(如 Flash 或者 SD 卡)等重要信息。
同时需要获取目标平台的硬件参考手册或者相关文档。
2.设置交叉编译工具链:UBOOT是使用C和汇编语言编写的,因此需要使用交叉编译工具链来生成可在目标平台上运行的二进制可执行文件。
交叉编译工具链包括交叉编译器、链接器和调试器等工具,这些工具需要针对目标平台进行配置。
4. 配置 UBOOT 环境:进入 UBOOT 源代码目录,运行 `make menuconfig` 命令来配置 UBOOT 的环境。
这个命令会打开一个图形界面,可以在其中选择需要的功能、驱动程序和选项。
根据目标平台的硬件特性和需求,选择适当的选项。
5. 修改配置文件:UBOOT 需要一个配置文件(通常是`include/configs/<target.h>`),在这个文件中需要将目标平台的硬件配置信息填入。
这些信息包括芯片型号、Flash 存储器地址等。
还需要设置启动参数,如内核地址、根文件系统地址等。
6. 编译 UBOOT:运行 `make` 命令来编译 UBOOT。
根据配置和硬件平台的不同,可能需要选择不同的编译选项。
编译过程会生成一个 UBOOT 头文件(u-boot.bin)和其他必要的文件。
7.将UBOOT烧录到目标平台:使用烧录工具(如JTAG烧录器、USB烧录器或者SD卡等)将编译好的UBOOT烧录到目标平台的存储设备中。
具体的烧录方法和工具依赖于目标平台的配置。
8.测试和调试:将烧录好的UBOOT安装到目标平台后,通过串口或者网络连接到目标平台,使用终端工具进行测试和调试。
可以通过串口输出来查看启动过程中的日志和错误信息,或者使用调试工具来分析程序执行的问题。
9.优化和定制:根据需求对UBOOT进行优化和定制。
可以修改配置文件、增加功能模块或者修改代码,以达到更好的性能和适应特定需求的目的。
基于AM33x的UBootSPL的CCS调试
基于AM335x的U-Boot/SPL 的CCS 调试在基于Linux的AM335x软件开发流程中,第一步就是U-Boot/SPL (Second Program Loader)的移植。
在移植中遇到问题比较常见,而U-Boot/SPL的调试手段比较简陋,不便于迅速找到问题。
利用仿真器可以单步调试的特点,就可以迅速定位到出问题的代码所在位置,加速移植的调试过程。
本文主要介绍如何用CCS+emulator调试基于AM335x的U-Boot/SPL。
1.AM335x Linux启动过程以及U-Boot/SPL调试代码的准备1.1 AM335x Linux的启动过程AM335x Linux的启动主要包括ROM,SPL, U-Boot 和kernel四个启动步骤:A.ROM codeROM code是固化在芯片内部的代码,当上电时序正确,而且晶振等芯片启动所需的条件都具备时,AM335x会从ROM code开始运行。
ROM code首先会读取sys_boot引脚上的配置,以确定存放SPL的存储器,或者可以获取SPL的外设。
具体可以参考AM335x 中的第26章Initialization。
ROM code会从相应的地方读取/获取SPL,并运行SPL。
B.SPLSPL和U-Boot 是bootloader的两个阶段。
这里分为两个阶段的原因是, ROM code中不会配置DDR,时钟等最小系统,所以ROM code只能把bootloader加载到片上SRAM中,而片上SRAM对成本影响很大,所以通常很小,例如在AM335x上只有64K,不足够放下整个U-Boot,所以将U-Boot分成两部分,SPL和U-Boot。
SPL主要的职责就是初始化DDR,时钟等最小系统,以读取U-Boot,并加载到DDR中。
具体来看,SPL 由ROM code加载到片上SRAM的起始位置,也就是0x402F0400。
SPL会进一步对芯片进行配置,主要包括以下几个方面以完成其主要职责:a.配置ARM core。
AM335X-USB下载程序
AM335X-USB下载程序概述使⽤蚂蚁矿板BB_Black_V1.6(DDR3 256M),BB_Black_V1.5(DDR3 512M)的USB0⼝下载程序,USB-HS模式,⾃定义Bulk传输,在Windows下使⽤Libusb驱动传输平均速度可以达到3.2MB/S。
相⽐TI 官⽅原始的bootloader使⽤uart0(115200波特率) xmodem协议的⽅式,下载速度提升明显。
硬件改造焊接mini usb⼝,可以使⽤下⾯这款usb座⼦(需要⽤⼑把底部两个塑料凸起削掉),嘉⽴创可以买到。
飞线,使usb的供电进⼊主板SYS_5V。
(下⾯的原理图跨了两页,详细请参考官⽅的BBB_SCH.pdf)改造完毕。
下载地址:下载完成后,你将得到4个⽂件:antminer.exe 运⾏在Windows平台的下载⼯具boot.bin AM335X BOOTROM加载到处理器内部SRAM的⼆级引导程序(SPL),该⽂件⽆tiimage⽂件头boot_ti.bin AM335X BOOTROM加载到处理器内部SRAM的⼆级引导程序(SPL),该⽂件添加了tiimage⽂件头zadig-2.5.exe Windows下⽤以安装libusb驱动的程序,libusb将usb底层操作暴露到⽤户态程序,使usb驱动编写更为简单。
对于有TF卡的⽤户,按照https:///yanye0xff/p/15037231.html的⽅法制作⼀张可以被AM335X BOOTROM识别的启动TF卡,然后把boot_ti.bin改名为MLO放到TF卡内即可。
将TF卡插⼊蚂蚁矿板的卡槽中,然后接上mini-usb线,按下POWER按钮上电(此处Power按钮我未焊接,⽤的镊⼦短接,有条件可以焊个上去)。
如果插好TF卡后,先使⽤DC-5V供电,再插mini-usb线,就不需要按POWER按钮上电了,蚂蚁矿板会⾃动上电。
只插UBS供电情况下,⽤镊⼦短接Power上电,USB-Bootloader启动完成USER LED0会⾃动亮起。
Uboot移植--支持yaffs2,TFTP菜单制作,支持Xmodem
Uboot移植--支持yaffs2,TFTP菜单制作,支持XmodemUboot移植--支持yaffs2,TFTP菜单制作,支持Xmodem 一,支持下载yaffs2文件系统1、在include/configs/apple2440.h头文件中定义一个管理对Yaffs2支持的宏和开启u-boot中对Nand Flash默认分区的宏,如下:gedit include/configs/apple2440.h//定义一个管理对Yaffs2支持的宏#define CONFIG_MTD_NAND_YAFFS2 1//开启Nand Flash默认分区,注意此处的分区要和你的内核中的分区保持一致#define MTDIDS_DEFAULT "nand0=nandflash0"#define MTDPARTS_DEFAULT"mtdparts=nandflash0:256k(bootloader)," \"3m(kernel)," \"-(root)"2、在原来对Nand操作的命令集列表中添加Yaffs2对Nand 的写命令,如下:gedit common/cmd_nand.c在函数U_BOOT_CMD中添加如下://注意:这里只添加了yaffs2的写命令,因为我们只用u-boot 下载(即写)功能,所以我们没有添加yaffs2读的命令U_BOOT_CMD(nand, CONFIG_SYS_MAXARGS, 1,do_nand,"NAND sub-system","info - show available NAND devices\n""nand device [dev] - show or set current device\n""nand read - addr off|partition size\n""nand write - addr off|partition size\n"" read/write 'size' bytes starting at offset 'off'\n"" to/from memory address 'addr', skipping bad blocks.\n" //注意:这里只添加了yaffs2的写命令,因为我们只用u-boot下载(即写)功能,所以我们没有添加yaffs2读的命令#if defined(CONFIG_MTD_NAND_YAFFS2)"nand write[.yaffs2] - addr off|partition size - write`size' byte yaffs image\n"" starting at offset off' from memory address addr' (.yaffs2 for 512+16 NAND)\n"#endif"nand erase [clean] [off size] - erase 'size' bytesfrom\n"" offset 'off' (entire device if not specified)\n""nand bad - show bad blocks\n""nand dump[.oob] off - dump page\n""nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n""nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n""nand biterr off - make a bit error at offset (UNSAFE)" #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK"\n""nand lock [tight] [status]\n"" bring nand to lock state or display locked pages\n""nand unlock [offset] [size] - unlock section"#endif);3,接着,在该文件中对nand操作的do_nand函数中添加yaffs2对nand的操作,如下:if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0){int read; if (argc < 4)goto usage; addr =(ulong)simple_strtoul(argv[2], NULL, 16); read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */printf("\nNAND %s: ", read ? "read" : "write");if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0)return 1; s = strchr(cmd, '.');if (!s || !strcmp(s, ".jffs2") || !strcmp(s, ".e")|| !strcmp(s, ".i")){if (read)ret = nand_read_skip_bad(nand, off,&size, (u_char *)addr);elseret = nand_write_skip_bad(nand, off,&size, (u_char *)addr);} //添加yaffs2相关操作,注意该处又关联到nand_write_skip_bad函数#ifdefined(CONFIG_MTD_NAND_YAFFS2)else if (s != NULL && (!strcmp(s,".yaffs2"))){nand->rw_oob = 1;nand->skipfirstblk = 1;ret =nand_write_skip_bad(nand,off,&size,(u_char *)addr);nand->skipfirstblk = 0;nand->rw_oob = 0;}#endif else if (!strcmp(s, ".oob")){/* out-of-band data */mtd_oob_ops_t ops ={.oobbuf = (u8 *)addr,.ooblen = size,.mode = MTD_OOB_RAW}; if (read)ret = nand->read_oob(nand, off,&ops);elseret = nand->write_oob(nand, off,&ops);}else{printf("Unknown nand command suffix'%s'.\n", s);return 1;} printf(" %zu bytes %s: %s\n", size, read ? "read" : "written", ret ? "ERROR" : "OK");return ret == 0 ? 0 : 1;}在include/linux/mtd/mtd.h头文件的mtd_info结构体中添加上面用到rw_oob和skipfirstblk数据成员,如下:#gedit include/linux/mtd/mtd.h //在mtd_info结构体中添加#if defined(CONFIG_MTD_NAND_YAFFS2)u_char rw_oob;u_char skipfirstblk;#endif在第二步关联的nand_write_skip_bad函数中添加对Nand OOB的相关操作,如下:#gedit drivers/mtd/nand/nand_util.c //在nand_write_skip_bad函数中添加int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, u_char *buffer){int rval;size_t left_to_write = *length;size_t len_incl_bad;u_char *p_buffer = buffer; #ifdefined(CONFIG_MTD_NAND_YAFFS2) //add yaffs2 file system supportif(nand->rw_oob==1){size_t oobsize = nand->oobsize;size_t datasize = nand->writesize;int datapages = 0; if(((*length)%(nand->oobsize+nand->writesize)) != 0) {printf ("Attempt to write error length data!\n");return -EINVAL;} datapages = *length/(datasize+oobsize);*length = datapages*datasize;left_to_write = *length;}#endif /* Reject writes, which are not page aligned */ if ((offset & (nand->writesize - 1)) != 0 ||(*length & (nand->writesize - 1)) != 0) {printf ("Attempt to write non page aligned data\n");return -EINVAL;} len_incl_bad = get_len_incl_bad (nand, offset, *length); if ((offset + len_incl_bad) >=nand->size) {printf ("Attempt to write outside the flash area\n");return -EINVAL;} #if !defined(CONFIG_MTD_NAND_YAFFS2) //add yaffs2 file system supportif (len_incl_bad == *length) {rval = nand_write (nand, offset, length, buffer);if (rval != 0)printf ("NAND write to offset %llxfailed %d\n",offset, rval); return rval;}#endif while (left_to_write > 0) {size_t block_offset = offset &(nand->erasesize - 1);size_t write_size; WATCHDOG_RESET (); if (nand_block_isbad (nand, offset &~(nand->erasesize - 1))) {printf ("Skip bad block 0x%08llx\n",offset & ~(nand->erasesize - 1));offset += nand->erasesize - block_offset;continue;} #if defined(CONFIG_MTD_NAND_YAFFS2)//add yaffs2 file system supportif(nand->skipfirstblk==1){nand->skipfirstblk=0;printf ("Skip the first good block %llx\n", offset & ~(nand->erasesize - 1));offset += nand->erasesize - block_offset;continue;}#endif if (left_to_write < (nand->erasesize - block_offset))write_size = left_to_write;elsewrite_size = nand->erasesize -block_offset; printf("\rWriting at 0x%llx -- ",offset); //add yaffs2 file system supportrval = nand_write (nand, offset, &write_size, p_buffer);if (rval != 0) {printf ("NAND write to offset %llxfailed %d\n",offset, rval);*length -= left_to_write;return rval;} left_to_write -= write_size;printf("%d%% iscomplete.",100-(left_to_write/(*length/100)));offset += write_size; #ifdefined(CONFIG_MTD_NAND_YAFFS2) //add yaffs2 file system supportif(nand->rw_oob==1){p_buffer +=write_size+(write_size/nand->writesize*nand->oobsize);}else{p_buffer += write_size;}#elsep_buffer += write_size;#endif } return 0;}在上一步nand_write_skip_bad函数中我们看到又对nand_write函数进行了访问,所以这一步是到nand_write 函数中添加对yaffs2的支持,如下:#geditdrivers/mtd/nand/nand_base.c //在nand_write函数中添加static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const uint8_t *buf){struct nand_chip *chip = mtd->priv;int ret; #if defined(CONFIG_MTD_NAND_YAFFS2)//add yaffs2 file system support int oldopsmode = 0; if(mtd->rw_oob==1){int i = 0;int datapages = 0; size_t oobsize =mtd->oobsize;size_t datasize = mtd->writesize;uint8_t oobtemp[oobsize];datapages = len / (datasize); for(i = 0; i < (datapages); i++){memcpy((void *)oobtemp, (void *)(buf + datasize * (i + 1)), oobsize);memmove((void *)(buf + datasize * (i + 1)), (void *)(buf + datasize * (i + 1) + oobsize), (datapages - (i + 1)) * (datasize) + (datapages - 1) * oobsize);memcpy((void *)(buf+(datapages) * (datasize + oobsize) - oobsize), (void *)(oobtemp), oobsize);}}#endif /* Do not allow reads past end of device */ if ((to + len) > mtd->size)return -EINVAL;if (!len)return 0; nand_get_device(chip, mtd,FL_WRITING); chip->ops.len = len;chip->ops.datbuf = (uint8_t *)buf; #ifdefined(CONFIG_MTD_NAND_YAFFS2) //add yaffs2 file system support if(mtd->rw_oob!=1){chip->ops.oobbuf = NULL;}else{chip->ops.oobbuf = (uint8_t *)(buf + len);chip->ops.ooblen = mtd->oobsize;oldopsmode = chip->ops.mode;chip->ops.mode = MTD_OOB_RAW;}#elsechip->ops.oobbuf = NULL;#endif ret = nand_do_write_ops(mtd, to,&chip->ops); *retlen = chip->ops.retlen; nand_release_device(mtd); #ifdefined(CONFIG_MTD_NAND_YAFFS2) //add yaffs2 file system support chip->ops.mode = oldopsmode;#endif return ret;}OK,对yaffs2支持的代码已修改完毕,重新编译u-boot 并下载到nand中,启动开发板,在u-boot的命令行输入:nand help查看nand的命令,可以看到多了一个nand write[.yaffs2]的命令,这个就是用来下载yaffs2文件系统到nand中的命令了。
AM3359之UBOOT
AM3359之UBOOTAM3359之U-boot编译2012-10-31 14:28:13分类: LINUX我用的PC主机是ubuntu12.04 LST 64位系统给出官方软件下载地址:软件下载ti-sdk-am335x-evm-05.05.00.00-Linux-x86-Install,下完之后安装,安装的时候自己指定一个位置,安装完后安装目录下面的文件:bin linux-devkitboard-support Makefiledocs Rules.makeexample-applications setup.shfilesystem targetNFSGraphics_SDK_setuplinux_4_06_00_02.bin targetNFS.103120 12_13.54host-tools以上文件的作用及内容在说明文档中有,这里就不细说了。
进入board-support文件夹board-port-labs linux-3.2.0-psp04.06.00.08.sdk u-boot-2011.09-psp04.06.00.08extra-drivers prebuilt-images其中u-boot-2011.09-psp04.06.00.08就是u-boot源码,进入该文件夹。
指定交叉编译器export PATH=/home/gavin/ti-sdk-am335x-evm-05.05.00.00/linux-devkit/bin:$PATH该交叉编译器是这个版本SDK包自带的。
执行arm-arago-linux-gnueabi-gcc -v可以查看版本信息,如果安装成功会显示版本号等信息。
make clean 一下:$ make CROSS_COMPILE=arm-arago-linux-gnueabi- ARCH=arm distclean配置make am335x_evm_config编译make CROSS_COMPILE=arm-arago-linux-gnueabi- ARCH=arm几分钟就可以编译完成。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
AM335x uboot 移植2013-06-11 22:36:39| 分类:am335x-艾默生 | 标签:uboot am335x 移植|举报|字号订阅uBOOT的编译命令直接一次性编译make O=am335x CROSS_COMPILE=arm-arago-linux-gnueabi ARCH=armam335x_evm配置make ARCH=arm CROSS_COMPILE=arm-arago-linux-gnueabi- am335x_evm_config编译make ARCH=arm CROSS_COMPILE=arm-arago-linux-gnueabi-清理make clean ARCH=arm CROSS_COMPILE=arm-arago-linux-gnueabi-make distclean ARCH=arm CROSS_COMPILE=arm-arago-linux-gnueabi-编译器环境变量的设置这个环境变量是TI的SDK包里面带的编译器,不是之前的arm-gcc-export PATH=$PATH:/mnt/disk1/ti-sdk-am335x-evm-05.05.00.00/linux-devkit/bin/UBOOT里面的MLO(u-boot-spl)如果使用NAND启动,那么这个文件就是相当于NBOOT,进行第一次的引导这个MLO实际上就是u-boot-spl.bin生成的,在编译完uboot后,SPL的目录里面会产生了许多的.o文件,这里文件就是uboot的文件,可以打开Makefile,有一些对应的宏定义,可以取消,减少MLO文件的大小UBOOT的链接脚本ldsUBOOT\arch\arm\cpu\armv7\u-boot.lds正常运行UBOOT的ldsUBOOT\arch\arm\cpu\armv7\omap-common\u-boot.lds这个是nboot,加载uboot用有2个lds,不同的作用,注意要区别开增加新的单板支持在boards.cfg文件中,找到加入,例如单板名字 arm armv7 对应board的目录 ti ti81xx以后就可以执行make 单板名字来生成uboot,这里被ti改写了,所以不是原版的uboot生成方法一些代码的定位u-boot-2011.09-psp04.06.00.08/arch/arm/cpu/armv7这个目录下的几个文件,start.s这个是程序的入口执行文件u-boot-2011.09-psp04.06.00.08/arch/arm/cpu/armv7/omap-commonu-boot-2011.09-psp04.06.00.08/arch/arm/cpu/armv7/ti81xx这2个目录是和平台板子相关,AM335X是ti81xx的版本以上都是和CPU有关u-boot-2011.09-psp04.06.00.08/arch/libARM平台的公用代码u-boot-2011.09-psp04.06.00.08/lib通用的库代码,无论什么平台都编译board/ti/xxx 这个目录就是单板的配置Makefile文件分析在终端中输入后make ARCH=arm CROSS_COMPILE=arm-arago-linux-gnueabi- am335x_evm_config 命令后,会生成3个文件1、.boards.depend2、include/config.h/* Automatically generated - do not edit */#define CONFIG_BOARDDIR board/ti/am335x#include <config_cmd_defaults.h>#include <config_defaults.h>#include <configs/am335x_evm.h>#include <asm/config.h>3、include/config.mkARCH = armCPU = armv7BOARD = am335xVENDOR = tiSOC = ti81xx终端中会输出awk '(NF && $1 !~ /^#/) { print $1 ": " $1 "_config; $(MAKE)" }'boards.cfg > .boards.dependConfiguring for am335x_evm board...支持的配置am335x配置有am335x_evmam335x_evm_restore_flasham335x_evm_spiboot解析Makefile文件,sinclude $(obj).boards.depend$(obj).boards.depend: boards.cfgawk '(NF && $$1 !~ /^#/) { print $$1 ": " $$1 "_config; $$(MAKE)" }' $< > $@我们搜索am335x_evm并没有在makefile文件中找到对应的关键字,但是发现boards.cfg 中有此关键词,可能am335x_evm_config输入后,是到boards.cfg中寻找的通过TI CCS调试uboot通过makefile文件建立ccs工程1、打开CCS,选择File->New->Project2、打开新建窗口后,选择c/c++下的Makefile Project with Existing Code3、点击下一步,选择uboot的存放的目录,然后点击完成4、等待右下角的进度,一直到达100%后,在继续操作5、最后在属性设置里,取消C的自动编译调试的时候,如果目标代码是汇编,则不会现实源码,只有C才会现实出uboot的代码运行流程u-boot-2011.09-psp04.06.00.08/arch/arm/cpu/armv7start.s 入口运行文件bl save_boot_params跳转到lowlevel_init.S该文件在(arch\arm\cpu\armv7\omap-common) ,如果是MLO则会定义CONFIG_SPL_BUILD宏,uboot没有定义,保存CPU ROM的参数到一个地方中bl cpu_init_crit SPL里面调用,初始化底层相关的(函数就在本文件中最下面)bl lowlevel_init 保存旧的堆栈指针,设置新的堆栈指针在lowlevel_init.S (arch\arm\cpu\armv7\omap-common)文件中bl s_init 此函数在Evm.c (board\ti\am335xwecon)文件中,不同的平台初始化不同的内容初始化堆栈指针跳转到C语言,board_init_f,C 言从个函数开始行语这执board_init_f 在Board.c (arch\arm\lib)文件中init_sequence数,行初始化组继续进relocate_code 函数,重新回到汇编start.s文件中relocate_code:在start.s文件中主要了实现uboot的重新定位代,和码bss段的清零ldr r0, _board_init_r_ofs 通个方式取过这获board_init_r函数入口adr r1, _startadd lr, r0, r1mov pc, lr 最后里个到这C函数,board_init_r里面board_init_r 第2 段的初始化,在阶board.c文件中enable_caches 个函数没有做什么内容这board_init 第2次初始化平台,里可以初始化其他内容了,和平台相关这mem_malloc_init 初始化malloc内存nand_init 初始化NAND(CONFIG_CMD_NAND需要定)义mmc_initialize 初始化SD(CONFIG_GENERIC_MMC需要定)义/drivers/mmc/mmc.c文件中board_mmc_init 平台相关omap_mmc_init(ID)/drivers/mmc/omap_hsmmc.c文件中env_relocate 初始化境量环变/common/env_common.c文件中stdio_initjumptable_initconsole_init_rmisc_init_r 平台相关,目前不知道什么用interrupt_initenable_interruptseth_initialize(gd->bd); 初始化以太网/net/eth.c文件中board_eth_init 平台相关的代中码cpsw_register /driver/net/cpsw.c 注册一个以太网设备main_loop(); 入控制台进init_sequence数里的内容组#if defined(CONFIG_ARCH_CPU_INIT)arch_cpu_init, /* basic arch cpu dependent setup */#endif#if defined(CONFIG_BOARD_EARLY_INIT_F)board_early_init_f,#endiftimer_init, Timer.c (arch\arm\cpu\armv7\omap-common)默的定器,开始运行认时刚uboot ,那个倒多少后按空格入时计时时间进uboot#ifdef CONFIG_FSL_ESDHCget_clocks,#endifenv_init, Env_nand.c (common) uboot默的参数,都在里初始化认这init_baudrate, 本文件中,初始化uboot使用的默的串口波特率认serial_init, Serial.c (drivers\serial)初始化串口,在UBOOT中,使用的默串口名认字是叫NS16550,可能是因原来就存在此代的故,然后用了为码缘继续调ns16550.c里面的函数初始化串口console_init_f, Console.c (common)初始化控制台display_banner, 本文件中,出一些信息,代表运行到了里输这#if defined(CONFIG_DISPLAY_CPUINFO)print_cpuinfo, /* display cpu info (and speed) */#endif#if defined(CONFIG_DISPLAY_BOARDINFO)checkboard, /* display board info */#endif#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)init_func_i2c, 本文件中,初始化IIC,然后用继续调Omap24xx_i2c.c (drivers\i2c),具体的CPU IIC初始化的实现#endifdram_init, /* configure available RAM banks */UBOOT用到的结构体register volatile gd_t *gd asm ("r8")此结构体记录了UBOOT所有的参数内容typedef struct global_data {bd_t *bd; 个是一个构体这还结unsigned long flags;unsigned long baudrate; UBOOT串口端所使用的串口波特率终unsigned long have_console; 串口控制台是否初始化?过=1初始化过//UBOOT 境量相关的量环变变unsigned long env_addr; 个是地址,存放了这uboot使用的境量参数存放在内环变存中的地址,例如了对应记录uboot的ip地址,入进uboot默的延等,和认时时间default_environment 起来对应unsigned long env_valid; 默的境量是否有效,认环变=1代表有效unsigned long fb_base;/* base address of frame buffer */#ifdef CONFIG_FSL_ESDHCunsigned long sdhc_clk;#endif#ifdef CONFIG_AT91FAMILY/* "static data" needed by at91's clock.c */unsigned long cpu_clk_rate_hz;unsigned long main_clk_rate_hz;unsigned long mck_rate_hz;unsigned long plla_rate_hz;unsigned long pllb_rate_hz;unsigned long at91_pllb_usb_init;#endif#ifdef CONFIG_ARM/* "static data" needed by most of timer.c on ARM platforms */unsigned long timer_rate_hz;unsigned long tbl;unsigned long tbu;unsigned long long timer_reset_value;unsigned long lastinc;#endif#ifdef CONFIG_IXP425unsigned long timestamp;#endifunsigned long relocaddr; /* Start address of U-Boot in RAM */phys_size_t ram_size; 内存的大小unsigned long mon_len; uboot整个bin文件的大小代码段+bss段unsigned long irq_sp; IRQ中断堆指栈针unsigned long start_addr_sp; /* start_addr_stackpointer */unsigned long reloc_off;#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) unsigned long tlb_addr;#endifvoid **jt; /* jump table */char env_buf[32];/* buffer for getenv() before reloc. */} gd_t;typedef struct bd_info {int bi_baudrate; 串口控制台波特率unsigned long bi_ip_addr; IP地址ulong bi_arch_number; 传递给LINUX内核,告诉当前是板子的IDulong bi_boot_params; 传递给linux 内核,告诉其参数存放的位置struct /* RAM configuration */{ulong start;ulong size;}bi_dram[CONFIG_NR_DRAM_BANKS];这个用于给LINUX传递启动信息的,内存大小和起始地址,如果有多块内存,则这个变量是一个数组} bd_t;SPL的代码/arch/arm/cpu/armv7/start.s 入口/arch/arm/cpu/armv7/omap-common C文件,Uboot的重定位relocate_code: 要有pie选项(arm-linux-ld命令中)movr4, r0 /* save addr_sp */ 新的堆栈地址movr5, r1 /* save addr of gd */ gd_t变量的内容地址,因为重定位后,这个地址会改变movr6, r2 /* save addr of destination */ 目标地址/* Set up the stack */stack_setup:movsp, r4 设置堆栈adr r0, _start uboot的起始运行地址cmpr0, r6moveq r9, #0 /* no relocation. relocation offset(r9) = 0 */ 如果代码段已经是目标了,那么不要复制了直接跳转到clear_bssbeqclear_bss /* skip relocation */movr1, r6 /* r1 <- scratch for copy_loop */ 代码段的目标地址ldr r3, _image_copy_end_ofs 要复制的长度addr2, r0, r3 /* r2 <- source end address */ 代码段的结束地址开始循环复制代码段copy_loop:ldmia r0!, {r9-r10} /* copy from source address [r0] */stmia r1!, {r9-r10} /* copy to target address [r1] */cmpr0, r2 /* until source end address [r2] */blo copy_loop重定位代码,修改代码为新的地址#ifndef CONFIG_SPL_BUILDR0是目标内存,修改后放入目标的内存中ldr r0, _TEXT_BASE /* r0 <- Text base */ 代码段的基地址sub r9, r6, r0 /* r9 <- relocation offset */ 重定位的偏移值 r9=代码段目标地址–代码段的基地址ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ r10=动态起始地址addr10, r10, r0 /* r10 <- sym table in FLASH */ r10 = 动态符号表的目标存放地址r2是rel_dyn段的内容,这个段就是代表要修改的数据.这个段都是放一个要修改的值,然后放一个标记.偏移值分为两种:相对位移和绝对位移ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ 要修改地址的信息的一些变量都放在这里addr2, r2, r0 /* r2 <- rel dyn start in FLASH */r3是放结束的地址,用来判断是否结束ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */addr3, r3, r0 /* r3 <- rel dyn end in FLASH */fixloop:从R2取出要修改的值,ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */addr0, r0, r9 /* r0 <- location to fix up in RAM */从R2的下一个位置读取一个值,这个值是用来判断是运行fixrel还是fixabs用ldr r1, [r2, #4]andr7, r1, #0xff这里判断是相对位移还是绝对位移,然后修改cmpr7, #23 /* relative fixup? */beqfixrelcmpr7, #2 /* absolute fixup? */beqfixabs/* ignore unknown type of fixup */b fixnextfixabs: 修改绝对位移,就是运行前才可以确定的/* absolute fix: set location to (offset) symbol value */movr1, r1, LSR #4 /* r1 <- symbol index in .dynsym */addr1, r10, r1 /* r1 <- address of symbol in table */ldr r1, [r1, #4] /* r1 <- symbol value */addr1, r1, r9 /* r1 <- relocated sym addr */b fixnextfixrel: 修改相对位移,编译时就确定了地址/* relative fix: increase location by offset */ldr r1, [r0]addr1, r1, r9fixnext: 写入本次修改的内容,判断是否运行完成,str r1, [r0] 将r1写入目标内存addr2, r2, #8 /* each rel.dyn entry is 8 bytes */cmpr2, r3 判断是否结束,blo fixloop 没有结束,继续循环b clear_bss 结束了#endif /* #ifndef CONFIG_SPL_BUILD */uboot命令环境变量printenv 打印当前的环境变量运行gobootm 0x82000000boot - boot default, i.e., run 'bootcmd'根据bootcmd环境变量运行命令bootd - boot default, i.e., run 'bootcmd' 根据bootcmd环境变量运行命令nand flash以太网ping 192.168.1.2 tftp。