Exynos4412 移植针对Samsung的Linux-6.1(一)下载、配置、编译Linux-6.1,安装依赖包解决No such file or director问题

系列文章目录


项目说明
宿主机操作系统Ubuntu 20.04 LTS x86_64
宿主机Linux内核版本5.4.0-126-generic
目标机linux内核版本Linux-6.1
目标机硬件CBT4412(类似:tiny4412)
MPUExynos4412(Cortex-A9)
U-Bootu-boot-2022.01-rc4
arm-none-linux-gnueabihf-gccgcc version 10.2.1 20201103 (GNU Toolchain for the A-profile Architecture 10.2-2020.11 (arm-10.16))

一、下载针对Samsung的Linux内核

在选择Linux内核时,首先要知道有哪些个人或团体在维护针对目标机架构的内核。
在The Linux Kernel官网中,有针对Samsung SoC的Linux内核。目前已经在维护Linux-6.2.0-rc1版本了。网址如下:
kernel/git/krzk/linux.git - Linux Samsung SoC tree
在这里插入图片描述

1、下载Linux-6.1

本文下载Linux-6.1。下载地址:
https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git/snapshot/linux-6.1.tar.gz

  • Linux-6.1和Linux-6.2.0-rc1:支持Cortex-A系列的CPU,包括Samsung的exynos4。
    在这里插入图片描述
    在这里插入图片描述

二、交叉编译工具链

1、交叉编译工具链的选择

访问Arm Developer 官网,根据gcc和glibc的版本,选择针对 Cortex-A系列的交叉编译工具链gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf。该版本包括以下工具:
在这里插入图片描述

2、GNU 10.2 cross-toolchain的安装

  1. 下载gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf.tar.xz
cd /opt
wget https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu-a/10.2-2020.11/binrel/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf.tar.xz
wget https://developer.arm.com/-/media/Files/downloads/gnu-a/10.2-2020.11/binrel/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf.tar.xz.asc
  1. 解压
sudo tar -xJf gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf.tar.xz
sudo md5sum --check gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf.tar.xz.asc

如果显示

gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf.tar.xz: OK

表明 XZ 压缩包正常。

  1. 配置用户环境变量
    Ubuntu用户分为root用户、系统用户和普通用户。为了方便使用,将/opt/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf/bin/路径添加到root和普通用户变量的PATH中。实现方法是:
  1. 修改/root/.bashrc文件。这个文件修改的是root用户环境变量。在文件最后面新增加一行代码,内容如下:
    export PATH=$PATH:/opt/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf/bin/
  2. 修改~/.bashrc文件。这个文件修改的是当前用户环境变量。在文件最后面新增加一行代码,内容如下:
    export PATH=$PATH:/opt/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf/bin/
    重启终端,让环境变量立即生效。
  3. 测试交又工具链
    检测交叉工具链是否安装成功,命令如下:
$ arm-none-linux-gnueabihf-gcc -v

如果没有报错,并能够显示编译器的相关信息,则说明交叉工具链安装成功。

2、修改顶层目录下的Makefile

cd ~/linux-6.1
vim Makefile

ARCH               ?= $(SUBARCH)

修改、并增加为

ARCH            := arm
CROSS_COMPILE 	:= arm-none-linux-gnueabihf-

CROSS_COMPILE修改为自己的交叉编译工具链。

二、为Exynos4412移植内核

3、导入默认配置

make exynos_defconfig

4、配置内核

make menuconfig
  • Kernel hacking —>
           [*] Panic on Oops
           (5) panic timeout
           [*] Kernel low-level debugging functions (read help!)
                 Kernel low-level debugging port (Use Samsung S3C UART 0 for low-level debug) —>
           [ ] Enable decompressor debugging via DEBUG_LL output
           [*] Early printk

Kernel low-level debugging port根据自己开发板的串口来选择。我的是串口0。

5、修改arch/arm/tools/mach-types

u-boot的机器码和linux内核的要一致。我在移植U-Boot时,配置CONFIG_MACH_TYPE为MACH_TYPE_EXYNOS4412。
查找U-Boot中arch/arm/include/asm/mach-types.h,存在

#define MACH_TYPE_TINY4412 4608
#define MACH_TYPE_EXYNOS4412 5030

所以,在内核源码的arch/arm/tools/mach-types中仿照origen添加exynos4412对应的机器码。如下:

origen			MACH_ORIGEN			ORIGEN			3455
exynos4412		MACH_EXYNOS4412		EXYNOS4412		5030

6、编译设备树

(1)将内核源文件中的设备树文件/arch/arm/boot/dts/exynos4412-origen.dts拷贝一份,改文件名为exynos4412-cbt4412.dts并修改

cp ./arch/arm/boot/dts/exynos4412-origen.dts ./arch/arm/boot/dts/exynos4412-cbt4412.dts
gedit ./arch/arm/boot/dts/exynos4412-cbt4412.dts

保留串口、内存、时钟等配置,添加网卡的基本配置:

// SPDX-License-Identifier: GPL-2.0
/*
 * Insignal's Exynos4412 based Origen board device tree source
 *
 * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com
 *
 * Device tree source file for Insignal's Origen board which is based on
 * Samsung's Exynos4412 SoC.
 */

/dts-v1/;
#include "exynos4412.dtsi"
#include "exynos4412-pinctrl.dtsi"
#include <dt-bindings/clock/samsung,s2mps11.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "exynos-mfc-reserved-memory.dtsi"

/ {
	model = "CBt4412 board based on Exynos4412";
	compatible = "samsung,exynos4412";

	chosen {
		stdout-path = &serial_0;
	};
		
	memory-controller@12570000 {
		#address-cells = <2>;
		#size-cells = <1>;
		ranges = <0 0 0x04000000 0x20000   // Bank0
			  1 0 0x05000000 0x20000   // Bank1
			  2 0 0x06000000 0x20000   // Bank2
			  3 0 0x07000000 0x20000>; // Bank3
	};

	memory@40000000 {
		device_type = "memory";
		reg = <0x40000000 0x40000000>;
	};

	fixed-rate-clocks {
		xxti {
			compatible = "samsung,clock-xxti";
			clock-frequency = <0>;
		};

		xusbxti {
			compatible = "samsung,clock-xusbxti";
			clock-frequency = <24000000>;
		};
	};
};

&cpu_thermal {
	cooling-maps {
		cooling_map0: map0 {
			/* Corresponds to 800MHz at freq_table */
			cooling-device = <&cpu0 7 7>, <&cpu1 7 7>,
					 <&cpu2 7 7>, <&cpu3 7 7>;
		};
		cooling_map1: map1 {
			/* Corresponds to 200MHz at freq_table */
			cooling-device = <&cpu0 13 13>, <&cpu1 13 13>,
					 <&cpu2 13 13>, <&cpu3 13 13>;
		};
	};
};

&serial_0 {
	status = "okay";
};

&serial_1 {
	status = "okay";
};

&serial_2 {
	status = "okay";
};

&serial_3 {
	status = "okay";
};

(2)修改/arch/arm/boot/dts/Makefile文件,添加上我们新创的设备树文件exynos4412-cbt4412.dts

dtb-$(CONFIG_ARCH_EXYNOS4) += \
	exynos4210-i9100.dtb \
	exynos4210-origen.dtb \
	exynos4210-smdkv310.dtb \
	exynos4210-trats.dtb \
	exynos4210-universal_c210.dtb \
	exynos4412-i9300.dtb \
	exynos4412-i9305.dtb \
	exynos4412-itop-elite.dtb \
	exynos4412-n710x.dtb \
	exynos4412-odroidu3.dtb \
	exynos4412-odroidx.dtb \
	exynos4412-odroidx2.dtb \
	exynos4412-origen.dtb \
	exynos4412-cbt4412.dtb \

(3)在linu源码目录下编译设备树

$ make dtbs
  DTC     arch/arm/boot/dts/exynos4412-cbt4412.dtb

此时,在arch/arm/boot/dts/目录中生成exynos4412-cbt4412.dtb。

7、解决fatal error: gmp.h: No such file or director问题

编译内核,报错

make uImage

报错:error: gmp.h 没有这个文件或目录
通过360搜索,找到解决方案如下:

sudo apt-get install  libgmp3-dev

8、解决error: mpc.h: No such file or director

编译内核,报错fatal error: gmp.h: 没有那个文件或目录。解决方法:

sudo apt-get install libmpc-dev

9、解决multiple (or no) load addresses错误

make uImage编译内核,报错multiple (or no) load addresses。表明没有定义宏LOADADDR。具体分析可参见博文Linux内核移植 part3:Exynos4412内核编译1

编辑arch/arm/boot/Makefile,直接添加

LOADADDR := 0x40008000

由于找不到mkimage工具,复制在uboot根目录tools目录的mkimage,放到/usr/local/bin即可。

sudo cp ~/u-boot-2022.01-rc4-cbt4412/tools/mkimage /usr/local/bin

准备就绪,make uImage编译内核,显示如下信息:

$ make uImage

10、解决gcc: error: unrecognized argument in option ‘-mabi=aapcs-linux’

  CC      scripts/mod/empty.o
gcc: error: unrecognized argument in option ‘-mabi=aapcs-linux’
gcc: note: valid arguments to ‘-mabi=’ are: ms sysv
gcc: error: unrecognized command line option ‘-mlittle-endian’
gcc: error: unrecognized command line option ‘-mtp=cp15’
gcc: error: unrecognized command line option ‘-mfpu=vfp’
make[1]: *** [scripts/Makefile.build:252: scripts/mod/empty.o] Error 1
make: *** [Makefile:1288: prepare0] Error 2

-mabi=aapcs-linux-mlittle-endian等等这些是arm-none-linux-gnueabihf-gcc的编译选项,gcc 9是支持的。出现这个问题,是因为CC代表的编译器不正确。我采用以下命令可以继续编译。

make ARCH=arm && make CROSS_COMPILE=arm-none-linux-gnueabihf- && make

虽然我在顶层目录的Makefile中,增加了ARCH :=armCROSS_COMPILE :=arm-none-linux-gnueabihf-,但是仍然会出现这个问题。然后,我有安装了lib32z1,问题仍然存在。但是再捣鼓了make distclean;make exynos_defconfig;make menuconfig一阵之后,就没有出现这个问题了。我分析问题的解决可能是2个方面:一是安装了lib32z1;二是Makefile中,ARCH和 CROSS_COMPILE的赋值要用:=,而不能用?=:= 、?=、 +=、 =四者的区别可以百度。

$ sudo apt-get install lib32z1

11、编译内核

准备就绪,make uImage编译内核,显示如下信息:

$ make uImage
[...]
  LD      arch/arm/boot/compressed/vmlinux
  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready
  UIMAGE  arch/arm/boot/uImage
Image Name:   Linux-6.1.0
Created:      Fri Jan  6 15:21:59 2023
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    7682528 Bytes = 7502.47 KiB = 7.33 MiB
Load Address: 40008000
Entry Point:  40008000
  Kernel: arch/arm/boot/uImage is ready

后续添加SD卡、NandFlash、DM9000网卡驱动,挂载跟文件系统,可以启动linux。初步结果如下:

Starting kernel ...

[    0.000000][    T0] Booting Linux on physical CPU 0xa00
[    0.000000][    T0] Linux version 6.1.0-gff8c1029068e-dirty (lighthouse@VM-4-13-ubuntu) (arm-none-linux-gnueabihf-gcc () 10.2.1 20201103, GNU ld (GNU Toolchain for the A-profile Architecture 10.2-2020.11 (arm-10.16)) 2.35.1.20201028) #9 SMP 
[    0.000000][    T0] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=10c5387d
[    0.000000][    T0] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000][    T0] OF: fdt: Machine model: CBT4412 board based on Exynos4412
[......]
[    2.506876][    T1] EXT4-fs (mmcblk0p3): recovery complete
[    2.515380][    T1] EXT4-fs (mmcblk0p3): mounted filesystem with ordered data mode. Quota mode: disabled.
[    3.150269][    T1] VFS: Mounted root (ext4 filesystem) on device 179:51.
[    3.151647][    T1] devtmpfs: mounted
[    3.153105][    T1] Freeing unused kernel image (initmem) memory: 1024K
[    3.153671][    T1] Run /linuxrc as init process
can't run '/etc/init.d/rcS': No such file or directory

Please press Enter to activate this console. 
/ # reboot
umount: can't open '/proc/mounts'
swapoff: can't open '/etc/fstab': No such file or directory
The system is going down NOW!
Sent SIGTERM to all processes
Terminated
Sent SIGKILL to all processes
Requesting system reboot

后记:后续移植SD卡、NandFlash和DM9000网卡都成功了,虽然有些波折。但是,在执行ifconfig指令时,出现了以下错误,实在无法调试内核和驱动,无奈只能止步于此。望后来者能够给出解决方案。

/ # ifconfig eth0 192.168.1.230 netmask 255.255.255.0 up
[   67.621272][   T91] dm9000 5000000.ethernet: dm9000 did not respond to first reset
[   67.621640][   T91] dm9000 5000000.ethernet: dm9000 did not respond to second reset
[   83.037857][    C3] mmc0: Timeout waiting for hardware interrupt.
[   83.038126][    C3] mmc0: sdhci: ============ SDHCI REGISTER DUMP ===========
[   83.038218][    C3] mmc0: sdhci: Sys addr:  0x7ac8b400 | Version:  0x00002401
[   83.038304][    C3] mmc0: sdhci: Blk size:  0x00007200 | Blk cnt:  0x00000000
[   83.043178][    C3] mmc0: sdhci: Argument:  0x3c500400 | Trn mode: 0x00000027
[   83.050295][    C3] mmc0: sdhci: Present:   0x01fa3000 | Host ctl: 0x00000013
[   83.057413][    C3] mmc0: sdhci: Power:     0x0000000e | Blk gap:  0x00000000
[   83.064530][    C3] mmc0: sdhci: Wake-up:   0x00000000 | Clock:    0x0000000f
[   83.071647][    C3] mmc0: sdhci: Timeout:   0x0000000e | Int stat: 0x00000003
[   83.078765][    C3] mmc0: sdhci: Int enab:  0x03ff000b | Sig enab: 0x03ff000b
[   83.085882][    C3] mmc0: sdhci: ACmd stat: 0x00000000 | Slot int: 0x00000001
[   83.093000][    C3] mmc0: sdhci: Caps:      0x05e80080 | Caps_1:   0x00000000
[   83.100118][    C3] mmc0: sdhci: Cmd:       0x0000193a | Max curr: 0x00000000
[   83.107235][    C3] mmc0: sdhci: Resp[0]:   0x00000900 | Resp[1]:  0x00000000
[   83.114353][    C3] mmc0: sdhci: Resp[2]:   0x00000000 | Resp[3]:  0x00000c00
[   83.121470][    C3] mmc0: sdhci: Host ctl2: 0x00000000
[   83.126591][    C3] mmc0: sdhci: ADMA Err:  0x00000400 | ADMA Ptr: 0x74c41208
[   83.133709][    C3] mmc0: sdhci: ============================================
[   93.697611][    C3] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
[   93.697793][    C3] rcu: 	0-...0: (1 GPs behind) idle=73fc/1/0x40000002 softirq=77/78 fqs=1290
[   93.698138][    C3] 	(detected by 3, t=2602 jiffies, g=-1075, q=16 ncpus=4)
[   93.698235][    C3] Sending NMI from CPU 3 to CPUs 0:
[  103.705129][    C3] rcu: rcu_preempt kthread timer wakeup didn't happen for 991 jiffies! g-1075 f0x0 RCU_GP_WAIT_FQS(5) ->state=0x402
[  103.705261][    C3] rcu: 	Possible timer handling issue on cpu=3 timer-softirq=1322
[  103.705347][    C3] rcu: rcu_preempt kthread starved for 992 jiffies! g-1075 f0x0 RCU_GP_WAIT_FQS(5) ->state=0x402 ->cpu=3
[  103.713494][    C3] rcu: 	Unless rcu_preempt kthread gets sufficient CPU time, OOM is now expected behavior.
[  103.723302][    C3] rcu: RCU grace-period kthread stack dump:
[  103.729032][    C3] task:rcu_preempt     state:I stack:0     pid:14    ppid:2      flags:0x00000000


  1. Linux内核移植 part3:Exynos4412内核编译_Camus-CSDN博客 ↩︎

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值