fl2440-linux内核3.0移植

基于ubuntu14.04,对fl2440开发板进行内核移植。

首先想让代码能在arm板上跑起来,就得用上交叉编译器,我用的crosstools源码网站:
http://crosstool-ng.org/download/crosstool-ng/ 完全兼容 比较大。
然后配置啥的在网上有。
linux内核下载地址:https://www.kernel.org/pub/linux/kernel/v3.x/
内核目录树:
在这里插入图片描述
在这里插入图片描述
  arch
  block
  crypto
  Documentation
  drivers
  firmware
  fs
  include
  init
  ipc
  kernel
  lib
  mm
  net
  samples
  scripts
  security
  sound
  tools
  usr
  virt
下载linux内核3.0版本源码到虚拟机下
创建相应的目录保存自己的以后相应要修改的东西。
在这里插入图片描述
源码的修改
第一个修改:SMDK2440上使用的是16MHz的晶振,而FL2440上使用的是12MHz的晶振,所以开发板相应代码要做修改,改了时钟频率

/fl2440/linux/linux-3.0/arch/arm/mach-s3c2440$ vim mach-smdk2440.c

/* the first modify */
static void __init smdk2440_map_io(void)
{
    s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
-   s3c24xx_init_clocks(16934400);
+   s3c24xx_init_clocks(12000000);
    s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
}

第二个修改:
我们的u-boot给Linux内核传的machine ID值为1999,而Linux内核里smdk2440开发板对应的machine ID是362,所以我们要修改内核代码让
smdk2440的machine ID与u-boot里的保持一致,这里我们在源码中将两个machine ID值互换

/fl2440/linux/linux-3.0/arch/arm/tools$ vim mach-types 

-s3c2440 ARCH_S3C2440 S3C2440 362
+s3c2440 ARCH_S3C2440 S3C2440 1999

-mini2440 MACH_MINI2440 MINI2440 1999
+mini2440 MACH_MINI2440 MINI2440 362

第三个修改:
samsung的串口驱动设备名字默认叫ttySAC,而我们一般使用ttyS,所以将源码中的设备名改掉:

/fl2440/linux/linux-3.0/drivers/tty/serial$ vim samsung.c

/*-#define S3C24XX_SERIAL_NAME  "ttySAC"*/
#define S3C24XX-SERIAL_NAME    "ttyS"

第四个修改:
修改顶层Makefile的ARCH为arm, CROSS_COMPILE为我们自己相应的交叉编译器

/fl2440/linux/linux-3.0$ vim Makefile

-ARCH ?= $(SUBARCH)
-CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
+ARCH ?= arm
+CROSS_COMPILE ?= /opt/xtools/arm920t/bin/arm-linux-4.4.6

内核配置
内核配置命令make menuconfig是非常重要操作,他负责指导makefile进行众多c文件的编译,所以要想这么多c文件有条理的编译,一定要进行相应的配置
Kconfig也是很重要的文本文件,在每一个文件夹下都有一个Kconfig,Kconfig产生的效果就是在make menuconfig中产生很多的配置选项,像一个菜单一样
同样make menuconfig也会产生相应的文件.config隐藏文件这个文件就可以指导makefile工作了,所以makefile Kconfig .config有着密不可分的关系,缺一不可。
在这里插入图片描述
我们是使用S3C2440做的SMDK2440开发板,所有其他的开发板都不应该选择。
我们的交叉编译器使用的是EABI接口,所以这里一定要修改配置,否则跑不起来。

make命令首先编译linux源码 然后会生成一个内核启动zImage的文件在arch/arm/boot/下,这就是给u-boot加载的文件,但是zImage并不能被u-boot的bootm命令启动,而需要使用mkimage工具在其前面加上bootm命令启动内核所需要的64字节(0x40)头信息方可启动,处理后的文件一般叫做uImage。

关于image:
Linux 内核有两种映像:一种是非压缩内核,叫 Image,另一种是它的压缩版本,叫zImage。根据内核映像的不同,Linux内核的启动在开始阶段也有所不同。zImage是Image经过压缩 形成的,所以它的大小比 Image小。但为了能使用zImage,必须在它的开头加上解压缩的代码,将 zImage解压缩之后才能执行,因此它的执行速度比Image要慢。但考虑到嵌入式系统的存储空容量一般比较小,采用zImage可以占用较少的存储空 间,因此牺牲一点性能上的代价也是值得的,所以一般的嵌入式系统均采用压缩内核的方式。
编译完成后,会在内核目录arch/arm/boot/下生成zImage内核映像文件。

写一个脚本完成一系列操作

#!/bin/bash
make
mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 30008040 -n "Linux Kernel" -d arch/arm/boot/zImage linuxroms3c2440.bin
chmod a+x linuxrom-s3c2440.bin

mkimage 如果没有的话,sudo apt-get install u-boot-tools。
-A arch
-O OS
-T type
-C 压缩类型为未压缩
-a uImage的入口地址
-e zImage的入口地址
-n zImage名字
-d 路径

修改修改的时候任意字符敲错可能都会出错,我就是那个改了出错又改的傻子。。。
然后执行chomd a+x build.sh 给权限,执行./build.sh
一万多个c文件外加一千多个汇编文件…所以编译时间非常漫长(差不多半个小时)

Two thousand years later…
在这里插入图片描述
然后我们就得到了我们的uimage文件 也就是我们的linuxrom-s3c2440.bin文件。
烧到开发板上跑

WARNING: at fs/sysfs/dir.c:455 sysfs_add_one+0x84/0xac()
sysfs: cannot create duplicate filename '/class/tty/ttyS2'
Modules linked in:
[<c003a078>] (unwind_backtrace+0x0/0xf4) from [<c0048b20>] (warn_slowpath_common+0x48/0x60)
[<c0048b20>] (warn_slowpath_common+0x48/0x60) from [<c0048bcc>] (warn_slowpath_fmt+0x30/0x40)
[<c0048bcc>] (warn_slowpath_fmt+0x30/0x40) from [<c00f596c>] (sysfs_add_one+0x84/0xac)
[<c00f596c>] (sysfs_add_one+0x84/0xac) from [<c00f6a40>] (sysfs_do_create_link+0x114/0x204)
[<c00f6a40>] (sysfs_do_create_link+0x114/0x204) from [<c01d17f8>] (device_add+0x32c/0x590)
[<c01d17f8>] (device_add+0x32c/0x590) from [<c01d1b00>] (device_create_vargs+0x8c/0xb0)
[<c01d1b00>] (device_create_vargs+0x8c/0xb0) from [<c01d1b44>] (device_create+0x20/0x28)
[<c01d1b44>] (device_create+0x20/0x28) from [<c01a7a9c>] (tty_register_device+0x6c/0xe0)
[<c01a7a9c>] (tty_register_device+0x6c/0xe0) from [<c01bfb24>] (uart_add_one_port+0x128/0x36c)
[<c01bfb24>] (uart_add_one_port+0x128/0x36c) from [<c01c6808>] (s3c24xx_serial_probe+0x4c/0x94)
[<c01c6808>] (s3c24xx_serial_probe+0x4c/0x94) from [<c01d4838>] (platform_drv_probe+0x18/0x1c)
[<c01d4838>] (platform_drv_probe+0x18/0x1c) from [<c01d3570>] (driver_probe_device+0x84/0x188)
[<c01d3570>] (driver_probe_device+0x84/0x188) from [<c01d3700>] (__driver_attach+0x8c/0x90)
[<c01d3700>] (__driver_attach+0x8c/0x90) from [<c01d2dfc>] (bus_for_each_dev+0x68/0x90)
[<c01d2dfc>] (bus_for_each_dev+0x68/0x90) from [<c01d26bc>] (bus_add_driver+0xa0/0x238)
[<c01d26bc>] (bus_add_driver+0xa0/0x238) from [<c01d3ce0>] (driver_register+0x78/0x13c)
[<c01d3ce0>] (driver_register+0x78/0x13c) from [<c0028378>] (do_one_initcall+0x34/0x188)
[<c0028378>] (do_one_initcall+0x34/0x188) from [<c00083c0>] (kernel_init+0x74/0x110)
[<c00083c0>] (kernel_init+0x74/0x110) from [<c0035b78>] (kernel_thread_exit+0x0/0x8)
---[ end trace 65f8ea860415c051 ]---
Cannot register tty device on line 2

抛了这个bug,问题是串口驱动冲突,然后继续配置menuconfig
Device Drivers —>
Character devices —>
Serial drivers —>
把<> 8250/16550 and compatible serial support取消
再烧,然后就没有问题了
然后就会出现内核启动的信息,包括内核版本、CPU、GPIO、硬件接口(i2C)、flash文件系统、flash分区、还有各种驱动的消息
最终找不到跟文件系统然后就终止。
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值