0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

嵌入式未来还是Linux的天下,并通过内核学习来阐述kernel的机理

Q4MP_gh_c472c21 2018-01-24 08:47 次阅读

首先阐述一下我为什么想学习一下Linux kernel。最早是因为对嵌入式的一时脑热,我买了开发板,买了不少资料,前前后后投进去了1000多了。不过好歹还是有点回报的,虽然还没有怎么着调,但又似乎拓宽了不小的知识面。

慢慢的我发现,对于从学软件入手的我来说,硬件知识的薄弱是个不容忽视的缺陷,毕竟软硬件间的代沟还是不小的,就像现在的老爹和fashion闺女一样,鸿沟还是忽视不得的。这有点让我望而却步,不过多大的困难都无法阻挡我的前进啊。我对策略稍作调整,因为我发现,嵌入式无论是现在,还是未来一段时间都还是Linux的天下;另外是真正的做Linux的大牛们似乎也都有涉足embedded system 的经历。这就使得仅仅会管理Linux系统和服务,简单的用几个Shell commands ,编译安装几个Linux应用,读懂几个Makefile……根本满足不了需求;另外也为了不让学习的OS知识只是空洞的理论。这都要求着自己必须有编写自己Shell程序的能力;要求着可以在Linux做程序开发的能力;要求着可以自己往kernel中附加自定义的系统调用、重组内核、添加自写驱动……的能力。这就要求着必须深入了解,正如任何一门技术一样,接触久了你就有种相地层实现挖掘的冲动。

调整后的策略就是先把Linux这个OS的机制弄明白,才可以迁移定制满足需求的系统,才可以写出高效率的Linux应用。整体路线就是农村包围城市,不断补充必要知识,循序渐进,最终呈现星星之火可以燎原之势。额,扯得够远。废话不多说,下面开始。

Kernel入门,要选本好的入门书籍,我从网上download一本《Linux内核设计与实现》。这本书简单易读,有OS基础和Linux应用基础的人一读即懂,我现已阅过3章,感觉很不错,另外配合《Linux操作系统内核实习》效果更佳。我想尽可能通过更加通俗的形式向你阐述kernel的机理,让我们一起如喝凉水般拿下kernel。

首先介绍一下内核源码的根目录描述:

arch(architecture) 特定体系结构的源码

crypto crypto API

Documention 内核源码文档

drivers 设备驱动程序

fs VFS和各种文件系统

include 内核头文件

init 内核引导和初始化

ipc 进程间通讯代码

kernel 像调度程序这样的核心子系统

lib 通用内核函数

mm 内存管理子系统和VM

net 网络子系统

scripts 编译内核所用到的脚本

security Linux安全模块

sound 语音子系统

usr 早期用户空间代码(所谓的initramfs)

这里只是简单阐述个目录及系统模块分布。随着慢慢地学习我相信一定可以把它们搞明白是怎么一回事的。

另外,你需要明白一些Linux必备的一些常识性名词解释知识,这里罗列一些名词,不明白的不再一一阐述,自己百度,Google:管态、目态、内核空间、用户空间、POSIX、system V、GNU、GPL、GNOME、KDE、QT、GTK+、openGL、shell、awk、Makefile、CC、GCC、G++、GDB、Perl……

下面来介绍一下内核开发和应用程序开发的差别:

内核编程时不能访问C库(因为Linux下很多C库函数是对Linux系统调用的封装,自身怎么可以调用自身呢?)

内核编程时必须使用GNU C。

内核编程时缺乏像用户空间那样的内存保护机制。

内核编程时浮点数很难使用。

内核只有一个很小的定长堆栈。

由于内核支持异步中断、抢占和SMP,因此必须时刻注意同步和并发。

要考虑可移植性的重要性。

对以上这几点进行描述。

1、首先就是内核不能访问C库的问题,你想啊Linux下很多C库函数是对Linux系统调用的封装,自身怎么可以调用自身呢?这里的系统调用学过OS的应该都清楚,是系统应用给用户提供的编程接口,注意这里的对象是用户。注意啦,程序员也是分等级的,在kernel级别的编程(这里指纯kernel编程),你已经看不到系统调用,此时你的职责可能就是为系统添加一个系统调用(后边会讲到),且C库是应用层对底层系调(系统调用,为了便于我打字,后边可能会多次出现)的封装,从逻辑的角度你也该明白了吧。那么问题就出来了,没有c库怎么办,还谈什么模块化,难不成都自己写?这就是接下来的问题。

2、既然kernel不能调用C库,那么它就得拥有自己独立的c语言库,这样才能高内聚低耦合,并且提升其安全性,所以就用了GNU C 。短小精悍效率高,毕竟是专才专用。这里需要注意一点,内核中没有实现printf();但是有功能更为强大的printk();其实也谈不上功能强大(因为printf()本身就很强大,尤其是在调试时,这里也显出了printk的优势),它和printf()的显著区别就是printk()允许通过指定一个标志来设置优先级。Syslog会根据这个优先级标志来决定什么地方显示这条系统消息。如:

printk( KERN_ERR “This is an error!”); //不理解吧,我也不理解,后边内核调试时肯定还会将这东西,不怕。

3、内核编程时缺乏像用户空间那样的内存保护机制。

你在做什么?内核好不好,这是一个OS的核心部分,控制着整个系统的运转,自然要有处理协调整个系统的权利,在内核coding的东西就是OS核心的一部分,是给别人或者自己在OS的上一层用的。既然你是把握这一切的,且又是在硬件基础上的第一层抽象,另外还把握着全局,内存的控制自然也不能束缚你,就像在公司工作一样,领导要在可能的范围内尽可能的下放权力,下属才能发挥他的极致,估计kernel也是这样,内存访问,包括其他的内核结构都不对出于内核的你进行束缚,当然也没有进行相应的保护机制。因为这是的内核是你的,你没必要傻逼到写程序让自己的系统崩溃吧,哈哈。这也留了一个问题,就是在coding过程中要斟酌好啊。

4、内核编程时浮点数很难使用。这里你需要知道的是在用户空间的进程进行浮点操作时,kernel会完成从整数到浮点数的模式转换,一般是通过捕获陷阱并作相应的处理的实现的。//陷阱可以算是一种特殊的异常,是从用户态进入内核态的途径,以后会进一步介绍。

与用户空间不同的是,kernel并不能完美的支持浮点操作,因为自身不能陷入自身。在kernel中使用浮点数时,除了要人工保存和恢复浮点寄存器,还有很多琐碎的事要做。直截了的说就是:不要在kernel中使用浮点数!!!

5、内核只有一个很小的定长堆栈。在x86上,kernel的栈是在编译时配置的,可为4k或者8k,且每个处理器都有自己的栈。为什么这么小呢?大了不可以么?我的理解是,现在都在追求微内核,这是一方面原因,还有就是内核也是一个软件,只不过是包含了硬件抽象且富含大量系统管理功能的进程,而其他功能的进程(系统调用,其他内核进程),在调度是,存在内核抢占和代替内核执行的情况,这是要将要执行的进程的上下文切换过来,当然这些数据都会出现在栈里边,你想如果栈很大,那么操作时内存访问地址会很长,访问时占内存且费时间,会降低效率,所以要尽可能的小且灵活……

6、由于内核支持异步中断、抢占和SMP,因此必须时刻注意同步和并发。这不仅仅是linux kernel ,是所有现有的多进程/多线程并发OS都要注意的,包括多线程编程也一样,你就把kernel想成是一个多线程的执行程序就OK了,不难理解。

7、要考虑可移植性的重要性。这个更不用多说了,因为这是linux的一个灰常显著的特征,大到企业的服务器,小到嵌入式的android,IP camera……等很多东西不同平台构架的cpu……应该是目前跑的平台最多的OS了,所以他的内核要有足够的可移植性,似乎有点java的感觉......

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    4975

    文章

    18235

    浏览量

    287827
  • 内核
    +关注

    关注

    3

    文章

    1309

    浏览量

    39831
  • Linux
    +关注

    关注

    87

    文章

    10974

    浏览量

    206670
  • Kernel
    +关注

    关注

    0

    文章

    48

    浏览量

    11032

原文标题:嵌入式未来一段时间还是Linux天下,一位嵌入式er初探Linux kernel经验

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    嵌入式资料 Kernel__LINUX内核设计与实现(第二版)

    嵌入式资料Kernel__LINUX内核设计与实现(第二版)
    发表于 11-11 21:46

    嵌入式Linux学习步骤

    服务 配置NFS服务 下载Bootloader和内核 嵌入式Linux应用软件开发流程熟悉嵌入式系统概念以及开发流程 建立嵌入式系统开发环境
    发表于 03-24 10:41

    学习嵌入式LINUX的笔记和体会

    结构的模式学习嵌入式linux将会是我们认识更清晰,简单可行使应用具有弹性。 快速入门 最简单的建立
    发表于 06-23 18:37

    嵌入式开发板的学习方法

    ,C语言编程基础,就可以学习嵌入式linux的基本框架了, 学习路线:单片机,C语言编程基础Linux基础框架:(BootloaderKer
    发表于 03-30 17:21

    学习嵌入式Linux的笔记和体会

    应用和内核捆绑在一起,甚至可以把应用写为内核的一个线程,在内核中运行,虽然这样在移植上带来了困难,但考虑嵌入式系统对尺寸要求小的特点,是完全可行的。不过我们使用三层软件结构的模式
    发表于 05-19 14:44

    嵌入式linux入门学习规划

    0.11版,适合学习。最后深入代码。 主攻书籍:linux内核完全剖析、unix环境高级编程、深入理解linux内核、情景分析和源代。 3、
    发表于 08-21 17:46

    嵌入式Linux怎么学?给大家推荐几本学习嵌入式系统的书籍

    上读入windows,启动它。类似的,这个BIOS对应于嵌入式Linux里的bootloader。这个bootloader要去Flash上读入Linux
    发表于 09-18 16:03

    嵌入式Linux学习步骤

    编译下载U-boot 编译下载Linux内核 编译下载Linux应用程序 5、
    发表于 07-03 00:56

    嵌入式未来的就业前景怎么样?

    的薪水?还是门槛。比如月薪 15k的 Linux嵌入式开发职位,门槛就有 Linux系统、 Shell编程、 Linux开发环境、 C语言、
    发表于 11-02 21:37

    嵌入式Linux系统基础概念讲解

    进行层次划分。嵌入式Linux系统做模块化处理就是可划分为Bootloader(引导程序),Kernel(内核),fs(文件系统),Shell(命令行界面),Gui(图形库)和 Emb
    发表于 12-25 16:37

    嵌入式系统基础阶段的学习建议

    内核机制》· 《Mastering Linux Kernel Development》7、Linux 内核开发与实践· 《
    发表于 10-29 07:36

    嵌入式Linux系统的资料大合集

    进行层次划分。嵌入式Linux系统做模块化处理就是可划分为Bootloader(引导程序),Kernel(内核),fs(文件系统),Shell(命令行界面),Gui(图形库)和 Emb
    发表于 10-28 06:41

    作为新人要如何学习嵌入式Linux

    作为新人,要如何学习嵌入式Linux?首先您要具备基本的C语言基础,然后,您要想好学习嵌入式Linux
    发表于 11-08 09:27

    如何通过网络升级嵌入式系统的linux内核

    通过网络升级嵌入式系统的linux内核1、首先修改u-boot分配两个kernel分区,kernel
    发表于 12-16 06:48

    嵌入式Linux内核编译

    实验环境VMware Workstation PlayerUbuntu16.04kernel-3.2.tar.bz2Linux内核编译在ubuntu上编译嵌入式Linux
    发表于 11-01 17:07 16次下载
    <b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b>的<b class='flag-5'>内核</b>编译