Freescale i.MX 6Q平台移植Android MNC

来源:互联网 发布:lol鼠标宏编程走a设置 编辑:程序博客网 时间:2024/05/21 14:49

公司一项目,用的是Freescalei.MX 6Q芯片,之前用的是Yocto系统。Linux+ Qt的架构。有客户希望使用Android平台。所以接到移植的要求。首次接触Freescale平台,所以问题很多。一切都是空白。记录一下移植过程。

 

       基本配置:Freescalei.MX 6Q + 1G DDR3 RAM +  8G eMMC.

 

代码下载

       先到Freescale的网站下载最新的文件及BSP代码。如果之前没有注册帐号,则需要先注册一个帐号。

http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/i.mx-applications-processors/i.mx-6-processors/i.mx6qp/i.mx-6-series-software-and-development-tool-resources:IMX6_SW

 

       当前最新的AndroidBSP版本为android M6.0.1_1.0.0。把文档下载下来。参考Android_User’s_Guide.pdf,下载AOSP部分的代码。

       mkdirmyandroid

mkdir bin

cd myandroid

curlhttps://storage.googleapis.com/Git-repo-downloads/repo > ~/bin/repo

chmod a+x ~/bin/repo

~/bin/repo init -uhttps://android.googlesource.com/platform/manifest -b android-6.0.1_r3

~/bin/repo sync

 

       上面的目录名自己可以随便定,没必要按文档上的来。U-boot和Kernel的代码是单独的,从Freescale的代码站上通过git clone下载。

       cd ~/myandroid

git clonegit://git.freescale.com/imx/linux-2.6-imx.git kernel_imx

cd kernel_imx

git checkout m6.0.1_1.0.0-ga

 

cd ~/myandroid/bootable

cd bootloader

git clonegit://git.freescale.com/imx/uboot-imx.git uboot-imx

cd uboot-imx

git checkout m6.0.1_1.0.0-ga

 

       相对路径按照此要求,分别放在bootable/bootloader下及项目根目录下。

 

       由于从Google源码repo下载的是AOSP代码,所以还需要加上Freescale的BSP代码,Freescale是通过Patch的形式提供的,从Freescale上下载Patch文件:android_M6.0.1_1.0.0_core_source.tar.gz,根据User’s Guide文档进行操作。

cd ~/myandroid

source~/android_M6.0.1_1.0.0_core_source/code/M6.0.1_1.0.0/and_patch.sh

c_patch /opt/android_M6.0.1_1.0.0_core_source/code/M6.0.1_1.0.0/imx_M6.0.1_1.0.0

 

       注意:执行此命令时,代码库中必须保留有.repo/.git这些信息,否则将无法进行。之前手快了点,直接把它删除了,只好重新下载了一次。

 

       以上执行完毕后,源代码下载工作就算完成了。

 

编译环境准备

       由于之前编译环境已经就绪,所以环境就不介绍了,需要注意的是Android 5.0之后的版本要求Open Java7,所以请安装Java 7

sudo apt-get update

sudo apt-get install openjdk-7-jdk

exportJAVA_HOME=/usr/lib/jvm/Java-7-openjdk-amd64/

 

sudo apt-get install lzop u-boot-tools

 

编译

       环境准备完毕之后,就可以先编译一下,看看有没有问题。调试阶段所以用Engineer Mode编译。

 

       source build/envsetup.sh

lunch sabrese_6dq-eng

make 2>&1 | tee build-log.txt

 

下载

       编译过程视机器配置而定,可能需要几十分钟到几小时不等。由于到目前为止什么也没有配置,所以生成的版本肯定不能运行,所以下载时还不能用编译生成的U-BOOT及Kernel。还好,之前Yocto的版本是可用的,所以先用之前版本的U-Boot+Kernel进行下载。

 

       配置mfgtools,在此用的mfgtools版本是2.6版本,首先修改工具根目录下的cfg.ini,把配置改为eMMC-Android

[LIST]

name = eMMC-Android

 

       修改同目录下的mfgtools-android-mx6q-sabresd-emmc.vbs文件。修改两个内容,把soc改为6q,mmc改为0。如下:

Set wshShell = CreateObject("WScript.shell")

wshShell.run "mfgtool2.exe -c""linux"" -l ""eMMC-Android"" -s""board=sabresd""  -s""folder=sabresd"" -s ""soc=6q""-s ""mmc=0"" -s ""data_type="""

Set wshShell = Nothing

 

       然后修改Linux/OSFirmware/ucl2.xml文件。这个文件里配置了很多平台的支持,从MX6SL到MX7D等。我们只需要关心MX6Q,找到eMMC-Android部分。先把前面U-boot/Kernel配置修改为老的版本,我们把这些文件放在firmware/old目录下。

       <!--CMD state="BootStrap"type="boot" body="BootStrap" file ="firmware/u-boot-imx6q%plus%%board%_sd.imx"ifdev="MX6Q">Loading U-boot</CMD-->

       <CMD state="BootStrap"type="boot" body="BootStrap" file ="firmware/old/u-boot-mx6q-old-mfg.bin"ifdev="MX6Q">Loading U-boot</CMD>

       <!--CMD state="BootStrap"type="boot" body="BootStrap" file="firmware/u-boot-imx6dl%board%_sd.imx"ifdev="MX6D">Loading U-boot</CMD>

       <CMD state="BootStrap"type="boot" body="BootStrap" file="firmware/u-boot-imx6qsabresd_sd.imx"ifdev="MX6D">Loading U-boot</CMD>

       <CMD state="BootStrap"type="boot" body="BootStrap" file="firmware/u-boot-imx6sx%board%_emmc.imx"ifdev="MX6SX">Loading U-boot</CMD>

       <CMD state="BootStrap"type="boot" body="BootStrap" file="firmware/u-boot-imx7d%7duboot%_sd.imx" ifdev="MX7D">LoadingU-boot</CMD>

       <CMD state="BootStrap"type="boot" body="BootStrap" file="firmware/u-boot-imx6ul%6uluboot%_emmc.imx"ifdev="MX6UL">Loading U-boot</CMD-->

 

       <CMD state="BootStrap"type="load" file="firmware/old/uImage-mx6q-old-mfg"address="0x10800000"

              loadSection="OTH"setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6QMX6D">Loading Kernel.</CMD>

 

       <CMD state="BootStrap"type="load"file="firmware/fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot"address="0x10C00000"

       另外,Kernel的运行地址也不正确,根据编译里链接的位置,改为0x10800000。无关的配置可以删除或屏蔽掉。initramfs由于之前的项目没有这个文件,所以用默认的,把地址改为0x10C00000。DTD文件也没有,所以暂时也可以屏蔽掉。

 

       测试下载,LoadingKernel, Jumping to OS Image正确,串口可以出信息,下一步是分区,format_android报错,看来是mksdcard-android.sh.tar文件旧的版本支持不完善。暂时把format_android步骤屏蔽。

 

       再往下FormatingPartition报错,说没有相应设备,用ls也的确没有列出相就的设备来。看来执行脚本没有作用。用较原始的方法,一条条命令来建立设备。先擦除:

       <CMD state="Updater"type="push" body="mknodblock,mmcblk0,/dev/mmcblk0,block"/>

       <CMD state="Updater"type="push" body="$ mknod /dev/zero c 1 5"/>

     <CMDstate="Updater" type="push" body="$ dd if=/dev/zeroof=/dev/mmcblk0 bs=128M count=1"> Erasing MBR and kernelparameters...</CMD>

 

       把U-Boot烧写到首块:

       <CMD state="Updater"type="push" body="send"file="files/android/%folder%/u-boot-imx%soc%%plus%.imx" >Sendingu-boot.imx</CMD>

      

       <CMD state="Updater"type="push" body="$ dd if=$FILE of=/dev/mmcblk%mmc% bs=1k seek=1conv=fsync">write U-Boot to eMMC</CMD>

 

       建立Boot分区:

     <CMDstate="Updater" type="push" body="mknodblock/mmcblk0,mmcblk0p1,/dev/mmcblk0p1,block"/>

 

       把Boot.img写到Boot分区:

       <CMD state="Updater"type="push" body="send"file="files/android/%folder%/boot-imx%soc%%plus%%ldo%.img">Sending and writting boot.img</CMD>

      

       <CMD state="Updater"type="push" body="$ dd if=$FILEof=/dev/mmcblk%mmc%p1">write boot.img</CMD>

 

       建立其它分区设备:

       <CMD state="Updater"type="push" body="mknodblock/mmcblk%mmc%,mmcblk%mmc%p4,/dev/mmcblk%mmc%p4,block"/>

       <CMD state="Updater"type="push" body="mknodblock/mmcblk%mmc%,mmcblk%mmc%p5,/dev/mmcblk%mmc%p5,block"/>

       <CMD state="Updater"type="push" body="mknod block/mmcblk%mmc%,mmcblk%mmc%p6,/dev/mmcblk%mmc%p6,block"/>

       <CMD state="Updater"type="push" body="mknodblock/mmcblk%mmc%,mmcblk%mmc%p7,/dev/mmcblk%mmc%p7,block"/>

 

       这样之后的格式化过程就可以顺利进行了。由于缺少经验,下载过程折腾了近一天才基本搞定。而且还是参考了一下之前一个Freescale i.MX6DL Android 5.0项目的配置。列一个较完整的配置,供参考:

<LISTname="eMMC-Android" desc="Choose eMMC as media">

       <CMD state="BootStrap"type="boot" body="BootStrap" file="firmware/old/u-boot-mx6q-old-mfg.bin"ifdev="MX6Q">Loading U-boot</CMD>

 

       <CMD state="BootStrap"type="load" file="firmware/old/uImage-mx6q-old-mfg"address="0x10800000"

              loadSection="OTH"setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6QMX6D">Loading Kernel.</CMD>

 

       <CMD state="BootStrap"type="load"file="firmware/fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot"address="0x10C00000"

              loadSection="OTH"setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6QMX6D">Loading Initramfs.</CMD>

 

       <CMD state="BootStrap"type="load"file="firmware/zImage-imx6q%plus%-%board%%ldo%.dtb"address="0x18000000"

              loadSection="OTH" setSection="OTH"HasFlashHeader="FALSE" ifdev="MX6Q">Loading devicetree.</CMD>

 

       <CMD state="BootStrap"type="jump" > Jumping to OS image. </CMD>

 

      <!--create partition -->

       <CMD state="Updater"type="push" body="send"file="mksdcard-android%data_type%.sh.tar">Sending partitionshell</CMD>

       <CMD state="Updater"type="push" body="$ tar xf $FILE ">Partitioning...</CMD>

       <CMD state="Updater"type="push" body="mknodblock,mmcblk0,/dev/mmcblk0,block"/>

       <CMD state="Updater"type="push" body="$ mknod /dev/zero c 1 5"/>

     <CMDstate="Updater" type="push" body="$ dd if=/dev/zeroof=/dev/mmcblk0 bs=128M count=1"> Erasing MBR and kernelparameters...</CMD>

       <CMD state="Updater"type="push" body="$ sh mksdcard-android%data_type%.sh/dev/mmcblk0"> Partitioning...</CMD>

      

       <!-- burn uboot -->

       <CMD state="Updater"type="push" body="send"file="files/android/%folder%/u-boot-imx%soc%%plus%.imx" >Sendingu-boot.imx</CMD>

      

       <CMD state="Updater"type="push" body="$ dd if=$FILE of=/dev/mmcblk%mmc% bs=1k seek=1conv=fsync">write U-Boot to eMMC</CMD>

 

       <CMD state="Updater"type="push" body="$ ls -l /dev/mmc* ">Formatting sdpartition</CMD>

 

     <CMDstate="Updater" type="push" body="mknodblock/mmcblk0,mmcblk0p1,/dev/mmcblk0p1,block"/>

       <CMD state="Updater"type="push" body="send"file="files/android/%folder%/boot-imx%soc%%plus%%ldo%.img">Sending and writting boot.img</CMD>

      

       <CMD state="Updater"type="push" body="$ dd if=$FILEof=/dev/mmcblk%mmc%p1">write boot.img</CMD>

 

       <CMD state="Updater"type="push" body="mknod block/mmcblk%mmc%,mmcblk%mmc%p4,/dev/mmcblk%mmc%p4,block"/>

       <CMD state="Updater"type="push" body="mknodblock/mmcblk%mmc%,mmcblk%mmc%p5,/dev/mmcblk%mmc%p5,block"/>

       <CMD state="Updater"type="push" body="mknodblock/mmcblk%mmc%,mmcblk%mmc%p6,/dev/mmcblk%mmc%p6,block"/>

       <CMD state="Updater"type="push" body="mknodblock/mmcblk%mmc%,mmcblk%mmc%p7,/dev/mmcblk%mmc%p7,block"/>

 

       <CMD state="Updater"type="push" body="$ mkfs.ext4 -E nodiscard /dev/mmcblk%mmc%p5">Formatting systempartition</CMD>

       <CMD state="Updater"type="push" body="$ mkfs.ext4 -E nodiscard /dev/mmcblk%mmc%p6">Formatting cachepartition</CMD>

 

       <CMD state="Updater"type="push" body="$ mkfs.ext4 -E nodiscard /dev/mmcblk%mmc%p7">Formatting devicepartition</CMD>

       <CMD state="Updater" type="push"body="$ mount -o remount,size=600M rootfs /">change size oftmpfs</CMD>

       <CMD state="Updater"type="push" body="send"file="files/android/%folder%/system.img" >Sendingsystem.img</CMD>

       <CMD state="Updater"type="push" body="$ simg2img $FILE /dev/mmcblk%mmc%p5">writtingsparse system.img</CMD>

      

       <!-- Write userdata.img is optional,for some customer this is needed, but it's optional. -->

       <!-- Also, userdata.img will haveandroid unit test, you can use this to do some auto test. -->

       <!-- <CMDstate="Updater" type="push" onError="ignore"body="pipe dd of=/dev/mmcblk0p7"file="file/android/userdate.img"> Sending userdata.img(optional)</CMD>

       <CMD state="Updater"type="push" body="frf">flush thememory.</CMD>  -->

       <CMD state="Updater"type="push" body="pipe dd of=/dev/mmcblk%mmc%p2 bs=512"file="files/android/%folder%/recovery-imx%soc%%plus%%ldo%.img">Sendingand writting recovery.img</CMD>

      

       <CMD state="Updater"type="push" body="$ sync">Sync file system</CMD>

       <CMD state="Updater"type="push" body="frf">Finishing rootfswrite</CMD>

 

       <CMD state="Updater"type="push" body="$ echo UpdateComplete!">Done</CMD>

      

</LIST>

 

       小插曲:在之后的下载过程中,发现死活不能启动,总是进入下载模式,下载了已经可以工作的U-Boot也不能从 U-Boot启动。后来下载了一个Yocto的版本,再重新下载Android版本才可以正常启动。估计是原因是之前的ucs2.xml配置文件中执行了以下两句:

       <CMD state="Updater"type="push" body="$ echo 1 >/sys/block/mmcblk%mmc%boot0/force_ro"> re-enable read-only access</CMD>

       <CMD state="Updater"type="push" body="$ mmc bootpart enable 1 1/dev/mmcblk%mmc%">enable boot partion 1 to boot</CMD>

       这两行应该是设置启动分区的,由于设置了Kernel分区为启动分区,所以无法启动。虽然后来屏蔽了这两行,而且每次都把MBR擦除了,但由于分区结构没有,一直不起作用。下载Yocto版本时由于分区结构不同,所以再重新下载时就正常了。

       另外,个人习惯把下载工具放在编译机上,把版本文件直接建立symbol link的方式放到工具目录下,这样编译完成直接就可以下载,不需要拷贝过程,如果出现

 

U-Boot移植

       可以下载了,接下来就需要移植U-Boot了。参考之前Yotco项目的分支v2009.08-fsl_imx6_linux-xxx-project3/develop,找到寄存器配置文件board/freescale/mx6q_project3/flash_header.S,把其中的配置:

#DDR IO TYPE:   

MXC_DCD_ITEM(1,IOMUXC_BASE_ADDR + 0x798, 0x000C0000) // IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE

MXC_DCD_ITEM(2,IOMUXC_BASE_ADDR + 0x758, 0x00000000) // IOMUXC_SW_PAD_CTL_GRP_DDRPKE

                    

#CLOCK:                    

MXC_DCD_ITEM(3,IOMUXC_BASE_ADDR + 0x588, 0x00000028) // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0

MXC_DCD_ITEM(4,IOMUXC_BASE_ADDR + 0x594, 0x00000028) // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1

                    

#ADDRESS:               

MXC_DCD_ITEM(5,IOMUXC_BASE_ADDR + 0x56c, 0x00000028) // IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS

MXC_DCD_ITEM(6,IOMUXC_BASE_ADDR + 0x578, 0x00000028) // IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS

MXC_DCD_ITEM(7,IOMUXC_BASE_ADDR + 0x74c, 0x00000028) // IOMUXC_SW_PAD_CTL_GRP_ADDDS

                    

#Control:              

MXC_DCD_ITEM(8,IOMUXC_BASE_ADDR + 0x57c, 0x00000028) // IOMUXC_SW_PAD_CTL_PAD_DRAM_RESET

MXC_DCD_ITEM(9,IOMUXC_BASE_ADDR + 0x58c, 0x00000000) // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2 - DSEcan be configured using Group Control Register: IOMUXC_SW_PAD_CTL_GRP_CTLDS

MXC_DCD_ITEM(10,IOMUXC_BASE_ADDR + 0x59c, 0x00000028) // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0

MXC_DCD_ITEM(11,IOMUXC_BASE_ADDR + 0x5a0, 0x00000028) // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1

MXC_DCD_ITEM(12,IOMUXC_BASE_ADDR + 0x78c, 0x00000028) // IOMUXC_SW_PAD_CTL_GRP_CTLDS

                    

#Data Strobes:             

MXC_DCD_ITEM(13,IOMUXC_BASE_ADDR + 0x750, 0x00020000) // IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL

MXC_DCD_ITEM(14,IOMUXC_BASE_ADDR + 0x5a8, 0x00000028) // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0

MXC_DCD_ITEM(15,IOMUXC_BASE_ADDR + 0x5b0, 0x00000028) // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1

MXC_DCD_ITEM(16,IOMUXC_BASE_ADDR + 0x524, 0x00000028) // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2

MXC_DCD_ITEM(17,IOMUXC_BASE_ADDR + 0x51c, 0x00000028) // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3

MXC_DCD_ITEM(18,IOMUXC_BASE_ADDR + 0x518, 0x00000028) // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4

MXC_DCD_ITEM(19,IOMUXC_BASE_ADDR + 0x50c, 0x00000028) // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5

MXC_DCD_ITEM(20,IOMUXC_BASE_ADDR + 0x5b8, 0x00000028) // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6

MXC_DCD_ITEM(21,IOMUXC_BASE_ADDR + 0x5c0, 0x00000028) // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7

                    

#Data:                  

MXC_DCD_ITEM(22,IOMUXC_BASE_ADDR + 0x774, 0x00020000) // IOMUXC_SW_PAD_CTL_GRP_DDRMODE

MXC_DCD_ITEM(23,IOMUXC_BASE_ADDR + 0x784, 0x00000028)  //IOMUXC_SW_PAD_CTL_GRP_B0DS

MXC_DCD_ITEM(24,IOMUXC_BASE_ADDR + 0x788, 0x00000028)  //IOMUXC_SW_PAD_CTL_GRP_B1DS

MXC_DCD_ITEM(25,IOMUXC_BASE_ADDR + 0x794, 0x00000028)  //IOMUXC_SW_PAD_CTL_GRP_B2DS

MXC_DCD_ITEM(26,IOMUXC_BASE_ADDR + 0x79c, 0x00000028)  //IOMUXC_SW_PAD_CTL_GRP_B3DS

MXC_DCD_ITEM(27,IOMUXC_BASE_ADDR + 0x7a0, 0x00000028)  //IOMUXC_SW_PAD_CTL_GRP_B4DS

MXC_DCD_ITEM(28,IOMUXC_BASE_ADDR + 0x7a4, 0x00000028)  //IOMUXC_SW_PAD_CTL_GRP_B5DS

MXC_DCD_ITEM(29,IOMUXC_BASE_ADDR + 0x7a8, 0x00000028)  //IOMUXC_SW_PAD_CTL_GRP_B6DS

MXC_DCD_ITEM(30,IOMUXC_BASE_ADDR + 0x748, 0x00000028)  //IOMUXC_SW_PAD_CTL_GRP_B7DS

                    

MXC_DCD_ITEM(31,IOMUXC_BASE_ADDR + 0x5ac, 0x00000028) // IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0

MXC_DCD_ITEM(32,IOMUXC_BASE_ADDR + 0x5b4, 0x00000028)  //IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1

MXC_DCD_ITEM(33,IOMUXC_BASE_ADDR + 0x528, 0x00000028)  //IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2

MXC_DCD_ITEM(34,IOMUXC_BASE_ADDR + 0x520, 0x00000028)  //IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3

MXC_DCD_ITEM(35,IOMUXC_BASE_ADDR + 0x514, 0x00000028)  //IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM4

MXC_DCD_ITEM(36,IOMUXC_BASE_ADDR + 0x510, 0x00000028)  //IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM5

MXC_DCD_ITEM(37,IOMUXC_BASE_ADDR + 0x5bc, 0x00000028)  //IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM6

MXC_DCD_ITEM(38,IOMUXC_BASE_ADDR + 0x5c4, 0x00000028)  //IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM7

 

MXC_DCD_ITEM(39,MMDC_P0_BASE_ADDR + 0x800, 0xA1390003) // DDR_PHY_P0_MPZQHWCTRL, enable bothone-time & periodic HW ZQ calibration.

#For target board,may need to run write leveling calibration to fine tune these settings.

MXC_DCD_ITEM(40,MMDC_P0_BASE_ADDR + 0x80c, 0x002D002B)    

MXC_DCD_ITEM(41,MMDC_P0_BASE_ADDR + 0x810, 0x00380030)

MXC_DCD_ITEM(42,MMDC_P1_BASE_ADDR + 0x80c, 0x001F0030)     

MXC_DCD_ITEM(43,MMDC_P1_BASE_ADDR + 0x810, 0x001C002E)    

                    

#Read DQS Gatingcalibration                   

MXC_DCD_ITEM(44,MMDC_P0_BASE_ADDR + 0x83c, 0x0338034C)      //MPDGCTRL0 PHY0

MXC_DCD_ITEM(45,MMDC_P0_BASE_ADDR + 0x840, 0x0330032C)      //MPDGCTRL1 PHY0

MXC_DCD_ITEM(46,MMDC_P1_BASE_ADDR + 0x83c, 0x032C0338)      //MPDGCTRL0 PHY1

MXC_DCD_ITEM(47,MMDC_P1_BASE_ADDR + 0x840, 0x03280268)      //MPDGCTRL1 PHY1

                    

#Read calibration                

MXC_DCD_ITEM(48,MMDC_P0_BASE_ADDR + 0x848, 0x46363C3C) // MPRDDLCTL PHY0

MXC_DCD_ITEM(49,MMDC_P1_BASE_ADDR + 0x848, 0x3C383446) // MPRDDLCTL PHY1

                    

#Writecalibration                                   

MXC_DCD_ITEM(50,MMDC_P0_BASE_ADDR + 0x850, 0x363C403C) // MPWRDLCTL PHY0

MXC_DCD_ITEM(51,MMDC_P1_BASE_ADDR + 0x850, 0x40304438) // MPWRDLCTL PHY1

                    

#read data bitdelay: (3 is the reccommended default value, although out of reset value is 0)                

MXC_DCD_ITEM(52,MMDC_P0_BASE_ADDR + 0x81c, 0x33333333) // DDR_PHY_P0_MPREDQBY0DL3

MXC_DCD_ITEM(53,MMDC_P0_BASE_ADDR + 0x820, 0x33333333) // DDR_PHY_P0_MPREDQBY1DL3

MXC_DCD_ITEM(54,MMDC_P0_BASE_ADDR + 0x824, 0x33333333) // DDR_PHY_P0_MPREDQBY2DL3

MXC_DCD_ITEM(55,MMDC_P0_BASE_ADDR + 0x828, 0x33333333) // DDR_PHY_P0_MPREDQBY3DL3

MXC_DCD_ITEM(56,MMDC_P1_BASE_ADDR + 0x81c, 0x33333333) // DDR_PHY_P1_MPREDQBY0DL3

MXC_DCD_ITEM(57,MMDC_P1_BASE_ADDR + 0x820, 0x33333333) // DDR_PHY_P1_MPREDQBY1DL3

MXC_DCD_ITEM(58,MMDC_P1_BASE_ADDR + 0x824, 0x33333333) // DDR_PHY_P1_MPREDQBY2DL3

MXC_DCD_ITEM(59,MMDC_P1_BASE_ADDR + 0x828, 0x33333333) // DDR_PHY_P1_MPREDQBY3DL3

                    

#For i.mx6qd partsof versions A & B (v1.0, v1.1), uncomment the following lines. For versionC (v1.2), keep commented              

#setmem /32   0x021b08c0 = 0x24911492    // fine tune SDCLK duty cyc to low - seen toimprove measured duty cycle of i.mx6

#setmem /32   0x021b48c0 = 0x24911492   

                    

#Completecalibration by forced measurement:                               

MXC_DCD_ITEM(60,MMDC_P0_BASE_ADDR + 0x8b8, 0x00000800) // DDR_PHY_P0_MPMUR0, frc_msr

MXC_DCD_ITEM(61,MMDC_P1_BASE_ADDR + 0x8b8, 0x00000800) // DDR_PHY_P0_MPMUR0, frc_msr

      

#MMDC init:                     

MXC_DCD_ITEM(62,MMDC_P0_BASE_ADDR + 0x004, 0x00020036) // MMDC0_MDPDC

MXC_DCD_ITEM(63,MMDC_P0_BASE_ADDR + 0x008, 0x09444040) // MMDC0_MDOTC

MXC_DCD_ITEM(64,MMDC_P0_BASE_ADDR + 0x00c, 0x898E79A4) // MMDC0_MDCFG0

MXC_DCD_ITEM(65,MMDC_P0_BASE_ADDR + 0x010, 0xDB538F64) // MMDC0_MDCFG1

MXC_DCD_ITEM(66,MMDC_P0_BASE_ADDR + 0x014, 0x01FF00DD) // MMDC0_MDCFG2

                    

#MDMISC: RALATkept to the high level of 5.               

#MDMISC: considerreducing RALAT if your 528MHz board design allow that. Lower RALAT benefits:                  

#a. betteroperation at low frequency, for LPDDR2 freq < 100MHz, change RALAT to 3              

#b. Smallperformence improvment                  

MXC_DCD_ITEM(67,MMDC_P0_BASE_ADDR + 0x018, 0x00011740) // MMDC0_MDMISC

MXC_DCD_ITEM(68,MMDC_P0_BASE_ADDR + 0x01c, 0x00008000) //MMDC0_MDSCR, set the Configurationrequest bit during MMDC set up

MXC_DCD_ITEM(69,MMDC_P0_BASE_ADDR + 0x02c, 0x000026D2) // MMDC0_MDRWD

MXC_DCD_ITEM(70,MMDC_P0_BASE_ADDR + 0x030, 0x008E1023) // MMDC0_MDOR

MXC_DCD_ITEM(71,MMDC_P0_BASE_ADDR + 0x040, 0x00000047) // Chan0 CS0_END

MXC_DCD_ITEM(72,MMDC_P0_BASE_ADDR + 0x000, 0x841A0000) // MMDC0_MDCTL

                    

#Mode registerwrites                                 

MXC_DCD_ITEM(73,MMDC_P0_BASE_ADDR + 0x01c, 0x02088032) // MMDC0_MDSCR, MR2 write, CS0

MXC_DCD_ITEM(74,MMDC_P0_BASE_ADDR + 0x01c, 0x00008033) // MMDC0_MDSCR, MR3 write, CS0

MXC_DCD_ITEM(75,MMDC_P0_BASE_ADDR + 0x01c, 0x00048031) // MMDC0_MDSCR, MR1 write, CS0

MXC_DCD_ITEM(76,MMDC_P0_BASE_ADDR + 0x01c, 0x09308030) // MMDC0_MDSCR, MR0write, CS0

MXC_DCD_ITEM(77,MMDC_P0_BASE_ADDR + 0x01c, 0x04008040) // MMDC0_MDSCR, ZQ calibration commandsent to device on CS0

                    

#setmem /32   0x021b001c = 0x0208803A   // MMDC0_MDSCR, MR2 write, CS1

#setmem /32   0x021b001c = 0x0000803B   // MMDC0_MDSCR, MR3 write, CS1

#setmem /32   0x021b001c = 0x00048039    // MMDC0_MDSCR, MR1 write, CS1

#setmem /32   0x021b001c = 0x09308038    // MMDC0_MDSCR, MR0write, CS1

#setmem /32   0x021b001c = 0x04008048    // MMDC0_MDSCR, ZQ calibration command sentto device on CS1

                    

MXC_DCD_ITEM(78,MMDC_P0_BASE_ADDR + 0x020, 0x00007800) // MMDC0_MDREF

                    

MXC_DCD_ITEM(79,MMDC_P0_BASE_ADDR + 0x818, 0x00022227) // DDR_PHY_P0_MPODTCTRL

MXC_DCD_ITEM(80,MMDC_P1_BASE_ADDR + 0x818, 0x00022227) // DDR_PHY_P1_MPODTCTRL

                    

MXC_DCD_ITEM(81,MMDC_P0_BASE_ADDR + 0x004, 0x00025576) // MMDC0_MDPDC now SDCTL power downenabled

                    

MXC_DCD_ITEM(82,MMDC_P0_BASE_ADDR + 0x404, 0x00011006) // MMDC0_MAPSR ADOPT power down enabled,MMDC will enter automatically to self-refresh while the number of idle cyclereached.

                    

MXC_DCD_ITEM(83,MMDC_P0_BASE_ADDR + 0x01c, 0x00000000) // MMDC0_MDSCR, clear this register(especially the configuration bit as initialization is complete)

       查看configs/mx6qsabresdandroid_defconfig文件,配置文件为board/freescale/mx6sabresd/mx6q_4x_mt41j128.cfg,把上面的配置根据此文件中的格式写到配置文件中,完成后是这样的:

DATA 4,0x020e0798, 0x000C0000

DATA 4,0x020e0758, 0x00000000

DATA 4,0x020e0588, 0x00000028

DATA 4,0x020e0594, 0x00000028

DATA 4,0x020e056c, 0x00000028

DATA 4,0x020e0578, 0x00000028

DATA 4,0x020e074c, 0x00000028

DATA 4,0x020e057c, 0x00000028

DATA 4,0x020e058c, 0x00000000

DATA 4,0x020e059c, 0x00000028

DATA 4,0x020e05a0, 0x00000028

DATA 4,0x020e078c, 0x00000028

DATA 4,0x020e0750, 0x00020000

DATA 4,0x020e05a8, 0x00000028

DATA 4,0x020e05b0, 0x00000028

DATA 4,0x020e0524, 0x00000028

DATA 4,0x020e051c, 0x00000028

DATA 4,0x020e0518, 0x00000028

DATA 4,0x020e050c, 0x00000028

DATA 4,0x020e05b8, 0x00000028

DATA 4,0x020e05c0, 0x00000028

DATA 4,0x020e0774, 0x00020000

DATA 4,0x020e0784, 0x00000028

DATA 4,0x020e0788, 0x00000028

DATA 4,0x020e0794, 0x00000028

DATA 4,0x020e079c, 0x00000028

DATA 4,0x020e07a0, 0x00000028

DATA 4,0x020e07a4, 0x00000028

DATA 4,0x020e07a8, 0x00000028

DATA 4,0x020e0748, 0x00000028

DATA 4,0x020e05ac, 0x00000028

DATA 4,0x020e05b4, 0x00000028

DATA 4,0x020e0528, 0x00000028

DATA 4,0x020e0520, 0x00000028

DATA 4,0x020e0514, 0x00000028

DATA 4,0x020e0510, 0x00000028

DATA 4,0x020e05bc, 0x00000028

DATA 4,0x020e05c4, 0x00000028

DATA 4, 0x021b0800,0xA1390003

DATA 4,0x021b080c, 0x002D002B

DATA 4,0x021b0810, 0x00380030

DATA 4,0x021b480c, 0x001F0030

DATA 4,0x021b4810, 0x001C002E

DATA 4,0x021b083c, 0x0338034C

DATA 4,0x021b0840, 0x0330032C

DATA 4,0x021b483c, 0x032C0338

DATA 4, 0x021b4840,0x03280268

DATA 4,0x021b0848, 0x46363C3C

DATA 4,0x021b4848, 0x3C383446

DATA 4,0x021b0850, 0x363C403C

DATA 4,0x021b4850, 0x40304438

DATA 4,0x021b081c, 0x33333333

DATA 4,0x021b0820, 0x33333333

DATA 4,0x021b0824, 0x33333333

DATA 4,0x021b0828, 0x33333333

DATA 4,0x021b481c, 0x33333333

DATA 4,0x021b4820, 0x33333333

DATA 4,0x021b4824, 0x33333333

DATA 4,0x021b4828, 0x33333333

DATA 4,0x021b08b8, 0x00000800

DATA 4,0x021b48b8, 0x00000800

DATA 4,0x021b0004, 0x00020036

DATA 4,0x021b0008, 0x09444040

DATA 4,0x021b000c, 0x898E79A4

DATA 4,0x021b0010, 0xDB538F64

DATA 4,0x021b0014, 0x01FF00DD

DATA 4,0x021b0018, 0x00011740

DATA 4,0x021b001c, 0x00008000

DATA 4,0x021b002c, 0x000026D2

DATA 4,0x021b0030, 0x008E1023

DATA 4,0x021b0040, 0x00000047

DATA 4, 0x021b0000,0x841A0000

DATA 4,0x021b001c, 0x02088032

DATA 4,0x021b001c, 0x00008033

DATA 4,0x021b001c, 0x00048031

DATA 4,0x021b001c, 0x09308030

DATA 4,0x021b001c, 0x04008040

DATA 4,0x021b0020, 0x00007800

DATA 4,0x021b0818, 0x00022227

DATA 4, 0x021b4818,0x00022227

DATA 4,0x021b0004, 0x00025576

DATA 4,0x021b0404, 0x00011006

DATA 4,0x021b001c, 0x00000000

 

/* set the defaultclock gate to save power */

DATA 4,0x020c4068, 0x00C03F3F

DATA 4,0x020c406c, 0x0030FC03

DATA 4,0x020c4070, 0x0FFFC000

DATA 4,0x020c4074, 0x3FF00000

DATA 4,0x020c4078, 0x00FFF300

DATA 4,0x020c407c, 0x0F0000C3

DATA 4,0x020c4080, 0x000003FF

       这里需要注意,要把UART相关的CCM_CCGRn相关的寄存器位打开。把串口的相应PIN脚设置正确。修改board/freescale/mx6sabresd/mx6sabresd.c中,设置串口。

staticiomux_v3_cfg_t const uart1_pads[] = {

       MX6_PAD_SD3_DAT7__UART1_TX_DATA |MUX_PAD_CTRL(UART_PAD_CTRL),

       MX6_PAD_SD3_DAT6__UART1_RX_DATA |MUX_PAD_CTRL(UART_PAD_CTRL),

 };

编译下载新的U-Boot,可以看到串口有信息输出了。但eMMC配置不正确,还没有加载Kernel。看原理图

eMMC挂在芯片的SD4接口,原始代码中都是挂在SD3上的,设备号为mmcblk2,现在新的设备号为mmcblk0,所以需要把它改过来,还是在board/freescale/mx6sabresd/mx6sabresd.c中修改,把不用的几个USDHC2,3控制器屏蔽掉。

structfsl_esdhc_cfg usdhc_cfg[] = {

       /*{USDHC2_BASE_ADDR},

       {USDHC3_BASE_ADDR},*/

        {USDHC4_BASE_ADDR},

};

 

mmc_get_env_devno()函数中dev_no删除掉相应的个数。

       /*dev_no--;*/

    dev_no -= 3;

 

       board_mmc_init()函数中,简化初始化过程,把之前的代码屏掉,只需要初始化一个MMC设备就可以了,换成以下代码:

    imx_iomux_v3_setup_multiple_pads(

        usdhc4_pads, ARRAY_SIZE(usdhc4_pads));

    usdhc_cfg[0].sdhc_clk =mxc_get_clock(MXC_ESDHC4_CLK);

 

    ret = fsl_esdhc_initialize(bis,&usdhc_cfg[0]);

    if (ret) return ret;

 

       修改voidboard_fastboot_setup(void)函数,MMC4_BOOTcase中mmc2改为mmc0

       case MMC4_BOOT:

          if (!getenv("fastboot_dev"))

                     setenv("fastboot_dev","mmc0");

          if (!getenv("bootcmd"))

                     setenv("bootcmd","boota mmc0");

          break;

 

       修改配置头文件include/configs/mx6sabre_common.h文件,修改以下内容:

#define CONFIG_SYS_FSL_ESDHC_ADDR      USDHC4_BASE_ADDR/*0*/

       SDHC地址改为SDHC4。

 

       #define EMMC_ENV \

       "emmcdev=0\0"\

       "update_emmc_firmware=" \

              "if test ${ip_dyn} = yes;then " \

                     "setenv get_cmd dhcp;" \

              "else " \

                     "setenv get_cmd tftp;" \

              "fi; " \

              "if ${get_cmd}${update_sd_firmware_filename}; then " \

                     "if mmc dev ${emmcdev}1; then "     \

                            "setexpr fw_sz${filesize} / 0x200; " \

                            "setexpr fw_sz${fw_sz} + 1; "     \

                            "mmc write${loadaddr} 0x2 ${fw_sz}; " \

                     "fi; "       \

              "fi\0"

 

       修改配置头文件include/configs/mx6sabresd.h

       #define CONFIG_MMCROOT                   "/dev/mmcblk0p2" /* SDHC4 */

 

       简化设备数,设备号改为0

#define CONFIG_SYS_FSL_USDHC_NUM      1

#define CONFIG_SYS_MMC_ENV_DEV         0     /* SDHC4 */

 

       修改完成后,编译出U-boot,下载后就可以加载并启动Kernel了,由于Kernel中的eMMC也没有配置,所以停在了初始化MMC驱动的位置。好了,下面需要配置Kernel了。

 

Kernel移植

       U-Boot由于之前的参考项目,而且U-Boot的版本是基本相同的,所以移植很顺利,基本参考了之前的修改,改完之后,一次就成功了,但Kernel就没这么顺利了,之前的Kernel比较老,所以没有用DTS那一套东东。新的Kernel版本是v3.14.52。

 

       首先修改dts文件,把不用的几个SDHC控制器禁止掉,修改arch/arm/boot/dts/imx6qdl-sabresd.dtsi文件。

       找到usdhc2,usdhc3,把状态status从okey改为disabled.

---a/kernel_imx/arch/arm/boot/dts/imx6qdl-sabresd.dtsi

+++b/kernel_imx/arch/arm/boot/dts/imx6qdl-sabresd.dtsi

@@ -1052,7 +1052,7@@

        pm-ignore-notify;

        keep-power-in-suspend;

        enable-sdio-wakeup;

-       status = "okay";

+       status = "disabled";

 };

 

 &usdhc3 {

@@ -1064,7 +1064,7@@

        no-1-8-v;

        keep-power-in-suspend;

        enable-sdio-wakeup;

-       status = "okay";

+       status = "disabled";

 };

 

 &usdhc4 {

 

       修改arch/arm/boot/dts/imx6qdl.dtsi文件,把mmc0的配置改为usdhc4。

---a/kernel_imx/arch/arm/boot/dts/imx6qdl.dtsi

+++b/kernel_imx/arch/arm/boot/dts/imx6qdl.dtsi

@@ -28,10 +28,10@@

                i2c1 = &i2c2;

                i2c2 = &i2c3;

                ipu0 = &ipu1;

-               mmc0 = &usdhc1;

+               mmc0 = &usdhc4;

                mmc1 = &usdhc2;

                mmc2 = &usdhc3;

-               mmc3 = &usdhc4;

+               mmc3 = &usdhc1;

                serial0 = &uart1;

                serial1 = &uart2;

                serial2 = &uart3;

 

       把新的Kernel下载后,不停在MMC初始化了,出了一个KernelPanic,看了一下,是在初始化BCM的BT/Wifi驱动。暂时先把它去掉。

 

       修改Kernel配置文件arch/arm/configs/imx_v7_android_defconfig文件。找到CONFIG_BCMDHD,改为

       # CONFIG_BCMDHD is not set

 

       把另两个相关的配置改为modules

-CONFIG_CFG80211=y

+CONFIG_CFG80211=m

 CONFIG_CFG80211_WEXT=y

-CONFIG_MAC80211=y

+CONFIG_MAC80211=m

 CONFIG_RFKILL=y

 

       去掉WiFi/BT之后,Kernel Panic没有了,系统停在了init中的mount_all函数,加载Partition失败,提示没有分区,说明fstab中的分区信息不正确,找到fstab文件。device/fsl/sabresd_6dq/fstab.freescale,把其中的mmcblk3全部改为mmcblk0

---a/device/fsl/sabresd_6dq/fstab.freescale

+++b/device/fsl/sabresd_6dq/fstab.freescale

@@ -5,12 +5,12 @@

 

 /devices/soc0/soc.0/2100000.aips-bus/2198000.usdhc/mmc_host*auto auto defaults voldmanaged=sdcard:auto,encryptable=userdata

 /devices/soc0/soc.0/2100000.aips-bus/2184000.usb/ci_hdrc.0*  auto auto defaults voldmanaged=usb:auto

-/dev/block/mmcblk3p5    /system     ext4  ro,barrier=1                    wait,verify

-/dev/block/mmcblk3p4    /data       ext4 nosuid,nodev,nodiratime,noatime,nomblk_io_submit,noauto_da_alloc,errors=panic    wait,encryptable=/dev/block/mmcblk3p9

-/dev/block/mmcblk3p6    /cache      ext4  nosuid,nodev,nomblk_io_submit   wait

-/dev/block/mmcblk3p7    /device     ext4  ro,nosuid,nodev                 wait

-/dev/block/mmcblk3p1    /boot       emmc  defaults                        defaults

-/dev/block/mmcblk3p2    /recovery   emmc  defaults                        defaults

-/dev/block/mmcblk3p8    /misc       emmc  defaults                        defaults

-/dev/block/mmcblk3boot0 /bootloader  emmc defaults                       defaults

+/dev/block/mmcblk0p5    /system     ext4  ro,barrier=1                    wait,verify

+/dev/block/mmcblk0p4    /data       ext4 nosuid,nodev,nodiratime,noatime,nomblk_io_submit,noauto_da_alloc,errors=panic    wait,encryptable=/dev/block/mmcblk0p9

+/dev/block/mmcblk0p6    /cache      ext4  nosuid,nodev,nomblk_io_submit   wait

+/dev/block/mmcblk0p7    /device     ext4  ro,nosuid,nodev                 wait

+/dev/block/mmcblk0p1    /boot       emmc  defaults                        defaults

+/dev/block/mmcblk0p2    /recovery   emmc  defaults                        defaults

+/dev/block/mmcblk0p8    /misc       emmc  defaults                        defaults

+/dev/block/mmcblk0boot0 /bootloader  emmc defaults                       defaults

 /dev/block/zram0 none swap defaultszramsize=314572800

 

       下载后,发现还是停在mount_all,不过提示变了,提示mount mmcblk0p5时size不正确,查了一下fstab文件,mmcblk0p5是system分区,根据提示,mount时认为有800M左右,实际只有600M左右。这应该是系统中的分区和实际的分区不符,实际的分区是mfg_tools下载时决定的,系统的分区在哪里设置不清楚,为了简单化,决定把BoardConfig.mk中的system分区改小一点。修改device/fsl/imx6/BoardConfigCommon.mk文件。暂时改为512M。

BOARD_BOOTIMAGE_PARTITION_SIZE:= 16777216

 BOARD_RECOVERYIMAGE_PARTITION_SIZE := 16777216

 

-BOARD_SYSTEMIMAGE_PARTITION_SIZE:= 629145600

+#BOARD_SYSTEMIMAGE_PARTITION_SIZE:= 629145600

+BOARD_SYSTEMIMAGE_PARTITION_SIZE:= 536870912

 BOARD_CACHEIMAGE_PARTITION_SIZE := 444596224

 BOARD_FLASH_BLOCK_SIZE := 4096

 TARGET_RECOVERY_UI_LIB := librecovery_ui_imx

 

       重新buildsystem,下载,从Log上看顺利进入系统了,接上 USB线,已经有ADB设备了,但adb device 提示没有权限,应该是屏幕上需要确认连接,由于屏驱动暂时没有移植,所以没有显示。

 

       为了方便调试,暂时关闭adbsecure,不需要屏上确认就可以连接。修改device/fsl/sabresd_6dq/init.rc文件,增加下面两行。

---a/device/fsl/sabresd_6dq/init.rc

+++b/device/fsl/sabresd_6dq/init.rc

@@ -87,7 +87,8 @@on boot

 

 

 # Enable adb security for JB4.2.2

-    setprop ro.adb.secure 1

+    setprop ro.adb.secure 0

+    setprop ro.debuggable 1

 

重新编译下载后,ADB就可以连接使用了,由于系统可以启动了,初步移植算完成了。

 

一些个人体会

       如果是通过 mfg_tools下载的,如果能借用之前可用的U-boot/Kernel会节省很多时间,默认的下载配置文件ucl2.xml可能不一定正确,最好是从其它项目拷贝一个过来改会更可靠一些。

       配置U-Boot时,Clock的配置需要特别注意,之前没注意,一直不出Log,其实串口早就配置正确了,只是Clock没有使能,所以无输出。

       不管实际接的eMMC通道是什么,最后统一全映射成mmc0,否则起不来,不知道为什么。Kernel中的配置也是如些,不理解。

       不需要或暂时不需要的设备尽可能的删除或屏蔽掉,可以减少对移植的干扰。

阅读全文
0 0
原创粉丝点击