基于 移植uboot后.

1. 移植linux内核

1.1 下载源码

打开 https://www.kernel.org/ 直接肝最新的 5.2.8

下载完后,在ubuntu里解压备用.

1.2 搭建交叉编译环境

. 交叉编译环境用的是arm-linux-gcc 4.6.4的版本,这个版本挺好找的,在网上下载压缩包后,根据个人习惯解压到
/opt/ 下, . 并且修改环境变量
sudo vim /etc/profile
export PATH=/opt/gcc-4.6./bin:$PATH . 保存,然后source /etc/profile 进行更新.稳妥起见,ubuntu要注销一下,重新登录. . 确定:在窗口输入arm-linux-gcc -v 显示的是你的编译环境就可以啦.

注:是可以多版本gcc编译器 " 伪共存 " 的,我这里就是gcc 3.4 的也有一份, 需要的时候,把环境变量注释一下留下需要的版本就好了.我觉得这样很方便.

1.3 修改时钟频率和mtd分区

s3c2440 支持2中时钟晶振:12MHz 和 16MHz,我这个板子上用的是12MHz,
所以修改 arch/arm/mach-s3c2440/mach-smdk2440.c s3c24xx_init_clocks();
改为:
s3c24xx_init_clocks();
修改nand 分区
arch/arm/mach-s3c24xx/common-smdk.c static struct mtd_partition smdk_default_nand_part[] = {
[] = {
.name = "uboot",
.size = SZ_256K,
.offset = ,
},
[] = {
.name = "env",
.offset = MTDPART_OFS_APPEND,
.size = SZ_128K,
},
[] = {
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = SZ_4M,
},
[] = {
.name = "rootfs",
.offset = MTDPART_OFS_APPEND,
.size = SZ_8M,
},
[] = {
.name = "appfs",
.offset = MTDPART_OFS_APPEND,
.size = SZ_8M,
},
}; //可自行修改,注因为内核编译完有3.4M,所以降kernel的分区改成了4M,根文件系统用的是jffs2,填充成了8M大小,所以这里是8M

1.4 配置linux内核

, 修改Makefile

搜索ARCH ,找到
ARCH ?= $(SUBARCH)
注释掉改成 ARCH ?= arm //因为要编译arm架构体系的. 这一步是代替编译的时候, make V=s ARCH=arm . 在下一行直接添加 交叉编译链
CROSS_COMPILE ?= arm-linux-
ok. 这样子,make menuconfig 就是arm架构的了.
. make menuconfig

这里我用的因为是s3c2440 的soc, 所以 选择最接近的s3c2410的模板来进行修改.
怎么查看有没有适合自己的呢?
这些config文件在: [ ./arch/arm/config/ ]下

使用: 在linux内核根目录下,执行

. make s3c2410_defconfig 就可以自动进行拷贝和更新.
. 然后make menuconfig 进行微调
. 保存: make savedefconfig 进行配置保存,
. 存档: cp davedefconfig /arch/arm/config/你想保存的型号, 我这里是s3c2440_defconfig make s3c2410_defconfig
make menuconfig
make savedefconfig
cp davedefconfig /arch/arm/config/s3c2440_defconfig

言归正传,怎么配置内核,make menuconfig 开头显示当前的交叉编译链, 如果没有配置交叉编译环境的话,当前的环境就是ubuntu的环境.

然后怎么配置:太繁琐了,附上网上的教程.

[https://blog.csdn.net/tk01044242_1/article/details/78815816]

1.5 制作uImage

make V=s 先编译看是否出错. 这里我先前编译未能通过,原因是用了3.+的gcc, 后来改成了新的编译器(4.6.)就没有再报错. 新的内核还是用新的编译器,就得内核用旧的编译器这是道理.

制作uImage
make V=s uImage
后面报错: OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready
UIMAGE arch/arm/boot/uImage
"mkimage" command not found - U-Boot images will not be built
arch/arm/boot/Makefile:: recipe for target 'arch/arm/boot/uImage' failed
make[]: *** [arch/arm/boot/uImage] Error
arch/arm/Makefile:: recipe for target 'uImage' failed
make: *** [uImage] Error //可以看到,zImage是编译完成了,但是说mkimage命令不支持, 所以uImage没有生成成功 把uboot源码文件夹中的mkimage(可执行文件) 拷贝到/sys/local/bin中,这样编译器就能支持给iamge添加64k的uboot头信息.形成uImage.这个文件去下一个uboot源码中获得. 最后生成的uImage 在 /arch/arm/boot中.

不出意外的话,内核就编译完成了.

1.6 烧录测试

我用的是tftp的方式 .
我的内核是3.4M, 按4M的空间来算,就是 0x400000
所以 tftp 0x30000000 uImage //这里的0x30000000 是三星内存的起始地址,临时的一个空间,掉电后就会消失,所以下一步就是要把这个固件 写入到不会丢失的nand flash中. 当然,这个时候,bootm 0x30000000 是可以直接启动内核的,只是掉电丢失. nand flash 写入的规则是,写入前要擦除.所以 nand erase 0x60000 0x400000 //为什么是0x60000 呢, 由下:
我的uboot环境是:
// mtdparts=nandflash0:256k@0(bootloader),128k(params),4m(kernel),-(root)
可知,+128k = 384k * = = 0x60000 ,所以前面2个空间占据了[~ 0x60000]的空间,因此,内核空间从0x60000开始.
0x400000 则是有uImage镜像大小决定,取大取整就好. 然后 我原本以为是 nand write 0x30000000 0x60000 0x400000 ,这样做的时候, uboot确实校验到头部信息了,但是总是 整个内核crc失败.不知道为什么.
在百度的时候,无意间看到: nand write.jffs2 0x30000000 0x60000 0x400000 ,居然就可以了...
可见差别在 nand write 和 nand write.jffs2上.
//1. 用tftp 将uImage 拷贝到临时内存中
tftp 0x30000000 uImage //2. 擦除nand flash中 属于kernel的区域
nand erase 0x60000 0x400000 //3. 将uImage 写入到nand flash
nand write.jffs2 0x30000000 0x60000 0x400000 //4.运行的时候,要将固件搬运到内存中运行
nand read.jffs2 0x30007fc0 0x60000 0x400000 //5.从内核处启动:
bootm 0x30007fc0
因为我的uboot参数是
bootcmd=nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0 所以我将nand flash中的内核,读到内存 0x30007FC0后 ,从这个地方开始执行内核的第一条,是核对uboot加入的64K的头部信息 bytes read: OK
## Booting image at 30007fc0 ...
Image Name: Linux-5.2.
Created: -- :: UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: Bytes = 3.3 MB
Load Address:
Entry Point:
Verifying Checksum ... OK
XIP Kernel Image ... OK 这里,如果写入方式[write.jffs2]正确的话,就会通过crc校验,否则就是crc error.
如果因为启动地址和搬运地址不匹配,未能识别到64K的uboot头, 会显示magic number err.

执行到后面,会提示panic 内核崩溃,因为我们文件系统还没做,所以会提示错误.

内核部分已经完成.

下一篇介绍 文件系统 的制作, 让系统真正跑起来.

.

最新文章

  1. oracle同一个数据库实例不同的用户之间的表、序列授权操作
  2. 64位系统里的IIS运行32位ODP.NET的方法
  3. Azure上七层负载均衡APP Gateway
  4. Web API应用架构设计分析(1)
  5. Messenger
  6. iptables配置(/etc/sysconfig/iptables)
  7. JAVA Builder模式构建MAP/LIST的示例
  8. android studio 编译加速
  9. 【Gym 100971A】Treasure Island
  10. sql回滚
  11. Java编程思想学习笔记_5(IO流)
  12. C语言第二节概述
  13. 201521123093 java 第二周学习总结
  14. python字符串常用内置方法
  15. Android——具有边框的Textview
  16. JAVA中通过Jaxp操作XML文件基础
  17. AspNetCore OpenId
  18. ASPxGridView 用法
  19. Graphics
  20. eclipse将javaSE项目导出成可执行jar包

热门文章

  1. .NET项目迁移到.NET Core操作指南
  2. Linux操作系统下文件作用
  3. idea中向pom.xml添加依赖时显示”not found dependency“
  4. Python之爬虫有感(一)
  5. 关于css样式加载的问题
  6. DML语言DDL
  7. C#3.0新增功能09 LINQ 基础05 使用 LINQ 进行数据转换
  8. [leetcode]914. X of a Kind in a Deck of Cards (easy)
  9. 最短代码实现包含100个key的字典,且每个value值不同
  10. element 上传组件 el-upload 的经验总结