另外,当你具备了优化的能力,你就不再需要问这个问题了。举个具体的例子,比如开发一个界面,我们在PC上用VC;在嵌入式Linux上,我们可能用QT或者Android。这时候你就应该学QT和Android编程。但基础还是C或者JAVA,在这个基础上熟悉它们的界面。如果你学过VC,你也应该花时间去了解那些类和控件。
如果你的目的是学习系统底层,也就是我的专长,我可以稍微说一下,在回答这个问题之前,我先回答一下:很多人问我,到底应该学驱动还是学应用程序?
我只能说是凭兴趣,驱动和应用不是截然分开的。 1.我们说的驱动不仅限于硬件操作,还包括操作系统的原理,进程的休眠唤醒调度等概念。如果想写出好的应用,更好的解决应用遇到的问题,这些知识是应该知道的。 2.做应用的门槛低,特别是现在ANDROID,纯JAVA。我个人认为做应用的发展路径就是精通业务,比如做通讯行业,IPTV行业,手机行业,你懂行业的需求。所以,做leader的人,大部分都是做应用的。 3.做驱动,其实我不想叫“做驱动”,我想叫“做底层系统”,如果做好了,什么行业都可以用。我工作几年了,做过手机,做过IPTV,做过会议电视,但是这些产品对我来说没什么区别,因为我只做底层的工作。 他们的事情跟我没关系,当应用出现问题,他们解决不了的时候,我会从内核角度给他们建议,给他们提供工具。

我个人认为做底层的发展方向是做技术专家。 4.其实做底层和做应用是没有界限的,有底层经验再做应用,会觉得很安心,有业务经验,了解底层之后可以很快组建团队。 回到怎么学的问题,嵌入式Linux底层体系包括哪些内容?别急,举个例子就知道了。 1.电脑开机的时候,显示那些界面谁的?就是BIOS。它是干什么的?一些自检,然后从硬盘读取Windows,启动起来。同样的,这个BIOS就对应着嵌入式Linux里面的bootloader,这个bootloader需要从Flash中读取Linux内核,然后启动起来。
2、启动Windows的目的是什么?当然是为了上网聊天了。这些上网和聊天工具在哪儿呢?在C盘和D盘上。所以Windows首先要识别C盘和D盘。在Linux中我们叫它根文件系统。 3、Windows能识别C盘和D盘,那么它一定能读写硬盘,这里面涉及到的东西就叫驱动程序,当然不只是硬盘,还有网卡,USB等等。 嵌入式Linux能从Flash中读取并执行应用程序,那么一定有Flash的驱动程序,当然也不只是Flash。 嵌入式LINUX包含四大部分:引导加载程序,内核,驱动程序,根文件系统。 1、引导加载程序:就是一个稍微复杂的裸板程序。但是要看懂和写好这个裸板程序可不是件容易的事。Windows中那些好用的工具反而削弱了我们的编程能力。很多人玩嵌入式系统的时候,都会用ADS,KEIL,你能回答这些问题吗? 1、接通电源后,CPU从哪里获取指令去执行? 答:一般从Flash中。 2.但是Flash只能读不能直接写。如果我用全局变量,这些全局变量放在哪里呢? 答:全局变量应该在内存中。 3.谁把全局变量放在内存中? 答:长期用ADS、KEIL的朋友,能回答一下吗?这就需要“重定位”。
在ADS或者KEIL里,重定位的代码都是做这些工具的公司给你写好的,你看过吗? 4、内存那么大,我怎么知道要把“原来存放在Flash中的内容”读到内存的“哪个地址”呢? 答:这个地址是由“链接脚本”决定的,ADS里有scatter file,KEIL里也有类似的文件。但是你研究过吗? 5、你说重定位就是把程序从Flash复制到内存里,那么这个程序能读Flash吗? 答:能,必须能操作Flash。当然不只是这些,还有设置时钟,让系统跑得更快等等。 先问再回答这个问题,bootloader的裸板程序其实有3个重点: 1、对硬件的操作 2、对ARM系统处理器的理解 3、程序的基本概念:重定位、堆栈、代码段、数据段、BSS段等。 对于硬件的操作,需要看原理图、芯片手册,这个需要有一定的硬件知识。 你不需要会设计硬件,但至少能看懂;你不需要会看模拟电路,但需要会看数字电路。这个能力我在学校学的,《微机原理》和《数字电路》(我忘了书名)两本书就够了。但我怀疑你有没有耐心看完这两本书。不知道现在有没有更快的书,想学快点,就先放过这个吧,不懂就问Google或者发贴。另外芯片手册一定要看,别找中文的,看英文的就行。刚开始很痛苦,但你会发现,一旦熟悉了语法和词汇,看任何芯片手册都很容易。要看懂ARM系统处理器,就看杜春雷的书,里面讲到汇编指令、异常模式、MMU等,这三样东西你只需要懂。
3.编程的基本概念,当然是看编译原理了,可惜这种书是绝对看不懂的,除非你是超级天才,我劝你还是别看了。只要看我写的和第一个视频就行了,别担心,不花钱。跟着视频做硬件相关的实验,这些概念就清晰了。我还没找到第二套讲这些概念的书或者视频,就允许我瞎吹一通吧。对于bootloader,我学的时候是先看的,然后自己写程序把各种硬件的实验都做了,GPIO,时钟,SDRAM,UART,NAND,搞清楚了之后,再把u-boot拼起来就很容易理解了。综上所述,硬件原理图看懂,芯片手册看懂,需要自己找资料,其他的按照第一个视频的章节目录学就行了。 2.内核:想快速学习的先跳过内核学习,直接学怎么写驱动。 如果你想成为专家,必须对内核有很深入的理解。注意我说的是理解,并没有指望能写一个内核。你需要了解调度机制,内存管理机制,文件管理机制等等。我推荐两本书:1.通读,请读薄的那本(浮躁社会讲求速度,哈哈),2.选择性阅读,读你想了解的部分3.驱动:驱动由硬件本身的操作和驱动程序的框架两部分组成。再是硬件,还是需要看懂原理图看芯片手册,多练习。说到驱动框架,有一些书可以介绍,LDD3,也就是老外写的那本,里面介绍了很多概念,值得一看。但是它的作用仅限于介绍概念,我基本是上手前用它来熟悉一下概念,上手之后就扔了。
4. 驱动介绍最全的应该是宋宝华的,说实话我只看了目录,很多人说很好,所以在这里推荐一下,如果想对某个领域有很深的了解,绝对是超5星推荐,别指望能看完,1800多页,两卷本,我不清楚某一部分的时候,就会翻一翻,这本书200到300页就能讲到任何一部分,非常详细。而且带着一定的目标带领你去分析内核源码,以Linux 2.4为例,但是原理是一样的,也适用于其他版本的Linux。 4. 根文件系统: 大家有没有想过这两个问题: 1. Linux做的产品,有的是用来监控的,有的是做手机的,有的是做平板的。那么内核启动,挂载根文件系统之后,应该启动哪个应用程序呢? 答:内核不知道也不关心应该启动哪个用户程序,它只启动init应用程序,对应/sbin/init。显然这个应用程序需要读取配置文件,并根据配置文件启动用户程序(监控、人工界面、手写板界面等)。这道题提醒我们,文件系统的内容,比如/sbin/init,配置文件,都是有一些约定俗成的。 2、你有没有想过,你写的hello,world程序里用到的printf函数是谁实现的? 答:这个函数不是你实现的,而是库函数实现的,运行时要去找库。这道题提醒我们,文件系统里肯定有库。
这里是一个简单的自问自答,如果想进一步了解,可以看看busybox的init.c,就知道init进程是干什么的了。当然也可以看看建立根文件系统那一章。 先说一下我的学习经历。 1.上学的时候学的是物理电子学,其实课程并没有教怎么设计电路,只教了一些电子电路方面的知识。在实验室里自学了PCB设计,只设计了2层板,现在都忘得差不多了。但是看原理图和芯片手册的能力还是有的。 2.我读的是软件专业,对软件设计挺感兴趣的,但是只学了C语言和数据库,出于兴趣做了不少竞赛题,没有能力参加竞赛,但是C语言练得很好。 3.在实验室和在第一家公司,设计过一些简单的PCI卡,写过一些windows驱动。 4.在第二家公司用51单片机做车载电话,开始走上纯软件的道路。 5.开始感觉到单片机的力不从心,于是辞职闭门研究了半年Linux,从如何操作red hat开始。步骤是先看懂,然后写裸板程序操作硬件,再分析u-boot。同时看懂并熟悉LINUX框架。写裸板的时候建议加强对中断的理解,内核就是利用中断来完成各种功能的。 6.分析完u-boot之后开始做简单的驱动编程,这时候我的能力还很薄弱。 7.开始在中兴通讯工作,工作了2年,写各种驱动,解决各种问题(驱动问题,帮助定位应用问题),能力得到了锻炼。总结一下要看的书: 1.硬件书籍:微机原理,数字电路,大学教材。 毕业好多年了,忘记名字了。2.Linux书籍:,老外写的那本