2016-10-10 08:53:05 sUb_569 阅读数 2040
  • Android底层技术:Linux驱动框架与开发

    于此,将框架(Framework)和设计模式(Design Pattern)应用于Linux驱动开发,说明了如何以面向对象、设计模式和框架概念来看待Linux驱动程序的架构。其直接的益处就是:让我们能基于一致的设计理念来结合Android HAL与Linux两层的驱动开发,规划出整体和谐Android-based软硬整合产品架构。

    22683 人正在学习 去看看 高煥堂

底层开发是什么?
是对于计算机核心课程的深入学习。
是学习计算机的厚重与底蕴。
是体会计算机的思维方式。
是精通计算机本质。
是真正职业素养的体现。
绝不是狭隘的只学习一方面的东西。
我们学习空间是整个计算机。

计算机核心课程(本科):
1.数学课 :
初级:高等数学,线性代数,离散数学,概率论与随机过程。
高级: 数理逻辑,数学分析,朴素集合论,组合数学。

2.原理课 :
初级:语言,数据结构与算法 , 操作系统 ,数据库 ,计算机网络 ,编译原理。
高级:高级操作系统,计算机组成原理,计算机系统结构,形式语言与自动机理论(对理解编译原理很有帮助)。

3实践课:
初级:软件工程,面向 过程/对象/函数 程序设计,网络应用及程序设计。
高级(经验):读源码,做项目,写文档

大学开设的课程都是有意义的,是经过筛选,一般对职业生涯有长远意义。可能学校老师讲的不好,教材不好,但是课是好的(可以自学)。所以大多数课都要好好学,尤其是专业课。

图灵奖获奖领域排名:(人数高低从左往右)
编译原理,程序设计语言,计算复杂性理论,人工智能,密码学,数据库。

内核是什么?
帮助我们学习计算机的一个实例,他是计算机科学的集大成者。
他不是计算机的全部。

从底层的角度看看我们学习的计算机
1.语言方面
2.系统方面
3.理论方面
4.实践方面
5.未来方面

2018-05-17 14:59:39 ChenGuiGan 阅读数 770
  • Android底层技术:Linux驱动框架与开发

    于此,将框架(Framework)和设计模式(Design Pattern)应用于Linux驱动开发,说明了如何以面向对象、设计模式和框架概念来看待Linux驱动程序的架构。其直接的益处就是:让我们能基于一致的设计理念来结合Android HAL与Linux两层的驱动开发,规划出整体和谐Android-based软硬整合产品架构。

    22683 人正在学习 去看看 高煥堂

一、嵌入式LINUX底层系统主要包括引导加载程序、LINUX内核、设备驱动程序以及文件系统4部分。

1、引导加载程序

包括固化在固件(firmware)中的boot代码(可选)和BootLoader两部分。

2、LINUX内核

特定于嵌入式板子的定制内核以及内核启动参数。

3、设备驱动程序

设备驱动的作用是将各种设备硬件的复杂物理特性的细节屏蔽,向上提供一个通用的接口,挂接到虚拟文件系统上,向下和硬件设备进行交互。驱动程序是系统软件和硬件外设之间的一个抽象层,在系统中的功能如下图所示。


4、文件系统

包括根文件系统和建立于Flash内存设备之上的文件系统。通常用ramdisk作为rootfs。

二、举例通俗易懂的理解这4大部分。

1、对于PC来说,按下开机键后,BIOS程序对PC进行一些自检,然后从硬盘中读入WINDOS操作系统,并运行WINDOWS操作系统,因为PC中安装的软件较多,故启动较慢。

对于嵌入式系统来说,电路板通电后,Bootloader程序从Flash中读入LINUX内核,并运行LINUX操作系统。嵌入式资源较少,故启动较快。

2、启动电脑后,我们需要上网聊天、看视频、写代码、写文档等,这些软件都安装在C/D/E/F等硬盘中,所以WINDOWS需要能够识别出上述所有硬盘。

在LINUX中,我们需要调用不同的资源完成不同的任务,这些资源存储在LINUX的根文件系统下(类似于硬盘)。

3、WINDOWS能够识别硬盘还不行,必须能够具备读写硬盘的功能,即驱动程序

嵌入式LINUX能够从Flash中读取并执行应用程序,也必须有FLASH的驱动程序



2019-03-05 16:35:54 weixin_42976659 阅读数 86
  • Android底层技术:Linux驱动框架与开发

    于此,将框架(Framework)和设计模式(Design Pattern)应用于Linux驱动开发,说明了如何以面向对象、设计模式和框架概念来看待Linux驱动程序的架构。其直接的益处就是:让我们能基于一致的设计理念来结合Android HAL与Linux两层的驱动开发,规划出整体和谐Android-based软硬整合产品架构。

    22683 人正在学习 去看看 高煥堂

很多初学者会问,嵌入式Linux怎么学?下面就来讨论讨论这个问题。

嵌入式Linux可以分为两部分:底层系统、应用开发。

对于应用开发 : C语言、数据结构、JAVA什么的需学好。嵌入式应用开发和PC上的应用开发并没有什么特别要注意的。也许你说在嵌入式上要做些优化,是的,要优化,但是未经优化的程序和PC上的程序开发没什么差别。另外,当你有能力去优化时,你已经不用来问这个问题了。具体到某个例子,比如说开发界面,在PC上我们用VC;在嵌入式Linux里也许我们用QT也用Android,这个时候你应该去学学QT、Android的编程。但是基础还是C或JAVA,在此基础上去熟悉它们的接口。你学过VC的话,也是要花时间去了解那些类、控件的。

如果你想学习底层系统,这是我的专长,倒是可以说一点。

在回答这个问题之前,我先回答:不少人问我,到底是学驱动还是学应用? 我只能说凭兴趣,并且驱动和应用并不是截然分开的。

我们说的驱动,其实并不局限于硬件的操作,还有操作系统的原理、进程的休眠唤醒调度等概念。想写出一个好的应用,想比较好的解决应用碰到的问题,这些知识你应该懂
做应用门槛低,特别是现在的ANDROID,纯JAVA。做应用的发展路径个人认为就是业务纯熟。比如在通信行业、IPTV行业、手机行业,你了解行业的需求。所以,当领导的人,多是做应用的。
做驱动,其实我不想称为“做驱动”,而是想称为“做底层系统”,做好了这是通杀各行业。我工作几年,做过手机、IPTV、会议电视,但是这些产品对我毫无差别,因为我只做底层。他们的业务跟我没关系。当应用出现问题,他们解决不了时,我就会从内核角度给他们出主意,给他们提供工具。做底层的发展方向,个人认为是技术专家。
其实,做底层还是做应用,之间并没有一个界线,有底层经验,再去做应用,你会感觉很踏实。有了业务经验,你再了解一下底层,很快就可以组成一个团队。
回到怎么学的问题上。嵌入式Linux底层系统包含哪些东西?不要急,举一个例子你就知道了。

电脑一开机,那些界面是谁显示的?是BIOS,它做什么?一些自检,然后从硬盘上读入windows,并启动它。类似的,这个BIOS对应于嵌入式Linux里的bootloader。这个bootloader要去Flash上读入Linux内核,并启动它。

启动windows的目的是什么?当然是上网聊天什么的了。这些上网、聊天工具在哪?在C盘、D盘上。所以, windows要先识别出C盘、D盘。在Linux下我们称为根文件系统。

windows能识别出C盘、D盘,那么肯定能读写硬盘才行。这涉及的东西称为驱动程序。当然不仅仅是硬盘,还有网卡、USB等等。嵌入式Linux能从Flash上读出并执行应用程序,肯定也得有Flash的驱动程序啊,当然也不仅仅是Flash。
先说到这里吧,嵌入式LINUX里含有bootloader, 内核, 驱动程序、根文件系统这4大块。

一、bootloader

它就是一个稍微复杂的裸板程序。但是要把这裸板程序看懂写好一点都不容易。Windows下好用的工具弱化了我们的编程能力。

很多人一玩嵌入式就用ADS、KEIL。你能回答这几个问题吗?

一上电,CPU从哪里取指令执行?
答:一般从Flash上指令。

但是Flash一般是只能读不能直接写的,如果我用到全局变量,这些全局变量在哪里?
答:全局变量应该在内存里

那么谁把全局变量放到内存里去?
答:长期用ADS、KEIL的朋友,你能回答吗?这需要"重定位"。在ADS或KEIL里,重定位的代码是制作这些工具的公司帮你写好了。
你可曾去阅读过?

内存那么大,我怎么知道把"原来存在Flash上的内容"读到内存的"哪个地址去"?
答:这个地址用"链接脚本"决定,在ADS里有scatter文件,KEIL里也有类似的文件。但是,你去研究过吗?

你说重定位是把程序从Flash复制到内存,那么这个程序可以读Flash啊?
答:是的,要能操作Flash。当然不仅仅是这些,还有设置时钟让系统运行得更快等等。
先自问自答到这里吧,bootloader这一个裸板程序,其实有3部分要点:

对硬件的操作

对ARM体系处理器的了解

程序的基本概念:重定位、栈、代码段数据段BSS段什么的。
对硬件的操作,需要看原理图、芯片手册。这需要一定的硬件知识,不求你能设计硬件,但是至少能看懂; 不求能看懂模拟电路,
但是要能看懂数字电路。这方面的能力我是在学校里学到的,微机原理、数字电路这2本书(书名忘了)就足够了。但是我怀疑你有无耐心把这2本书看完。我不知道现在有没有更快捷的书。想速成的话,就先放掉这块吧,不懂就问GOOGLE、发贴。

另外,芯片手册是肯定要读的,别去找中文的,就看英文的。开始是非常痛苦,以后就会发现那些语法、词汇一旦熟悉后, 读任何芯片手册都很容易。

对ARM体系处理器的了解, 看杜春蕾的<ARM体系架构与编程>吧,里面讲有汇编指令,有异常模式、MMU等。也就这3块内容需要你了解。

程序的基本概念,王道当然是去看编译原理了。可惜,这类书绝对是天书级别的。劝你若非超级天才还是别去看了。就看我写的<嵌入式Linux应用开发完全手册>和第1期视频吧,别担心,不用花钱。照着视频把硬件相关的实验做了,这些概念就清楚了。我还没有发现第2套讲这些概念的书或视频,允许我盲目吹嘘一回。

对于bootloader,我学习时是先看了<ARM体系架构与编程>,然后自己写程序把各个硬件的实验都做了一遍,比如GPIO、时钟、 SDRAM、UART、NAND。把它们都弄清楚了,组台在一起就很容易看懂u-boot了 。
总结一下,看懂硬件原理图、看芯片手册,这需要你自己去找资料。剩下的,就按<嵌入式Linux应用开发完全手册>和第1期视频的章 节目录去学习吧。

二、内核

想速成的人,先跨过内核的学习,直接学习怎么写驱动。

想成为高手,内核必须深刻了解。注意,我说的是了解,我没奢望去写出一个内核。

要对里面的调度机制、内存管理机制、文件管理机制等等有所了解。

推荐两本书:

通读<linux内核完全注释>,请看薄的那本(浮燥的社会讲求速度)

选读<Linux内核情景分析>, 想了解哪一块就读哪一节
三、驱动

驱动包含两部分:硬件本身的操作、驱动程序的框架。

又是硬件,还是要看得懂原理图、读得懂芯片手册,多练吧。

说到驱动框架,有一些书介绍一下。LDD3,即<Linux设备驱动>,老外写的那本,里面介绍了不少概念,值得一读。但是,它的作用 也就限于介绍概念了。我基本上是入门之前用它来熟悉一下概念,入门后就扔掉了。

驱动方面比较全的介绍,应该是宋宝华的<linux设备驱动开发详解>了,老实说我只看过目录,有不少人说好,这里推荐一下。

要想深入了解某一块,<Linux内核情景分析>绝对是超5星级推荐。你别指望把它读完,1800多页,上下两册呢。我是某一块不清楚 时,就去翻一下它。任何一部分,这书都可以讲上2、3百页,非常详细。并且是以某个目标来带你分析内核源码。它以linux 2.4为例,但是原理相通,同样适用于其它版本的linux。

把你手上的开发板所涉及的硬件,都去尝试写一个驱动吧。有问题就先"痛苦地思考",思考的过程中你会把很多不相关的知识串联起来,最终贯通。

四、根文件系统

大家有没有想过这2个问题:

对于Linux做出来的产品,有些用作监控、有些做手机、有些做平板。那么内核启动后,挂载根文件系统后,应该启动哪一个应用程序呢?
答:内核不知道也不管应该启动哪一个用户程序。它只启动init这一个应用程序,它对应/sbin/init。

显然,这个应用程序就要读取配置文件,根据配置文件去启动用户程序(监控、手册界面、平板界面等等,这个问题提示我们,文件系统的内容是有一些约定的,比如要有/sbin/init,要有配置文件 。

你写的hello,world程序,有没有想过里面用到的printf是谁实现的?
答:这个函数不是你实现的,是库函数实现的。它运行时,得找到库。

这个问题提示我们,文件系统里还要有库。

简单的自问自答到这里,要想深入了解,可以看一下busybox的init.c,就可以知道init进程做的事情了。
当然,也可以看<嵌入式Linux应用开发完全手册>里构建根文件系统那章。

我的学习经历

我在学校时读的是物理电子专业,其实课程里没有教怎么设计电路,只是教了些电子电路方面的知识。PCB的设计是在实验室里自学的,只设计过2层板,现在忘记得差不多了。但是保留了看原理图、看芯片手册的能力。

选修了软件学位,对软件设计挺感兴趣,但是也只是学了C语言、数据库而已。凭着兴趣做了不少竞赛题。没能力去参加竞赛,但是把C语言练得很扎实。

在实验室、在第1家公司,就是设计些简单的PCI卡,写一下windows的驱动程序

在第2家公司,用51单片机做车载电话,开始走上纯软件的道路。

开始感到单片机的不足,辞职半年闭门学Linux,从red hat怎么操作开始。步骤就是先看<ARM体系架构与编程>,再自己写裸板程序操作硬件,接着到分析u-boot。同时看<linux内核完全注释>,对LINUX框架有所了解。
在写裸板时,建议各位加强对中断的理解,内核就是用中断来完成各种功能的。

分析完u-boot,就开始进行简单的驱动编程了,这时候,能力还很弱。

开始去中兴上班,工作2年,编写各类驱动、解决各类问题(驱动问题、帮助定位应用问题),能力得到煅炼。
总结

硬件方面的书: 微机原理、数字电路,高校里的教材。

Linux方面的书:
<ARM体系架构与编程>
<嵌入式Linux应用开发完全手册>
<Linux设备驱动>,老外写的那本
<linux设备驱动开发详解>
<linux内核完全注释>
<Linux内核情景分析>
在这里插入图片描述
嵌入式Linux底层系统怎么学?

有需要资料的可以加我:腾讯QQ3249838614
或加入嵌入式就业交流群 551627734一起交流 学习 欢迎全国各地的大学生和各位行业大佬一起交流!
(STM32串口应用)http://www.makeru.com.cn/live/detail/1290.html?s=69821
(stm32电机驱动)http://www.makeru.com.cn/live/1392_1218.html?s=69821
(定时器)http://www.makeru.com.cn/live/1392_1199.html?s=69821
(DMA专题讲解)http://www.makeru.com.cn/live/1392_1020.html?s=69821]http://www.makeru.com.cn/live/1392_1048.html?s=69821http://www.makeru.com.cn/live/1392_1020.html?s=69821
( ADC读取光照传感器)http://www.makeru.com.cn/live/1392_1004.html?s=69821
(STM32中断系统)http://www.makeru.com.cn/live/1392_1124.html?s=69821
(时钟系统)http://www.makeru.com.cn/live/1392_1082.html?s=69821
(stm32 实战之温湿度采集)http://www.makeru.com.cn/live/detail/1476.html?s=69821

2016-05-11 15:53:38 give_me_555 阅读数 610
  • Android底层技术:Linux驱动框架与开发

    于此,将框架(Framework)和设计模式(Design Pattern)应用于Linux驱动开发,说明了如何以面向对象、设计模式和框架概念来看待Linux驱动程序的架构。其直接的益处就是:让我们能基于一致的设计理念来结合Android HAL与Linux两层的驱动开发,规划出整体和谐Android-based软硬整合产品架构。

    22683 人正在学习 去看看 高煥堂

Android和Linux底层通信机制实现


Android系统把对硬件的支持分成了两层,一层放在用户空间(User Space),一层放在内核空间(Kernel Space),其中,硬件抽象层(HAL层)运行在用户空间,而Linux内核驱动程序运行在内核空间。

为什么要这样安排呢?这是为了保护厂家的利益,把对硬件的支持逻辑都放在内核空间。我们知道,Linux内核源代码版权遵循GNU License,而Android源代码版权遵循Apache License,前者在发布产品时,必须公布源代码,而后者无须发布源代码。如果把对硬件支持的所有代码都放在Linux驱动层,那就意味着发布时要公开驱动程序的源代码,而公开源代码就意味着把硬件的相关参数和实现都公开了。内核驱动层只提供简单的访问硬件逻辑,例如读写硬件寄存器的通道,至于从硬件中读到了什么值或者写了什么值到硬件中的逻辑,都放在硬件抽象层中去了,这样就可以把商业秘密隐藏起来了。

下图描述了硬件抽象层在Android系统中的位置以及与其它层的关系: 

法术都是



2008-02-25 22:00:00 firePhoenix1981 阅读数 1861
  • Android底层技术:Linux驱动框架与开发

    于此,将框架(Framework)和设计模式(Design Pattern)应用于Linux驱动开发,说明了如何以面向对象、设计模式和框架概念来看待Linux驱动程序的架构。其直接的益处就是:让我们能基于一致的设计理念来结合Android HAL与Linux两层的驱动开发,规划出整体和谐Android-based软硬整合产品架构。

    22683 人正在学习 去看看 高煥堂

Linux网络系统底层机制分析(2

----linux底层的若干机制(续)

3 软中断

下面的内容大都总结自《linux kernel development》。

由于我们希望中断处理函数执行花的时间越短越好,因此,可以把一部分相对不是那么紧急的工作推后执行,这就是下半部的角色。下半部的任务就是执行与中断处理密切相关的但中断处理程序本身不执行的工作。一般来说,中断处理程序完成的任务主要是确认中断,并拷贝数据到内存中,余下的工作便是下半部的事了。

Linux的下半部机制有一个发展的过程,最初是“bottom half---BH”,由于其灵活性不够(静态创建的),存在一定的性能瓶颈,后来引入了任务队列(task queue)以代替BH。但是改善效果不是很明显,在2.3以后,引入了软中断和tasklet,但是仍然保留了task queue

软中断是一组静态定义的接口,定义为:

static struct softirq_action softirq_vec[32] __cacheline_aligned_in_smp;

struct softirq_action

{

void (*action)(struct softirq_action *);/*使用自结构体作为参数可以适应将来可能的改变*/

void *data;/*可以存放实际会使用到的数据*/

};

Tasklet实际上是一种基于软中断的灵活性强的,动态创建的下半部实现机制。但也有一些不同的地方。一般的软中断可以在所有的处理器上同时执行,即使是两个类型相同的也可以(类型相同,指的是在softirq_vecindex相同),而两个类型不同的tasklet可以在不同的处理器上同时执行(这个好理解),但是相同的tasklet则不行。Tasklet其实是一种在性能和易用性之间寻求平衡的产物(见前一个限制。这样的设计可能是因为softirq的执行机会比较多,并且其优先级比较高,对于一些对执行频率不是要求特别高的重要任务,如果也在每个cpu上都可以同时执行,会造成一些浪费,并且对其他的任务影响也比较大。所以处理他别几个特别高级别的任务,可以选择使用tasklet,达到一种妥协。并且这样不用考虑访问冲突),这样不同的任务都可以找到适合自己的机制,不会造成浪费。性能稍比软中断弱一些,但是由于其可以动态创建,灵活性比较强。

现在内核中用到的软中断个数比较少,tasklet占用的indexTASKLET_SOFTIRQ5。网络接收和发送使用了两个软中断号,NET_TX_SOFTIRQ2NET_RX_SOFTIRQ3

软中断必须先触发(raise_softirq)才能被执行,这实际上就是标记一个全局的标志数字--cpu_pending,在将对应的位置1(为什么只是标识本CPU?),通过下面的代码就可以认识它了。软中断都在一个函数中被调用执行:do_softirq,它检查到pending有未决的软中断(不为零)时,调用__do_softirq,下面来看__do_softirq的执行:

......
restart:

/* Reset the pending bitmask before enabling irqs */

set_softirq_pending(0);/*将本cpu对应的cpu_pending字段置为零,它的值已被保存在pending局部变量中。这样做的目的是避免下面处理中产生的中断打乱它的值*/

local_irq_enable();/*打开中断*/

h = softirq_vec;/*h指向静态全局的软中断数组*/

do {

    if (pending & 1) {

        h->action(h);/*如果此软中断号未决,则执行其处理函数*/

        rcu_bh_qsctr_inc(cpu);

      }

      h++;

      pending >>= 1;

} while (pending);

local_irq_disable();/*开中断*/

pending = local_softirq_pending();/*读入本cpupending*/

if (pending && --max_restart)

     goto restart;/*如果本cpu还有未决的软中断,并且尝试的次数还没有到达最大值,则继续处理*/

if (pending)

    wakeup_softirqd();/*达到了最大次数,还有未决软中断,则唤醒处理软中断的内核线程--ksoftirqd,每个cpu一个*/

从上面的处理可以看出:软中断的执行环境是内核上下文,一次的执行可以对软中断循环执行多遍(期间中断有可能触发新的软中断),另外一个是各cpu完全是独立(taskletaction中,通过每个tasklet链表节点的锁--表示此tasklet的状态,来达到限制同一个tasklet不能在不同的cpu上执行的目的)。由于tasklet和网络部分的关系不是特别大,这里就不细说了。

那么哪些地方会执行do_softirq呢?1是从硬件中断返回时;二是在ksoftirqd中;另外是在一些现实检查软中断的子系统,如网络子系统的代码中。上面已经看到了ksoftirqd内核线程在适当的实际会唤醒,网络子系统中对软中断的处理随后将看到,但是硬件中断返回时对软中断的处理是怎么的呢?我们知道中断处理函数在do_IRQ中被调用,在处理完中断线上的处理函数后,会调用irq_exit,在irq_exit中有这样的语句:

if (!in_interrupt() && local_softirq_pending())

       invoke_softirq();/*调用do_softirq或者_do_softirq*/

他检查当前是否是中断上下文,如果不是(),并且有未决的软中断就处理软中断。这几句话看的不是太明白,难道irq_exit还有其他的,不是在中断中的调用点?一查时发现不少调用点,但是不能确定是否都是在中断上下文中的。

 

Linux文件系统和底层驱动的笔记

博文 来自: zhang_yin_liang
没有更多推荐了,返回首页