嵌入式linux-系统移植,Linux内核编译,设备树编译,Linux内核基本概念,内核启动流程,内核调试方法(点灯法,printk打印输出信息,OOP内核异常信息)

文章目录

1,基本概念

1.1,Linux内核

从技术上说 linux 是一个内核
“内核”指的是一个提供硬件抽象层、磁盘及文件系统控制、多任务等功能的系统软件。一个内核不是一套完整的操作系统。
通常我们使用的 linux 系统是一个集 linux 内核、工具集、各种库、桌面管理器、应用程序等一体的一个发布包 (发行版)‏

1.2,主流的 Linux 发行版

Debian GNU/Linux
Red Hat Linux
Fedora Core
Ubuntu Linux
SUSE Linux
Gentoo Linux
Asianux
Slackware Linux
Turbo Linux
CentOS

1.3,Linux 内核的特性

免费开源
可以移植,支持的硬件平台广泛
arm, i386, m68k, m32r,m68knommu, mips, ppc, s390, sh, sparc
高可扩展性
可剪裁、可扩展,可以运行在大型主机,也可以运行在个人计算机上
高可靠性、稳定性
稳定性是linux鲜明特点,安装了linux系统的主机,
连续运行一年不宕机是很平常的事情
超强的网络功能
真正的多任务,多用户系统
模块化设计
模块可以动态加载,卸载,可以减少系统体积,同时可以用来解决冲突问题,模块调试

1.4,Linux内核版本

目前linux系统采用 A.B.C.D 的版本号管理方式
A 表示linux的主版本号
B 表示linux的次版本号,B 为偶数表示稳定版本,奇数表示开发中的版本(下载B 为偶数的版本
C 表示linux的发行版本号
D 表示更新版本号
主版本(X.Y)
1.0 2.0 2.2 2.4 2.6 3.x

1.5,Linux内核子系统

进程管理
内存管理
文件系统
网络协议
设备管理

  1. linux系统不是正真的实时系统(采用时间片轮转的方式做的)
  2. 美国军方的Vxwork是正真的实时系统(中断抢占)

1.6,Linux内核模块结构图

在这里插入图片描述

  1. 应用访问内核要通过系统调用
  2. 内核访问硬件要通过映射

1.7,linux内核编译(移植好的)

1.7.1,拷贝到linux并解压,然后编译

linux@linux:~$ cp /mnt/hgfs/Linuxsharexiaomei/linux-3.14-fs4412.tar.xz 
linux@linux:~$ tar -vxf linux-3.14-fs4412.tar.xz 
linux@linux:~/linux-3.14-fs4412$ ls
arch      cd       crypto         firmware          include  Kbuild   lib          mm              README          scripts   tools
block     COPYING  Documentation  fs                init     Kconfig  MAINTAINERS  Module.symvers  REPORTING-BUGS  security  usr
build.sh  CREDITS  drivers        fs4412_defconfig  ipc      kernel   Makefile     net             samples         sound     virt
linux@linux:~/linux-3.14-fs4412$ make uImage 

1.7.2,linux内核编编译出错make[1]: `include/generated/mach-types.h’ is up to date.

linux@linux:~/linux-3.14-fs4412$ make uImage 
  CHK     include/config/kernel.release
  CHK     include/generated/uapi/linux/version.h
  CHK     include/generated/utsrelease.h
make[1]: `include/generated/mach-types.h' is up to date.
  CALL    scripts/checksyscalls.sh
  GEN     scripts/mod/devicetable-offsets.h
  HOSTCC  scripts/mod/file2alias.o
scripts/basic/fixdep: 1: scripts/basic/fixdep: Syntax error: "(" unexpected
make[2]: *** [scripts/mod/file2alias.o] Error 2
make[1]: *** [scripts/mod] Error 2
make: *** [scripts] Error 2
1.7.2.1,解决方案
linux@linux:~/linux-3.14-fs4412$ make clean
linux@linux:~/linux-3.14-fs4412$ make uImage 

1.7.3,linux内核编译出错"mkimage" command not found - U-Boot images will not be built

  SHIPPED arch/arm/boot/compressed/bswapsdi2.S
  AS      arch/arm/boot/compressed/bswapsdi2.o
  LD      arch/arm/boot/compressed/vmlinux
  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
make[1]: *** [arch/arm/boot/uImage] Error 1
make: *** [uImage] Error 2
1.7.3.1,解决方案
linux@linux:~/linux-3.14-fs4412$ sudo apt-get install uboot-mkimage
[sudo] password for linux: 
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Package uboot-mkimage is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
  u-boot-tools

E: Package 'uboot-mkimage' has no installation candidate
linux@linux:~/linux-3.14-fs4412$ sudo apt-get install u-boot-tools 

1.7.4,编译成功

Image Name:   Linux-3.14.0
Created:      Fri Jan 11 19:41:27 2019
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    3014944 Bytes = 2944.28 kB = 2.88 MB
Load Address: 40008000
Entry Point:  40008000
  Image arch/arm/boot/uImage is ready

1.7.5,测试

1.7.5.1,备份原有的,拷贝新编译的
linux@linux:~/linux-3.14-fs4412$ mv /tftpboot/uImage /tftpboot/uImage.ok
linux@linux:~/linux-3.14-fs4412$ cp arch/arm/boot/uImage /tftpboot/
1.7.5.2,开发板重新上电,在串口终端中,查看启动信息

在这里插入图片描述

成功启动

1.8,编译设备树(设备树是3.14内核之后特有的)

1.8.1,编译设备树

linux@linux:~/linux-3.14-fs4412$ make dtbs
  DTC     arch/arm/boot/dts/exynos4210-origen.dtb
  DTC     arch/arm/boot/dts/exynos4210-smdkv310.dtb
  DTC     arch/arm/boot/dts/exynos4210-trats.dtb
  DTC     arch/arm/boot/dts/exynos4210-universal_c210.dtb
  DTC     arch/arm/boot/dts/exynos4412-odroidx.dtb
  DTC     arch/arm/boot/dts/exynos4412-origen.dtb
  DTC     arch/arm/boot/dts/exynos4412-fs4412.dtb
  DTC     arch/arm/boot/dts/exynos4412-smdk4412.dtb
  DTC     arch/arm/boot/dts/exynos4412-tiny4412.dtb
  DTC     arch/arm/boot/dts/exynos4412-trats2.dtb
  DTC     arch/arm/boot/dts/exynos5250-arndale.dtb
  DTC     arch/arm/boot/dts/exynos5250-smdk5250.dtb
  DTC     arch/arm/boot/dts/exynos5250-snow.dtb
  DTC     arch/arm/boot/dts/exynos5420-arndale-octa.dtb
  DTC     arch/arm/boot/dts/exynos5420-smdk5420.dtb
  DTC     arch/arm/boot/dts/exynos5440-sd5v1.dtb
  DTC     arch/arm/boot/dts/exynos5440-ssdk5440.dtb
linux@linux:~/linux-3.14-fs4412$ 

1.8.2,测试

1.8.2.1,备份原有的,拷贝需要的
linux@linux:~/linux-3.14-fs4412$ mv /tftpboot/exynos4412-fs4412.dtb /tftpboot/exynos4412-fs4412.dtb.ok
linux@linux:~/linux-3.14-fs4412$ cp arch/arm/boot/dts/exynos4412-fs4412.dtb /tftpboot/
linux@linux:~/linux-3.14-fs4412$ cd /tftpboot/
linux@linux:/tftpboot$ ls
exynos4412-fs4412.dtb  exynos4412-fs4412.dtb.ok  uImage  uImage.ok
1.8.2.2,开发板重新上电,观察启动信息

1.9,Linux内核代码结构

在这里插入图片描述

目录简介
kernel/ Linux 内核管理核心源码
内核核心调度算法
arch/
arch/arm/mach-exynos
arch/目录 存放体系结构、平台相关代码(如arm系列,powerpc系列等)
arch/arm/目录存放arm系列不同机器型号的代码(自己新开发了一个机器,就要新增加一个,比如:arch/arm/mach-exynos,就是4412开发板的)
drivers/ 所有的驱动代码 (drivers/usb/, etc.)‏
专门和硬件打交道的代码
include/
include/asm-
内核头文件
体系结构相关头文件
Linux内核基本的头文件(保留类型和配置)
include/linux/lib混合库代码 (zlib, crc32...)‏
fs/文件系统代码 (fs/ext3/, etc.)‏
ipc/进程通讯相关代码
mm/内存管理代码
net/网络协议代码

2,启动分析

2.1,嵌入式系统启动信息分析

  1. u-boot启动阶段
U-Boot 2013.01 (Aug 24 2014 - 12:01:19) for FS4412
CPU:	Exynos4412@1000MHz
Board: FS4412
DRAM:  1 GiB
……Loading: * ######################
Starting kernel ...
  1. linux内核启动阶段
Booting Linux on physical CPU 0xa00
Linux version 3.14.0 (david@ubuntu)
CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=10c5387d
Machine model: Insignal Origen evaluation board based on Exynos4412
IP-Config: Complete:
VFS: Mounted root (nfs filesystem) on device 0:10
  1. 根文件系统阶段(可运行应用程序)
[root@farsight ]# ls
a.out    dev      lib      mnt      root     sys      usr
bin      etc      linuxrc  proc     sbin     tmp      va

2.2,嵌入式系统 启动流程

在这里插入图片描述

    //阶段一(汇编) 
   设置为SVC模式,关闭中断,MMU,看门狗
   基本硬件设备初始化  //初始化时钟,串口,flash,内存    
   自搬移到内存          
   设置好栈 跳转到C阶段
   //阶段二(C语言)
   大部分硬件初始化
   搬移内核到 内存
   运行内核

2.3,内核启动流程

a. 自解压内核 decompess (arch/arm/boot/compressed/head.S)
b. 运行内核汇编部分 head.S 入口stext (arch/arm/kernel/head.S)
检测合法性(CPU 类型,机器类型)
c. 运行内核C部分 start_kernel (init/main.c)
CPU,机器参数的安装 setup_arch
中断,定时,终端,内存等最基本的初始化
创建核心进程 kernel_init运行,启动多任务调度
d. 挂载rootfs(根文件系统)
e. 运行第一个应用程序init (一般是 linuxrc)

3,调试方法

3.1,点灯法

启动过程中,串口无打印信息,可以将最简单的LED灯的汇编代码,加入到想要分析的文件的,相应的代码位置,通过看灯有没有被点亮,从而判断程序有没有执行到这里

		ldr r0, =0x11000c40 @GPK2_7 led2
		ldr r1, [r0]
		bic r1, r1, #0xf0000000
		orr r1, r1, #0x10000000
		str r1, [r0]
		
		ldr r0, =0x11000c44
		mov r1,#0xff
		str r1, [r0]

3.2,printk打印输出信息

3.2.1,三个打印函数

	puts   (内核解压前用)
	printascii  (内核解压后,console(串口)初始化前)
	printk (内核解压后,信息输出显示是在 console 初始化之后)

3.2.2,打印级别:

#define KERN_EMERG        "<0>"   	/* system is unusable           */
#define KERN_ALERT        "<1>”     /* action must be taken immediately */
#define KERN_CRIT         "<2>"   	/* critical conditions          */
#define KERN_ERR          "<3>"   	/* error conditions         */
#define KERN_WARNING      "<4>"   	/* warning conditions           */
#define KERN_NOTICE       "<5>"     /* normal but significant condition */
#define KERN_INFO         "<6>"   	/* informational            */
#define KERN_DEBUG        "<7>"   	/* debug-level messages
printk( KERN_INFO “ \n  INFO Level \n”);

3.2.3,通过proc在运行时查看和修改日志级别

cat /proc/sys/kernel/printk            显示   4 4 1 7
echo “7 4 1 7” > /proc/sys/kernel/printk  后 
cat /proc/sys/kernel/printk            显示7 4 1 7

3.2.4,例

3.2.4.1,在init/main.c中加入printk()打印信息

在这里插入图片描述

3.2.4.2,编译uImage,并拷贝至/tftpboot/目录
linux@linux:~/linux-3.14-fs4412$ make uImage


linux@linux:~/linux-3.14-fs4412$ cp arch/arm/boot/uImage /tftpboot/
3.2.4.3,开发板上电重启,查看打印信息

在这里插入图片描述

3.3,OOP内核异常信息

3.3.1,制造错误

修改drivers/char/fs4412_led_drv.c
在s5pv210_led_init函数中int  ret=0;下增加下面语句: int *ptr  =  NULL; *ptr  = 0xff;

3.3.2,运行该内核报错

	[    1.165000] Unable to handle kernel NULL pointer dereference at virtual address 00000000
	[    1.170000] pgd = c0004000
	[    1.175000] [00000000] *pgd=00000000
	[    1.175000] Internal error: Oops: 805 [#1] PREEMPT SMP ARM
	[    1.180000] Modules linked in:
	[    1.185000] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.14.0 #25
	[    1.190000] task: ee8a0000 ti: ee8a4000 task.ti: ee8a4000
	[    1.195000] PC is at s5pv210_led_init+0x18/0x180
	[    1.200000] LR is at do_one_initcall+0x30/0x144
	[    1.205000] pc : [<c024225c>]    lr : [<c00087b4>]    psr: 60000153
	[    1.205000] sp : ee8a5ef8  ip : c059afac  fp : 00000000
	[    1.215000] r10: c052d4fc  r9 : c0564b80  r8 : c0242244
	[    1.220000] r7 : c05a3400  r6 : c055134c  r5 : 00000000  r4 : ee8a4000
	[    1.230000] r3 : 00000055  r2 : c04c0430  r1 : 00000001  r0 : 1f400000
	[    1.235000] Flags: nZCv  IRQs on  FIQs off  Mode SVC_32  ISA ARM  Segment kernel
	[    1.245000] Control: 10c5387d  Table: 4000404a  DAC: 00000015
	[    1.250000] Process swapper/0 (pid: 1, stack limit = 0xee8a4240)
	[    1.255000] Stack: (0xee8a5ef8 to 0xee8a6000)

3.3.3,找出错位置

根据PC is at s5pv210_led_init+0x18/0x180 知道出错的函数是s5pv210_led_init
根据pc : [<c024225c>]  知道出错的位置
#arm-none-linux-gnueabi-addr2line c024225c -e vmlinux -f   在源码中会显示具体出错的位置

3.3.4,例

3.3.4.1,制造错误

在这里插入图片描述

3.3.4.2,编译

在这里插入图片描述

查看编译信息,发现没有编译drivers/char/fs4412_led_drv.c

3.3.4.3,临时修改drivers/char/Makefile

在这里插入图片描述

3.3.4.4,再次编译,如果成功,拷贝至/tftpboot/目录

在这里插入图片描述

3.3.4.5,开发板上电重启,查看串口终端打印信息

在这里插入图片描述

3.3.4.6,如果还是不能确定具体位置,可以通过arm-none-linux-gnueabi-addr2line反向定位出错位置
linux@linux:~/linux-3.14-fs4412$ arm-none-linux-gnueabi-addr2line c024225c -e  vmlinux -f 
s5pv210_led_init
/home/linux/linux-3.14-fs4412/drivers/char/fs4412_led_drv.c:71

在/home/linux/linux-3.14-fs4412/drivers/char/fs4412_led_drv.c文件的第71行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值