編輯:關於Android編程
公司一項目,用的是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目錄下。
loadSection="OTH"setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6QMX6D">Loading Kernel.
另外,Kernel的運行地址也不正確,根據編譯裡鏈接的位置,改為0x10800000。無關的配置可以刪除或屏蔽掉。initramfs由於之前的項目沒有這個文件,所以用默認的,把地址改為0x10C00000。DTD文件也沒有,所以暫時也可以屏蔽掉。
測試下載,LoadingKernel, Jumping to OS Image正確,串口可以出信息,下一步是分區,format_android報錯,看來是mksdcard-android.sh.tar文件舊的版本支持不完善。暫時把format_android步驟屏蔽。
再往下FormatingPartition報錯,說沒有相應設備,用ls也的確沒有列出相就的設備來。看來執行腳本沒有作用。用較原始的方法,一條條命令來建立設備。先擦除:
Erasing MBR and kernelparameters...
把U-Boot燒寫到首塊:
建立Boot分區:
把Boot.img寫到Boot分區:
建立其它分區設備:
這樣之後的格式化過程就可以順利進行了。由於缺少經驗,下載過程折騰了近一天才基本搞定。而且還是參考了一下之前一個Freescale i.MX6DL Android 5.0項目的配置。列一個較完整的配置,供參考:
loadSection="OTH"setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6QMX6D">Loading Kernel.
loadSection="OTH"setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6QMX6D">Loading Initramfs.
loadSection="OTH" setSection="OTH"HasFlashHeader="FALSE" ifdev="MX6Q">Loading devicetree.
Erasing MBR and kernelparameters...
小插曲:在之後的下載過程中,發現死活不能啟動,總是進入下載模式,下載了已經可以工作的U-Boot也不能從 U-Boot啟動。後來下載了一個Yocto的版本,再重新下載Android版本才可以正常啟動。估計是原因是之前的ucs2.xml配置文件中執行了以下兩句:
這兩行應該是設置啟動分區的,由於設置了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 /systemext4 ro,barrier=1 wait,verify
-/dev/block/mmcblk3p4 /dataext4nosuid,nodev,nodiratime,noatime,nomblk_io_submit,noauto_da_alloc,errors=panic wait,encryptable=/dev/block/mmcblk3p9
-/dev/block/mmcblk3p6 /cacheext4 nosuid,nodev,nomblk_io_submit wait
-/dev/block/mmcblk3p7 /deviceext4 ro,nosuid,nodev wait
-/dev/block/mmcblk3p1 /bootemmc defaults defaults
-/dev/block/mmcblk3p2 /recoveryemmc defaults defaults
-/dev/block/mmcblk3p8 /miscemmc defaults defaults
-/dev/block/mmcblk3boot0 /bootloader emmcdefaultsdefaults
+/dev/block/mmcblk0p5 /systemext4 ro,barrier=1 wait,verify
+/dev/block/mmcblk0p4 /dataext4nosuid,nodev,nodiratime,noatime,nomblk_io_submit,noauto_da_alloc,errors=panic wait,encryptable=/dev/block/mmcblk0p9
+/dev/block/mmcblk0p6 /cacheext4 nosuid,nodev,nomblk_io_submit wait
+/dev/block/mmcblk0p7 /deviceext4 ro,nosuid,nodev wait
+/dev/block/mmcblk0p1 /bootemmc defaults defaults
+/dev/block/mmcblk0p2 /recoveryemmc defaults defaults
+/dev/block/mmcblk0p8 /miscemmc defaults defaults
+/dev/block/mmcblk0boot0 /bootloader emmcdefaultsdefaults
/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中的配置也是如些,不理解。
不需要或暫時不需要的設備盡可能的刪除或屏蔽掉,可以減少對移植的干擾。
當然選類似微信的剪裁咯,為什麼?請看下文分析眾所周知頭像剪裁上傳是絕大部分APP必備的功能之一,但是剪裁的模式有2種交互形式,第一種是采用系統自帶的剪裁功能,我個人是比較
Android數據分批加載-滑動到底部自動加載列表2014年5月9日 本博文介紹如何進行數據分批加載,在應用開發當中會經常使用到ListView,點擊更多加載數據是我們經
先看看電影票在線選座功能實現的效果圖: 界面比較粗糙,主要看原理。這個界面主要包括以下幾部分 1、座位 2、左邊的排數 3、左上方的縮略圖 4、縮略圖中的紅色區域 5、手
先來上個效果圖:當滑動時:數值顯示,滑動停止時顯示數字,使用FrameLayout結合SeekBar。首先我們看看。Layout:<?xml version