物聯網之系統移植三(內核分析)

Linux內核分析筆記:https://blog.csdn.net/weixin_39148042/article/details/82494809

Linux內核分析

1、基本概念

2、啓動分析

3、調試方法

Linux內核基本概念

Linux內核

• 從技術上說 linux 是一個內核

• “內核”指的是一個提供硬件抽象層、磁盤及文件系統控制、多任務等功能的系統軟件。一個內核不是一套完整的操作系統。

• 通常我們使用的 linux 系統是一個集 linux 內核、工具集、各種庫、桌面管理器、應用程序等一體的一個發佈包 (發行版)‏

主流的 Linux 發行版

Debian GNU/Linux

Red Hat Linux

Fedora Core

Ubuntu Linux

SUSE Linux

Gentoo Linux

Asianux

Slackware Linux

Turbo Linux

CentOS

Linux 內核的特性

• 免費開源

• 可以移植,支持的硬件平臺廣泛

     arm, i386, m68k, m32r,m68knommu, mips, ppc, s390, sh, sparc

• 高可擴展性

‐ 可剪裁、可擴展,可以運行在大型主機,也可以運行在個人計算機上

• 高可靠性、穩定性

‐ 穩定性是linux鮮明特點,安裝了linux系統的主機,

‐ 連續運行一年不宕機是很平常的事情

• 超強的網絡功能

• 真正的多任務,多用戶系統

• 模塊化設計

‐ 模塊可以動態加載,卸載,可以減少系統體積,同時可以用來解決衝突問題,模塊調試

Linux內核版本

• 目前linux系統採用 A.B.C.D 的版本號管理方式

– A 表示linux的主版本號

– B 表示linux的次版本號,B 爲偶數表示穩定版本,奇數表示開發中的版本

– C 表示linux的發行版本號

– D 表示更新版本號

• 主版本(X.Y)

– 1.0   2.0  2.2   2.4  2.6  3.x

Linux內核子系統

進程管理

內存管理

文件系統

網絡協議

設備管理

Linux內核模塊結構圖

編譯內核(已移植好的)

• 編譯內核    make uImage

• 編譯設備樹  make dtbs

Linux內核代碼結構

Linux系統源代碼目錄結構

Linux內核啓動分析

嵌入式系統啓動信息分析

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 ...

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

根文件系統階段(可運行應用程序)

[root@farsight ]# ls

a.out    dev      lib      mnt      root     sys      usr

bin      etc      linuxrc  proc     sbin     tmp      va

嵌入式系統 啓動流程

    //階段一(彙編) 

   設置爲SVC模式,關閉中斷,MMU,看門狗

   基本硬件設備初始化  //初始化時鐘,串口,flash,內存   

   自搬移到內存         

   設置好棧 跳轉到C階段

   //階段二(C語言)

   大部分硬件初始化

   搬移內核到 內存

   運行內核

內核啓動流程

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)

   

Linux內核調試方法

內核調試方法     點燈法

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]

內核調試方法     printk打印輸出信息

    puts   (內核解壓前)

printascii  (console初始化前)

printk (內核解壓後,信息輸出顯示是在 console 初始化之後)

 

    通過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

– 打印級別:

#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”);

內核調試方法     OOP內核異常信息

1.  製造錯誤

    修改drivers/char/fs4412_led_drv.c

    在s5pv210_led_init函數中int  ret=0;下增加下面語句: int *ptr  =  NULL; *ptr  = 0xff;

 

 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. 找出錯位置 

    根據PC is at s5pv210_led_init+0x18/0x180 知道出錯的函數是s5pv210_led_init

    根據pc : [<c024225c>]  知道出錯的位置

    #arm-none-linux-gnueabi-addr2line c024225c -e vmlinux -f   在源碼中會顯示具體出錯的位置

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章