Kindle4: 编译并运行upstream linux kernel – v4.4

Kindle4官方提供的Linux  kernel版本为2.6.31, 已经算是很旧版本的kernel了。当前最新版本的linux kernel为4.5,而brillo-m10-dev arm emulator所使用的版本为v4.4,对于 CPU主频只有800MHz并且RAM为256MB的Kindle4来说,跑个Brillo-m10-dev系统还是很不错的。Kindle4的优点是有PMIC(电源管理),有fuel gauge,有WiFi,当然,还有一个USB 2.0接口,使用USB协议的adb比TCP协议的adb要好用很多(master分支上的adb已经支持TCP协议断开检查,并且解决了在执行adb reboot命令没有回应的问题)。

  • 相关开发环境:

1. 主机系统: ubuntu-14.04 x86_64

2. 编译工具: arm-eabi-4.6 – https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/

3. 烧机工具:fastboot – http://www.mobileread.com/forums/showthread.php?t=174923

  • 文件结构
kindle4
|-- Fastboot-Kindle
|   `-- fastboot
|-- tools
|   `-- arm-eabi-4.6
|-- u-boot-2009.08
|   `-- u-boot-bist-kernel
`-- v4.4
    `-- arch
        `-- arm
            `-- boot
                |-- dts
                |   `-- imx50-evk.dtb
                `-- zImage

1. Fastboot-Kindler包含fastboot源代码及fastboot可执行程序,用于烧写u-boot-bist-kernel

2. u-boot-2009.08包含kindle4 u-boot 4.1.3版本源代码

3. tools/arm-eabi-4.6 编译u-boot代码所需要的工具链

4. v4.4 包含linux kernel v4.4源代码及编译好的zImage与imx50-evk.dtb文件

  • bootloader – u-boot

需要修改u-boot,以便能够引导使用Flattened Device Tree(FDT) 的kernel。相关的patch文件可以从这里下载:kindle4_v4.1.3_u-boot-bist_fdt.patch,编写u-boot-kernel-v4.4.its文件:

/*
 * Simple U-boot uImage source file containing a single kernel and FDT blob
 */

/dts-v1/;

/ {
	description = "i.MX508 Linux kernel and FDT blob";
	#address-cells = <1>;

	images {
		kernel@1 {
			description = "i.MX508 Linux kernel";
			data = /incbin/("../v4.4/arch/arm/boot/zImage");
			type = "kernel";
			arch = "arm";
			os = "linux";
			compression = "none";
			load = <0x70008000>;
			entry = <0x70008000>;
			hash@1 {
				algo = "crc32";
			};
			hash@2 {
				algo = "sha1";
			};
		};
		fdt@1 {
			description = "Flattened Device Tree blob";
			data = /incbin/("../v4.4/arch/arm/boot/dts/imx50-evk.dtb");
			type = "flat_dt";
			arch = "arm";
			compression = "none";
			hash@1 {
				algo = "crc32";
			};
			hash@2 {
				algo = "sha1";
			};
		};
	};

	configurations {
		default = "conf@1";
		conf@1 {
			description = "i.MX508 Boot Linux kernel with FDT blob";
			kernel = "kernel@1";
			fdt = "fdt@1";
		};
	};
};

从这里可以看到编译出来的kernel存放在../v4.4/arch/arm/boot/zImage, 而dtb文件为../v4.4/arch/arm/boot/dts/imx50-evk.dtb。

最后执行如下脚本,就可以生成我们所需要的烧机文件:u-boot-bist-kernel

#! /bin/bash
set -e

TP="`pwd`/../tools/arm-eabi-4.6"

if [ ! -f include/config.h ] ; then
	CROSS_COMPILE=${TP}/bin/arm-eabi- ARCH=arm TYPE=bist make imx50_yoshi_bist_config
fi
CROSS_COMPILE=${TP}/bin/arm-eabi- ARCH=arm TYPE=bist make $@
if [ -f u-boot.bin ] ; then
	tools/mkimage -A arm -O linux -T kernel -C none -a 0x79800000 -e 0x79800000 -n 'u-boot-bist' -d u-boot.bin u-boot-bist-kernel
	tools/mkimage -f u-boot-kernel-v4.4.its u-boot-kernel-v4.4
	dd if=u-boot-kernel-v4.4 of=u-boot-bist-kernel bs=$((1024*1024)) seek=1
fi

NOTE:由于生成最终的u-boot-bist-kernel文件需要zImage与imx50-vvk.dtb,所以在执行这个脚本时需要保证这两个文件已经存在。

执行如下命令将u-boot-bist-kernel写入到kernel分区:

hzak@B85RPI:~/kindle4/u-boot-2009.08$ ../Fastboot-Kindle/fastboot flash kernel u-boot-bist-kernel && ../Fastboot-Kindle/fastboot reboot

系统重启后会自动进入我们编译出来的u-boot – bist系统,这时候执行如下命令可以正常启动linux系统:

...
In:    serial
Out:   serial
Err:   serial
POST done in 1 ms
Battery voltage: 3712 mV

bist > bootm 0x141000
## Booting kernel from FIT Image at 7a000000 ...
   Using 'conf@1' configuration
   Trying 'kernel@1' kernel subimage
     Description:  i.MX508 Linux kernel
     Type:         Kernel Image
     Compression:  uncompressed
     Data Start:   0x7a0000dc
     Data Size:    4240184 Bytes =  4 MB
     Architecture: ARM
     OS:           Linux
     Load Address: 0x70008000
     Entry Point:  0x70008000
     Hash algo:    crc32
     Hash value:   d85b369e
     Hash algo:    sha1
     Hash value:   363136b407684d3d58119823f819501f9f254399
   Verifying Hash Integrity ... crc32+ sha1+ OK
## Flattened Device Tree from FIT Image at 7a000000
   Using 'conf@1' configuration
   Trying 'fdt@1' FDT blob subimage
     Description:  Flattened Device Tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x7a40b53c
     Data Size:    10230 Bytes = 10 kB
     Architecture: ARM
     Hash algo:    crc32
     Hash value:   682b5aa0
     Hash algo:    sha1
     Hash value:   c336f63fd6f4e82d21439ca2843a99eea47f03bb
   Verifying Hash Integrity ... crc32+ sha1+ OK
   Booting using the fdt blob at 0x7a40b53c
   Loading Kernel Image ... OK
OK
   Loading Device Tree to 71ffa000, end 71fff7f5 ... OK

Starting kernel ...
  • kernel – v4.4.2

为了使Kindle4能跑brillo-m10-dev系统,kernel版本当然是使用v4.4了。相关的commit为:

commit 96cb1584b08c9a74a7cce6805354d4515c2131ae
Author: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date:   Wed Feb 17 12:31:25 2016 -0800

    Linux 4.4.2

kernel相关的patch文件请从这里下载:linux-v4.4_kindle4.patch.gz

目前能够正常工作的设备有:

1. uart1 – 输出kernel log,用于kernel调试

diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
index a634b11..9755a46 100644
--- a/drivers/clk/imx/clk.c
+++ b/drivers/clk/imx/clk.c
@@ -101,12 +101,14 @@ void __init imx_register_uart_clocks(struct clk ** const clks[])
 
 static int __init imx_clk_disable_uart(void)
 {
+#if 0
        if (imx_keep_uart_clocks && imx_uart_clocks) {
                int i;
 
                for (i = 0; imx_uart_clocks[i]; i++)
                        clk_disable_unprepare(*imx_uart_clocks[i]);
        }
+#endif
 
        return 0;
 }

不能disable uart时钟,否则会死机。why?

2. esdhc3 – 读写eMMC

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 1f1582f..114dcd2 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1267,7 +1267,7 @@ static int sdhci_esdhc_runtime_suspend(struct device *dev)
        ret = sdhci_runtime_suspend_host(host);
 
        if (!sdhci_sdio_irq_enabled(host)) {
-               clk_disable_unprepare(imx_data->clk_per);
+//             clk_disable_unprepare(imx_data->clk_per);
                clk_disable_unprepare(imx_data->clk_ipg);
        }
        clk_disable_unprepare(imx_data->clk_ahb);
@@ -1282,7 +1282,7 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
        struct pltfm_imx_data *imx_data = pltfm_host->priv;
 
        if (!sdhci_sdio_irq_enabled(host)) {
-               clk_prepare_enable(imx_data->clk_per);
+//             clk_prepare_enable(imx_data->clk_per);
                clk_prepare_enable(imx_data->clk_ipg);
        }
        clk_prepare_enable(imx_data->clk_ahb);

在runtime suspend的时候不能disable per(外设时钟)。why?

USB 目前还存在问题,不能正常工作。

相关的编译脚本如下:

#! /bin/bash

TP="`pwd`/../tools/arm-eabi-4.6"

if [ ! -f .config ] ; then
	CROSS_COMPILE=${TP}/bin/arm-eabi- ARCH=arm make imx_v6_v7_defconfig
fi

CROSS_COMPILE=${TP}/bin/arm-eabi- ARCH=arm make $@
  • 相关的参考文档:
  1. http://www.devicetree.org/Main_Page

发表评论

电子邮件地址不会被公开。 必填项已用*标注