jz2440-linux3.4.2-kernel移植【学习笔记】【原创】
平台:jz2440
作者:庄泽彬(欢迎转载,请注明作者)
说明:韦东山二期视频学习笔记
交叉编译工具:arm-linux-gcc (GCC)4.3.2
linux:linu3.4.2
PC环境:ubuntu18.04
一、kernel的编译和烧录:
下载linux-3.4.2版本进行移植,下载链接:https://mirrors.edge.kernel.org/pub/linux/kernel/v3.x/
修改顶层Makefile,设置为arm架构,以及设置交叉工具链
1 zhuang@zhuang:~/project/3-jz2440/systems/linux-3.4.2$ git diff . 2 diff --git a/Makefile b/Makefile 3 index 901a9557..9cc1639a 100644 4 --- a/Makefile 5 +++ b/Makefile 6 @@ -192,8 +192,8 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ 7 # Default value for CROSS_COMPILE is not to prefix executables 8 # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile 9 export KBUILD_BUILDHOST := $(SUBARCH) 10 -ARCH ?= $(SUBARCH) 11 -CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%) 12 +ARCH ?= arm 13 +CROSS_COMPILE ?= arm-linux- 14 15 # Architecture as present in compile.h 16 UTS_MACHINE := $(ARCH)
编译:
1 make s3c2410_defconfig 2 make uImage -j4
哎呀,竟然报了下面这个错误:
应该是高版本的make导致这个错误出现的,按照错误的log修改文件。
修改如下:
1 diff --git a/kernel/timeconst.pl b/kernel/timeconst.pl 2 index eb51d76e..04612394 100644 3 --- a/kernel/timeconst.pl 4 +++ b/kernel/timeconst.pl 5 @@ -370,7 +370,7 @@ if ($hz eq '--can') { 6 } 7 8 @val = @{$canned_values{$hz}}; 9 - if (!defined(@val)) { 10 + if (!@val) { 11 @val = compute_values($hz); 12 } 13 output($hz, @val);
生成对应的uImage :
上述编译出来的内核烧录到板子加载内核却出现乱码,出现乱码,有可能是我们的机器ID没有设置好,导致调用的初始化错误导致的。:
二 、内核的启动
uboot启动内核主要的操作如下,从nandflash里把内核读入内存,设置TAG参数(内存的起始地址大小,命令行参数等等),R1存放机器ID,R2存放参数的存放地址,内核在启动的时候会解析TAG参数,根据uboot传递过来的机器ID,判断是否能够支持该机器,从而调用对应板子的初始化函数.
uboot设置机器ID的代码主要流程如下:
Smdk2410.c (board\samsung\smdk2440)
board_init
gd->bd->bi_arch_number = MACH_TYPE_SMDK2410; //设置机器ID的默认值
Bootm.c (arch\arm\lib)
boot_jump_linux
unsigned long machid = gd->bd->bi_arch_number;
s = getenv("machid"); //可根据环境变量设置机器ID
我在cmdline随便设置一个machid,看看内核支持那些板子
set machid 33333
启动过程打印的log,根据log可以看出有匹配对应的开发板子的一个过程,最后由于匹配失败,卡在这里。
OK Using machid 0x33333 from environment Starting kernel ... Uncompressing Linux... done, booting the kernel. Error: unrecognized/unsupported machine ID (r1 = 0x00033333). Available machine support: ID (hex) NAME 00000400 AML_M5900 0000014b Simtec-BAST 0000015b IPAQ-H1940 0000039f Acer-N35 00000290 Acer-N30 000002a8 Nex Vision - Otom 1.1 00000454 QT2410 000000c1 SMDK2410 000005b4 TCT_HAMMER 000001db Thorcom-VR1000 000005d2 JIVE 000003fe SMDK2413 000003f1 SMDK2412 00000377 S3C2413 00000474 VSTMS 00000695 SMDK2416 000002de Simtec-Anubis 00000707 AT2440EVB 000007cf MINI2440 000002a9 NexVision - Nexcoder 2440 0000034a Simtec-OSIRIS 00000250 IPAQ-RX3715 0000016a SMDK2440 00000518 GTA02 000003b8 HP iPAQ RX1950 0000043c SMDK2443
2.1 支持mini2440开发板的machid 7cf
设置cmdline波特率为115200
1 set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
nfs 32000000 192.168.1.100:/work/nfs_root/uImage //烧录内核命令
设置machid为mini2440的开发板7cf,启动,串口不会有乱码.
2.2支持smdk2440开发板的machid 16a
设置machid为smdk2440开发板16a,串口却出现乱码:
我们来看看内核smd2440开发板初始化代码,是不是跟jz2440有差异:
Mach-smdk2440.c (arch\arm\mach-s3c24xx)
MACHINE_START(S3C2440, "SMDK2440")
/* Maintainer: Ben Dooks <ben-linux@fluff.org> */
.atag_offset = 0x100,
.init_irq = s3c24xx_init_irq,
.map_io = smdk2440_map_io, //这个函数的初始化化有点问题,
.init_machine = smdk2440_machine_init,
.timer = &s3c24xx_timer,
.restart = s3c244x_restart,
MACHINE_END
static void __init smdk2440_map_io(void)
{
s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
s3c24xx_init_clocks(16934400); //jz2440开发板是12M的晶振,使用使用smdk2440的machid,这里要修改为12000000
s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
}
代码修改如下,支持smdk2440开发板,串口输出不会有乱码:
zhuang@zhuang:~/project/3-jz2440/systems/linux-3.4.2$ git diff . diff --git a/arch/arm/mach-s3c24xx/mach-smdk2440.c b/arch/arm/mach-s3c24xx/mach-smdk2440.c index 83a1036d..b92c2bd5 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2440.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2440.c @@ -162,7 +162,7 @@ static struct platform_device *smdk2440_devices[] __initdata = { static void __init smdk2440_map_io(void) { s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc)); - s3c24xx_init_clocks(16934400); + s3c24xx_init_clocks(12000000); //jz2440开发板是12M的晶振,使用使用smdk2440的machid,这里要修改为12000000 s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs)); }
设置为smdk2440开发板的machid 16a,启动系统串口没有输出乱码见下图:
三、修改内核分区
内核将nandflash分区划分如下:
1 0x00000000-0x00040000 : "bootloader" 2 0x00040000-0x00060000 : "params" 3 0x00060000-0x00260000 : "kernel" 4 0x00260000-0x10000000 : "root"
代码修改如下:
1 diff --git a/arch/arm/mach-s3c24xx/common-smdk.c b/arch/arm/mach-s3c24xx/common-smdk.c
2 index 084604be..f7dce9b9 100644
3 --- a/arch/arm/mach-s3c24xx/common-smdk.c
4 +++ b/arch/arm/mach-s3c24xx/common-smdk.c
5 @@ -110,43 +110,23 @@ static struct platform_device smdk_led7 = {
6
7 static struct mtd_partition smdk_default_nand_part[] = {
8 [0] = {
9 - .name = "Boot Agent",
10 - .size = SZ_16K,
11 + .name = "bootloader",
12 + .size = SZ_256K,
13 .offset = 0,
14 },
15 [1] = {
16 - .name = "S3C2410 flash partition 1",
17 - .offset = 0,
18 - .size = SZ_2M,
19 + .name = "params",
20 + .offset = MTDPART_OFS_APPEND,
21 + .size = SZ_128K,
22 },
23 [2] = {
24 - .name = "S3C2410 flash partition 2",
25 - .offset = SZ_4M,
26 - .size = SZ_4M,
27 - },
28 - [3] = {
29 - .name = "S3C2410 flash partition 3",
30 - .offset = SZ_8M,
31 + .name = "kernel",
32 + .offset = MTDPART_OFS_APPEND,
33 .size = SZ_2M,
34 },
35 - [4] = {
36 - .name = "S3C2410 flash partition 4",
37 - .offset = SZ_1M * 10,
38 - .size = SZ_4M,
39 - },
40 - [5] = {
41 - .name = "S3C2410 flash partition 5",
42 - .offset = SZ_1M * 14,
43 - .size = SZ_1M * 10,
44 - },
45 - [6] = {
46 - .name = "S3C2410 flash partition 6",
47 - .offset = SZ_1M * 24,
48 - .size = SZ_1M * 24,
49 - },
50 - [7] = {
51 - .name = "S3C2410 flash partition 7",
52 - .offset = SZ_1M * 48,
53 + [3] = {
54 + .name = "rootfs",
55 + .offset = MTDPART_OFS_APPEND,
56 .size = MTDPART_SIZ_FULL,
57 }
58 };
59 zhuang@zhuang:~/project/3-jz2440/systems/linux-3.4.2$
内核启动将会把nandflash划分为上述四个分区
四、制作新的文件系统
3.1编译busybox1.20.0
解压busybox
tar -xvf busybox-1.20.0.tar.bz2
设置交叉工具链make menuconfig
编译
1 make
安装
1 make install CONFIG_PREFIX=/work/nfs_root/fs_mini_mdev_new
从交叉工具链安装glibc
1 cd /work/nfs_root/fs_mini_mdev_new 2 mkdir lib usr/lib
3 cp /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib/*so* lib/ -d
4 cp /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/usr/lib/*so* usr/lib/ -d
创建etc目录
1 mkdir etc
在etc目录下创建inittab文件
1 vim inittab //内容从2-6行 2 # /etc/inittab 3 ::sysinit:/etc/init.d/rcS 4 console::askfirst:-/bin/sh 5 ::ctrlaltdel:/sbin/reboot 6 ::shutdown:/bin/umount -a -r
在etc目录下穿件init.d/rcS文件
1 mkdir init.d 2 vim init.d/rcS
chmod a+x init.d/rcS //设置为可执行文件 3 rcS文件内容如下: 4 #!/bin/sh 5 6 mount -a 7 mkdir /dev/pts 8 mount -t devpts devpts /dev/pts 9 echo /sbin/mdev > /proc/sys/kernel/hotplug 10 mdev -s
在etc目录下创建fstab文件:内容如下:
1 # device mount-point type options dump fsck order 2 proc /proc proc defaults 0 0 3 tmpfs /tmp tmpfs defaults 0 0 4 sysfs /sys sysfs defaults 0 0 5 tmpfs /dev tmpfs defaults 0 0
创建dev目录:
1 mkdir dev 2 sudo mknod console c 5 1 3 sudo mknod null c 1 3
创建其他目录
1 mkdir proc tmp mnt sys root
编译制作jffs2映像文件的工具
1 tar -xvf mtd-utils-05.07.23.tar.bz2 2 cd mtd-utils-05.07.23/util 3 make 4 sudo make install
//根据需要有可能要先编译zlib库
将fs_mini_mdev_new目录制作成文件系统镜像命令:
1 mkfs.jffs2 -n -s 2048 -e 128KiB -d fs_mini_mdev_new -o fs_mini_mdev_new.jffs2
在uboot中将文件系统和内核烧录进系统命令
1 nfs 30000000 192.168.1.100:/work/nfs_root/fs_mini_mdev_new.jffs2 2 nand erase.part rootfs 3 nand write.jffs2 30000000 260000 $filesize 4 set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2 5 //烧录内核 6 nfs 32000000 192.168.1.100:/work/nfs_root/uImage
7 bootm 32000000
启动系统,却报了如下的错误,这是由于我们的交叉工具链接在编译的时候是使用eabi接口的,内核也要使用这种接口才行
进入内核make menuconfig,加上EABI接口
重新烧录系统,成功进入系统没有问题。
五、移植yaffs文件系统
下载yaffs文件系统的链接:https://yaffs.net/get-yaffs
或者使用git下载命令:
1 git clone git://www.aleph1.co.uk/yaffs2
将yaffs文件系统源码安装到内核:
./patch-ker.sh c m /home/zhuang/project/3-jz2440/systems/linux-3.4.2
make menuconfig选中yaffs文件系统
编译却报了如下的错误:
查看内核struct mtd_info的定义,并没有sync成员而是_sync,把报错的地方都加上_即可。
将文件系统制作成yaffs2文件系统镜像
1 mkyaffs2image fs_mini_mdev_new fs_mini_mdev_new.yaffs2
烧录启动:
1 nfs 30000000 192.168.1.100:/work/nfs_root/fs_mini_mdev_new.yaffs2 2 nand erase.part rootfs 3 nand write.yaffs 30000000 260000 $filesize
觉得不错,就给我点小支持吧,蟹蟹
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2017-10-01 在android系统调试中使用tinyalsa命令【转】
2017-10-01 linux驱动由浅入深系列:tinyalsa(tinymix/tinycap/tinyplay/tinypcminfo)音频子系统之一【转】