【嵌入式开发】 Linux Kernel 下载 配置 编译 安装 及 驱动简介(二)

简介: 【嵌入式开发】 Linux Kernel 下载 配置 编译 安装 及 驱动简介(二)

4. 内核编译



简单命令 : 直接使用 make 命令进行编译;




过滤命令行输入 : 将 make 编译信息输出到文件中, 警告 和 错误 会输出到命令行;


-- 输出发到文件 : 使用 make > ../make_log 命令, 会自动将无关的日志存放到 make_log 文件中, 错误和警告提示会显示出来;


-- 输出到黑洞 : 使用 make > /dev/null 命令, 输出的日志信息会自动;




并行编译 : make 可以进行多作业并行编译, 在多核的机器上这样进行编译效率很高;


-- 并行编译弊端 : 如果 Makefile 出现依赖错误, 并行编译会报错, 使用 单作业 make 可以编译通过, 内核无此类错误, 可以并行编译;


-- 使用命令 : make -jn , 其中 n 是一个整数, 例如 make -j4 就是开起 4 个作业同时编译;


-- 多作业编译并输出文件 : make -j4 > make_log, 开启四个作业同时进行编译, 并将编译输出信息存放到 make_log 中;




编译过程 : 使用 make -j4 > make_log 命令, 省略了一部份;



octopus@octopus:~/uplooking/kernel/linux-2.6.32.63$ make -j4 > make_log
scripts/mod/modpost.c: In function ‘get_markers’:
scripts/mod/modpost.c:1562: warning: ignoring return value of ‘asprintf’, declared with attribute warn_unused_result
scripts/mod/modpost.c: In function ‘add_marker’:
scripts/mod/modpost.c:1982: warning: ignoring return value of ‘asprintf’, declared with attribute warn_unused_result
scripts/kallsyms.c: In function ‘read_symbol’:
scripts/kallsyms.c:112: warning: ignoring return value of ‘fgets’, declared with attribute warn_unused_result
WARNING: modpost: Found 2 section mismatch(es).
To see full details build your kernel with:
'make CONFIG_DEBUG_SECTION_MISMATCH=y'







5. 安装内核





(1) 安装内核



编译和安装系统 : 本人用的 Ubuntu 系统, 安装内核比较麻烦, 这里只列出 Redhat 系统安装内核的流程, 即 在 ubuntu 上编译, 在 Redhat 上安装;



a. 内核文件位置



文件位置 : 编译好的内核位于 arch 对应体系结构的目录下的 boot 目录下;


-- 使用默认编译好的配置内核地址 : arch/i386/boot ;



octopus@octopus:~/uplooking/kernel/linux-2.6.32.63/arch/i386/boot$ ls

bzImage


b. 拷贝内核文件



/boot 目录 : 内核文件存放在 /boot 目录下, 下面列举除了 boot 目录下的文件;



[root@ip28 boot]# ls

config-2.6.18-164.el5  initrd-2.6.18-164.el5.img  System.map-2.6.18-164.el5

grub                   symvers-2.6.18-164.el5.gz  vmlinuz-2.6.18-164.el5

-- 内核文件 : 其中的 vmlinuz-2.6.18-164.el5 就是内核, 将 bzImage 文件改名为 vmlinuz-2.6.32.63 即可, 后面是版本号, 该版本是 Linux 内核的 2.6.32.63 版本;



c. 修改 grub.conf 文件



文件位置 : 每个系统中该文件的位置不同, 在 redhat 中内核配置文件是 /etc/grub.conf 文件;



# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You do not have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /, eg.
#          root (hd0,0)
#          kernel /boot/vmlinuz-version ro root=/dev/hda1
#          initrd /boot/initrd-version.img
#boot=/dev/hda
default=0
timeout=5
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
hiddenmenu
title Red Hat Enterprise Linux Server (2.6.18-164.el5)
  root (hd0,0)
  kernel /boot/vmlinuz-2.6.18-164.el5 ro root=LABEL=/ console=tty0 console=ttyS0,9600n8 ide0=noprobe clock=tsccount
  initrd /boot/initrd-2.6.18-164.el5.img

(2) 安装模块



模块安装介绍 : modules 安装可以自动完成, 首先切入到 root 权限下, 执行 make modules_install 命令, 即可将编译好的模块安装到 /lib/modules 目录下;






(3) 符号对照表



生成目录 : 编译的是时候在内核源码根目录生成一个 System.map 的对照表, 这份对照表是 内核中的符号 和 地址对应起来, 比如函数的地址, 变量的地址等;



00000000 A VDSO32_PRELINK
00000040 A VDSO32_vsyscall_eh_frame_size
000001d5 A kexec_control_code_size
00000400 A VDSO32_sigreturn
0000040c A VDSO32_rt_sigreturn
00000414 A VDSO32_vsyscall
00000424 A VDSO32_SYSENTER_RETURN
01000000 A phys_startup_32
c1000000 T _text
c1000000 T startup_32
c1000054 t default_entry



三. 内核开发





1. 关于头文件



不能使用标准库 : 内核中是不存在 标准库 和 标准头文件的;


-- 没有引用 : 标准库实质上就是调用内核中的东西, 此时内核还不存在;


-- 性能考虑 : 链接执行标准库性能很低, 对于内核来说降低性能是致命的;




使用头文件 : 内核中实现了大部分 C 函数, 只要将相关的头文件引入即可;


-- 基本头文件 : 这类头文件在 include 目录下的, 如 字符串处理相关的头文件路径是 include/linux/string.h, 引入 <linux/string.h> 即可使用里面的方法;


-- 体系结构相关头文件 : 这类头文件在 arch/architecture/include/asm 目录下, 如 x86 相关的体系结构头文件在 arch/x86/include/asm 目录下, 引入的时候引入 <asm/xxx.h> 即可;






2. 内核 C 语言标准



内核C语言符合的标准 : 内核不符合 ANSI C 标准, 符合 ISO C99 和 GNU C 标准;






(1) 内联函数



内联函数介绍 : 函数会在其调用的位置展开, 没有函数调用和返回的开销;


-- 函数调用开销 : 函数调用的时候需要 寄存器的存储和恢复;


-- 内联函数优点 : 编译器会把函数代码和其本身一起优化;


-- 内联函数缺点 : 代码展开后会占用跟多空间, 占用更多的指令缓存, 内核中把对时间要求高 并且 本身比较短 的函数定义为内联函数;




内联函数定义 : 使用 sttaic inline 限定函数;


-- 示例 : static inline void hello(char * argv);


-- 使用 static 限制 : 编译时不会为其创建函数体;






(2) 内联汇编



嵌入汇编 : 使用 asm() 指令嵌入汇编;


-- 前提 : C 语言中嵌入的汇编需要与体系结构对应才可以, 例如在笔记本上执行的 C 程序必须嵌入 x86 的汇编才可以, 不能使用 arm 汇编;


-- 示例 : asm volatile("mov %1, %0\n\t" : "=r"(output) : "r"(input));


-- 使用场景 : 在内核中 体系结构底层代码 或者 对时间要求严格的地方使用 汇编语言实现;






(3) 分支声明



选择优化 : gcc 编译器会根据分支选择优化, 条件很少出现的代码不进行优化, 条件很多时候出现的时候才优化;


-- 示例 : likely() 和 unlikely();




标记分支示例 : if(istrue){} 是条件;


-- 标记为很少发生的情况 : if(unlikely(istrue)){};


-- 标记为经常发生的情况 : if(likely(istrue)){};






3. 关于内存保护机制



用户空间的内存保护 : 当用户程序出现非法内存访问, 内核就会发送错误信号, 杀死整个进程;




内核出现内存非法访问 : 会导致整个内核 oops, 这种错误很常见, 而且很难排查;


-- 技巧 : 内核中的内存不分页, 用掉哪些内存都要记住, 否则会出现错误;






4. 关于浮点数



用户空间使用浮点数 : 用户进行浮点运算的时候, 内核会进行从整数到浮点数操作的模式转换;




内核空间使用浮点数 : 内核不能完美支持浮点操作, 其本身不能陷入, 如果非要使用的话 需要人工操作浮点寄存器, 过程相当繁琐;






5. 栈的大小



用户栈 : 用户空间的栈很大, 可以存放巨大的结构体等大数据;




内核栈 : 内核的栈很小, 32位 x86 体系结构上 是 8KB, 64 位的是 16 KB;






6. 同步和并发



内核的同步并发机制 : 内核经常产生竞争, 需要并发访问共享数据, 需要有同步机制保证不出现竞争条件;


-- Linux系统抢占属性 : Linux 是抢占式多任务操作系统, 内核必须和任务同步, 内核中一段代码可能会被另一段抢占, 几段代码可能访问同一资源, 因此需要 自旋锁 信号量等机制保护;


-- Linux 系统对称多处理(SMP)属性 : 多个处理器执行内核代码 可能会导致访问同一资源, 这里也使用 自旋锁 和 信号量机制;


-- 中断保护 : 中断可能在一段代码访问资源的时候到来, 中断处理程序又可能访问同一资源, 又出现多个代码访问同一资源;






四. 驱动简介





1. 驱动和模块



驱动概念 :


-- 实现位置 : 驱动在内核中实现, 一般在内核中的 driver 目录下;


-- 驱动作用 : 驱动的作用是提供 机制(实现什么功能), 不是提供 策略(用户如何使用这种功能), 编写访问硬件的内核代码的时候, 不要给用户强加策略;




可加载模块 : 可以在内核运行时加载的代码叫模块, 每个模块由目标代码组成, 可以在内核运行的时候动态连接到内核中;


-- 机制特点 : 这是一种可以动态加载功能单元来扩展功能的机制, 类似与插件;


-- 与驱动关系 : 内核为每个驱动创建不同的模块, 实现驱动的扩展性;






2. 驱动分类



驱动分类 : 驱动分为 字符设备, 块设备 和  网络设备;




a. 字符设备



字符设备概念 : 这种设备可以像字节流一样访问, 字符设备驱动程序实现这种特性;


-- 字符设备访问方式 : 通过 /dev 下的字符设备文件来访问, 该驱动程序需要实现 open close rad write 系统调用;


-- 顺序访问 : 大部分字符设备只能顺序访问数据, 指针不能前后移动, 如 串口驱动, 只能顺序读写数据;


-- 灵活访问 : 有些字符设备可以移动指针访问, 如 framebuffer 设备;




b. 块设备



块设备概念 :  这种设备按照文件块访问数据, 如 一块为 512 字节, 那么会按照 512 字节访问设备;


-- 块设备访问方式 : 通过 /dev 下面的文件系统访问;


-- 与字符设备区别 : 内核内部管理数据的方式不同, 内核和驱动的接口不同;


-- 访问方式 : 块设备除了提供与字符设备相同的接口之外, 还要提供专门面向块设备的接口;


-- 块设备与文件系统关系 : 块设备支持文件系统挂载, 其能够容纳文件系统, 应用程序可以通过文件系统访问块设备;




c. 网络设备



网络设备概念 : 网络设备不在 /dev 下表示, 是通过单独的网络接口来代表这种设备的;


-- 访问方式 : 网络设备需要通过网络接口进行访问;


-- 实现方式 : 内核与网络设备通信 与 字符设备 和 块设备都不同, 是调用一套数据传输相关的 api 完成这种操作;






3. 设备文件和设备驱动



设备文件简介 :


-- 概念 : 文件系统上的一个节点, 是一种特殊的文件, 每个设备文件代表了一个设备;


-- 位置 : 设备文件一般在 /dev 目录下;


-- 创建命令 : 使用 mknod 命令进行创建;


-- 设备接口 : 设备文件是应用程序和设备驱动之间的接口, 应用程序通过操作设备文件使用设备驱动的功能;


-- 与字符和块设备对应 : 字符设备 和 块设备 必定与一个设备文件对应;




驱动位置 :


-- 内核源码中的位置 : 内核中的驱动在根目录下的 drivers 目录下;



octopus@octopus:~/uplooking/kernel/linux-2.6.32.63/drivers$ pwd
/home/octopus/uplooking/kernel/linux-2.6.32.63/drivers
octopus@octopus:~/uplooking/kernel/linux-2.6.32.63/drivers$ ls
accessibility  built-in.o   dio       hwmon       Kconfig    message        oprofile  ps3        sh         usb
acpi           cdrom        dma       i2c         leds       mfd            parisc    rapidio    sn         uwb
amba           char         edac      ide         lguest     misc           parport   regulator  spi        video
ata            clocksource  eisa      idle        macintosh  mmc            pci       rtc        ssb        virtio
atm            connector    firewire  ieee1394    Makefile   modules.order  pcmcia    s390       staging    vlynq
auxdisplay     cpufreq      firmware  ieee802154  mca        mtd            platform  sbus       tc         w1
base           cpuidle      gpio      infiniband  md         net            pnp       scsi       telephony  watchdog
block          crypto       gpu       input       media      nubus          power     serial     thermal    xen
bluetooth      dca          hid       isdn        memstick   of             pps       sfi        uio        zorro

-- Linunx系统中的位置 : /usr/src/linux-headers-3.11.0-15/drivers ;



root@octopus:/usr/src/linux-headers-3.11.0-15/drivers# ls
accessibility  bus          devfreq   gpu         infiniband  mailbox   mtd      pinctrl    remoteproc  spi      vfio      zorro
acpi           cdrom        dio       hid         input       Makefile  net      platform   reset       ssb      vhost
amba           char         dma       hsi         iommu       md        nfc      pnp        rpmsg       staging  video
ata            clk          edac      hv          ipack       media     ntb      power      rtc         target   virt
atm            clocksource  eisa      hwmon       irqchip     memory    nubus    pps        s390        tc       virtio
auxdisplay     connector    extcon    hwspinlock  isdn        memstick  of       ps3        sbus        thermal  vlynq
base           cpufreq      firewire  i2c         Kconfig     message   parisc   ptp        scsi        tty      vme
bcma           cpuidle      firmware  ide         leds        mfd       parport  pwm        sfi         uio      w1
block          crypto       fmc       idle        lguest      misc      pci      rapidio    sh          usb      watchdog
bluetooth      dca          gpio      iio         macintosh   mmc       pcmcia   regulator  sn          uwb      xen
root@octopus:/usr/src/linux-headers-3.11.0-15/drivers# pwd
/usr/src/linux-headers-3.11.0-15/drivers

常用的驱动简介 :

-- block : 块设备驱动;


-- char : 虚拟中断驱动;


-- serial : 串口驱动;


-- net : 网络设备驱动;


-- vedio : framebuffer 设备驱动;


-- sound : 声卡驱动;



系统中设备驱动信息 : 使用  dmesg 命令查看;


octopus@octopus:~/uplooking/kernel/linux-2.6.32.63/drivers$ dmesg
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Initializing cgroup subsys cpuacct
[    0.000000] Linux version 3.11.0-15-generic (buildd@akateko) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #25~precise1-Ubuntu SMP Thu Jan 30 17:42:40 UTC 2014 (Ubuntu 3.11.0-15.25~precise1-generic 3.11.10)
[    0.000000] KERNEL supported cpus:
[    0.000000]   Intel GenuineIntel
[    0.000000]   AMD AuthenticAMD
[    0.000000]   NSC Geode by NSC
[    0.000000]   Cyrix CyrixInstead
[    0.000000]   Centaur CentaurHauls
[    0.000000]   Transmeta GenuineTMx86
目录
相关文章
|
26天前
|
Linux 编译器 开发工具
【Linux快速入门(三)】Linux与ROS学习之编译基础(Cmake编译)
【Linux快速入门(三)】Linux与ROS学习之编译基础(Cmake编译)
|
28天前
|
人工智能 Java 关系型数据库
Red Hat Enterprise Linux 9.5 发布下载,新增功能亮点概述
Red Hat Enterprise Linux 9.5 发布下载,新增功能亮点概述
69 4
Red Hat Enterprise Linux 9.5 发布下载,新增功能亮点概述
|
12天前
|
关系型数据库 MySQL Linux
MySQL数据库下载安装教程(Windows&Linux)
本文档详细介绍了MySQL的安装步骤,包括安装前的准备工作、下载安装包、Windows和Linux系统下的具体安装流程,以及如何配置MySQL服务、设置环境变量、启动服务和连接数据库等关键操作。
|
25天前
|
NoSQL Linux PHP
如何在不同操作系统上安装 Redis 服务器,包括 Linux 和 Windows 的具体步骤
本文介绍了如何在不同操作系统上安装 Redis 服务器,包括 Linux 和 Windows 的具体步骤。接着,对比了两种常用的 PHP Redis 客户端扩展:PhpRedis 和 Predis,详细说明了它们的安装方法及优缺点。最后,提供了使用 PhpRedis 和 Predis 在 PHP 中连接 Redis 服务器及进行字符串、列表、集合和哈希等数据类型的基本操作示例。
49 4
|
1月前
|
存储 安全 数据管理
如何在 Rocky Linux 8 上安装和配置 Elasticsearch
本文详细介绍了在 Rocky Linux 8 上安装和配置 Elasticsearch 的步骤,包括添加仓库、安装 Elasticsearch、配置文件修改、设置内存和文件描述符、启动和验证 Elasticsearch,以及常见问题的解决方法。通过这些步骤,你可以快速搭建起这个强大的分布式搜索和分析引擎。
40 5
|
1月前
|
Linux 数据安全/隐私保护
适用于 Linux 的最佳命令行下载加速器
适用于 Linux 的最佳命令行下载加速器
53 3
|
29天前
|
存储 缓存 Linux
【Linux】另一种基于rpm安装yum的方式
通过本文的方法,您可以在离线环境中使用RPM包安装YUM并进行必要的配置。这种方法适用于无法直接访问互联网的服务器或需要严格控制软件源的环境。通过配置本地YUM仓库,确保了软件包的安装和更新可以顺利进行。希望本文能够为您在特定环境中部署YUM提供实用的指导。
135 0
|
1月前
|
关系型数据库 MySQL Linux
Linux-安装Mariadb
本文介绍了在 Alibaba Cloud Linux 系统上安装和配置 MariaDB 10.5 的步骤。包括下载安装、初始化数据库、启动服务、处理启动失败的常见问题(如权限问题),以及如何连接数据库、设置密码和允许外部连接。通过这些步骤,您可以顺利完成 MariaDB 的安装和基本配置。
51 0
|
1月前
|
Linux
Linux - 如何编译源码安装软件
源码编译安装通常包括三个步骤:1) `./configure` 检测平台特征和依赖项,生成 Makefile;2) `make` 编译源码,生成可执行文件;3) `make install` 将可执行文件安装到指定目录并配置环境变量。
49 0
|
28天前
|
Linux 网络安全 数据安全/隐私保护
Linux 超级强大的十六进制 dump 工具:XXD 命令,我教你应该如何使用!
在 Linux 系统中,xxd 命令是一个强大的十六进制 dump 工具,可以将文件或数据以十六进制和 ASCII 字符形式显示,帮助用户深入了解和分析数据。本文详细介绍了 xxd 命令的基本用法、高级功能及实际应用案例,包括查看文件内容、指定输出格式、写入文件、数据比较、数据提取、数据转换和数据加密解密等。通过掌握这些技巧,用户可以更高效地处理各种数据问题。
70 8