【嵌入式开发】 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
目录
相关文章
|
7天前
|
存储 IDE Linux
零基础保姆级教程!手把手教你免费玩转Linux CentOS安装+学习环境搭建(附避坑指南)
本文详细介绍了在VMware虚拟机中安装CentOS 6.8的全过程。首先,需确保已安装VMware并开启V-CPU虚拟化功能,可通过BIOS设置或使用LeoMoon CPU-V工具检测。接着,下载CentOS镜像文件,并在VMware中新建虚拟机,配置CPU、内存、硬盘等参数。最后,加载ISO镜像启动虚拟机,按照提示完成CentOS的安装,包括语言、键盘、存储方式、地区、密码设置及硬盘分区等步骤。安装完成后,以root用户登录即可进入系统桌面,开始学习Linux命令和操作。
53 12
零基础保姆级教程!手把手教你免费玩转Linux CentOS安装+学习环境搭建(附避坑指南)
|
1天前
|
关系型数据库 MySQL 应用服务中间件
Linux 手动安装快速部署 LNMP 环境实战
本文详细记录了在阿里云ECS上手动搭建LNMP环境的过程,系统选用Ubuntu 24.04。主要内容包括:1) 使用`apt`安装Nginx和MySQL,并更新软件源;2) 编译安装PHP 8.4.5,配置PHP-FPM及环境路径;3) 配置MySQL root用户密码;4) 调整Nginx支持PHP解析并测试整体环境。通过此过程,重现手动配置服务器的细节,帮助熟悉各组件的安装与协同工作。
|
1天前
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
40 18
|
20天前
|
缓存 Ubuntu Linux
Linux中yum、rpm、apt-get、wget的区别,yum、rpm、apt-get常用命令,CentOS、Ubuntu中安装wget
通过本文,我们详细了解了 `yum`、`rpm`、`apt-get`和 `wget`的区别、常用命令以及在CentOS和Ubuntu中安装 `wget`的方法。`yum`和 `apt-get`是高层次的包管理器,分别用于RPM系和Debian系发行版,能够自动解决依赖问题;而 `rpm`是低层次的包管理工具,适合处理单个包;`wget`则是一个功能强大的下载工具,适用于各种下载任务。在实际使用中,根据系统类型和任务需求选择合适的工具,可以大大提高工作效率和系统管理的便利性。
112 25
|
10天前
|
人工智能 Linux iOS开发
Linux下搭建本地deepseek(附文档下载)
本文介绍了在Linux上搭建本地DeepSeek的步骤。主要涉及安装ollama、下载deepseek模型(1.5b参数版本)和配置ChatboxAI客户端。通过命令行安装ollama后,使用`ollama run deepseek-r1:1.5b`下载模型,并配置环境变量以确保服务正常运行。最后,通过ChatboxAI与模型进行交互。整个过程适合初学者,服务器配置为4核CPU和8GB内存,无GPU,响应速度稍有延迟但可接受。相关资源链接已提供。
90 2
|
25天前
|
Linux API
Linux下载工具wget与curl
`wget` 是一个用于从网络下载文件的命令行工具,支持HTTP、HTTPS和FTP协议。它能自动处理下载中断,并支持递归下载网站内容。基本用法:`wget URL`,可指定文件名(`-O`)、保存目录(`-P`),还支持断点续传(`-c`)、限速(`--limit-rate`)和递归下载(`-r`)。相比之下,`curl` 更侧重于发送各种HTTP请求(如GET、POST),并支持文件上传、自定义请求头和cookie等功能。
57 10
|
1月前
|
Ubuntu Java Linux
Linux 安装 Qualcomm ® SnapdragonTM Profiler
通过本文的详细介绍,您应该已经成功在 Linux 系统上安装并配置了 Qualcomm® Snapdragon™ Profiler,并能够连接 Android 设备进行性能分析。Snapdragon Profiler 提供了丰富的工具和功能,可以帮助开发者深入了解应用程序的性能瓶颈,从而进行优化。希望本文能对您有所帮助,让您在开发过程中更高效地使用 Snapdragon Profiler 进行性能分析和优化。
78 10
|
1月前
|
Linux
Linux安装svn并启动
Linux安装svn并启动
60 10
|
2月前
|
Oracle 关系型数据库 Linux
linux8安装oracle 11g遇到的问题记录
Oracle 11g在Linux 8上安装时会遇到link编译环节的问题。官方建议忽略安装中的链接错误,安装完成后应用DBPSU 11.2.0.4.240716补丁及一次性补丁33991024,再重新编译二进制文件,并配置监听器和数据库。但因11g已退出服务期,这些补丁需付费获取。网上信息显示22年1月的PSU补丁也可解决问题,找到该补丁后按常规方式打补丁即可。如有需求或疑问可咨询我。
103 20
|
2月前
|
弹性计算 运维 Ubuntu
os-copilot在Alibaba Cloud Linux镜像下的安装与功能测试
我顺利使用了OS Copilot的 -t -f 功能,我的疑惑是在换行的时候就直接进行提问了,每次只能写一个问题,没法连续换行更有逻辑的输入问题。 我认为 -t 管道 功能有用 ,能解决环境问题的连续性操作。 我认为 -f 管道 功能有用 ,可以单独创建可连续性提问的task问题。 我认为 | 对文件直接理解在新的服务器理解有很大的帮助。 此外,我还有建议 可以在非 co 的环境下也能进行连续性的提问。
89 7