当前位置:首页 » 操作系统 » linux嵌入式软件

linux嵌入式软件

发布时间: 2023-01-22 03:17:15

A. 学习linux嵌入式开发什么软件好

用Linux平台就行了,C语言一定要学好,指针一定要明确,像指针数组、数组指针、指针函数、函数指针数组、函数返回值是个指针,结构体指针(主要是链表)、文件操作指针(FILE *其实是typedef结构体的指针)等,要灵活运用typedef 定义类型、灵活运用结构体。
再学习Linux的系统编程,主要是文件操作,文件描述符fd,对文件的操作write,read,open.close等,然后学习进程fork();vfork();创建进程和管理父子进程,进程之间的通信无名管道、命名管道、消息队列、共享内存、信号量、套接字等;都掌握之后要学线程以及线程的互斥和同步,线程之间共享进程的资源,就要对资源进行合理的分配,例如信号量sem和线程互斥锁pthread_mutex,信号是用来检测信号的ISGNAL的,常见的信号例如ctrl+c,中断前台的进程和kill中断后台的进程,如果对网络感兴趣,可以学习下Linux的网络套接子Socket,实现多台主机之间进程的通信,例如QQ和IPMSG都是对网络套接字的操作,熟悉一下TCP、UDP协议和Tftp、HTTP的网络层的传输协议,个人觉得解析buff最费时间,可以自己做一下IPMSG,单用户和并发server,echo服务器。
感兴趣GUI的可以学习一下C++和Qt,Qt被nokia收购,nokia被微软收购,Qt支持很多的平台,很实用,C++主要是对类的操作,和C中的结构体相似,class 类名{};// 声明类class 类名:继承方式 基类{};//继承类类中包含私有成员、公有成员、受保护的成员,类是对事物共性的一种抽象,对象是共性的一种实体化,是类的一个实例,老师的共性是:教书,吃饭,睡觉等,可以抽象成一个类,个性是年龄、性别、名字等,是老师类的一个实例,C++还有很多的内容,Qt是用C++来写的,其中的窗口都是派生于QWidget的,具体的不多说了。
学完C++和Qt,有了面向对象的概念后,可以去学Java和android系统,做手机的应用软件和游戏开发,和Java 和C++类似,去掉c++中指针部分,完全脱离了内存的操作,完全的面向对象,android和Qt类似,具体内容不多说了。
说说底层的吧:
底层主要用到的是C语言和arm汇编主要是v4版本以后的汇编标准语言,首先清楚底层是怎么引导Linux系统的,嵌入式很大一部分使用缩减版的Linux内核主要是稳定版本的,千万不要去追求最新,最适合的才是最好的,前部分由汇编语言引导C语言,主要设置开发板软硬件的环境,主要是bootloader(vivi、uboot.bin),然后把设置好的param参数传给内核,内核调用这些参数去找相应的文件,进行相应的操作,然后就是Linux的根文件系统了,最后是软件的移植。
用到的软件:vmplayer (Linux redenterp版)、windows下的超级终端,LSJF24X0.exe(下载bootloader时使用,也可以用H-Jtag)、tftpd32.exe(做windows下的server用,用于u-boot网线下载)等工具。
以上是个人的体会,仅供参考!

B. 基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南(六)

作者 魏永明MiniGUI 提供的非 GUI/GDI 接口本文讲述了 MiniGUI 为应用程序提供的非 GUI/GDI 接口 这些接口能够帮助应用程序更好地和操作系统交互 扩展应用程序功能 并提高应用程序的可移植性 内容主要涉及到如下几个方面 MiniGUI Lite 和 select 系统调用 基于 UNIX Domain Socket 的进程间通讯 编写可移植性代码等 引言一般而言 GUI 系统的应用程序编程接口主要集中于窗口 消息队列 图形设备等相关方面 但因为 GUI 系统在处理系统事件时通常会提供自己的机制 而这些机制往往会和操作系统本身提供的机制不相兼容 比如 MiniGUI 提供了消息循环机制 而应用程序的结构一般是消息驱动的 也就是说 应用程序通过被动接收消息来工作 但很多情况下 应用程序需要主动监视某个系统事件 比如在 UNIX 操作系统中 可以通过 select 系统调用监听某个文件描述符上是否有可读数据 这样 如何将 MiniGUI 的消息队列机制和现有操作系统的其他机制融合在一起 就成了一个较为困难的问题 本文将讲述几种解决这一问题的方法 我们知道 MiniGUI Lite 采用 UNIX Domain Socket 实现客户程序和服务器程序之间的交互 应用程序也可以利用这一机制 完成自己的通讯任务――客户向服务器提交请求 而服务器完成对客户的请求处理并应答 一方面 在 MiniGUI Lite 的服务器程序中 你可以扩展这一机制 注册自己的请求处理函数 完成定制的请求/响应通讯任务 另一方面 MiniGUI Lite 当中也提供了若干用来创建和操作 UNIX Domain Socket 的函数 任何 MiniGUI Lite 的应用程序都可以建立 UNIX Domain Socket 并完成和其他 MiniGUI Lite 应用程序之间的数据交换 本文将举例讲述如何利用 MiniGUI Lite 提供的函数完成此类通讯任务 嵌入式 Linux 系统现在能够在许多不同架构的硬件平台上运行 MiniGUI 也能够在这些硬件平台上运行 但由于许多硬件平台具有和其他硬件平台不同的特性 比如说 常见的 CPU 是 Little Endian 的 而某些 CPU 则是 Big Endian 的 这要求我们在编写代码 尤其是文件 I/O 相关代码时 必须编写可移植代码 以便适合具有不同架构的平台 本文将描述 MiniGUI 为应用程序提供的可移植性函数及其用法 除了与上述内容相关的函数之外 MiniGUI 还提供了其他一些函数 本文最后部分将描述这些函数的用途和用法 包括配置文件读写以及定点数运算 MiniGUI Lite和 select 系统调用我们知道 在 MiniGUI Lite 之上运行的应用程序只有一个消息队列 应用程序在初始化之后 会建立一个消息循环 然后不停地从这个消息队列当中获得消息并处理 直到接收到 MSG_QUIT 消息为止 应用程序的窗口过程在处理消息时 要在处理完消息之后立即返回 以便有机会获得其他的消息并处理 现在 如果应用程序在处理某个消息时监听某个文件描述符而调用 select 系统调用 就有可能会出现问题――因为 select 系统调用可能会长时间阻塞 而由 MiniGUI Lite 服务器发送给客户的事件得不到及时处理 这样 消息驱动的方式和 select 系统调用就难于很好地融合 在 MiniGUI Threads 中 因为每个线程都有自己相应的消息队列 而系统消息队列是由单独运行的 desktop 线程管理的 所以任何一个应用程序建立的线程都可以长时间阻塞 从而可以调用类似 select 的系统调用 但在 MiniGUI Lite 当中 如果要监听某个应用程序自己的文件描述符事件 必须进行恰当的处理 以避免长时间阻塞 在 MiniGUI Lite 当中 有几种解决这一问题的办法 在调用 select 系统调用时 传递超时值 保证 select 系统调用不会长时间阻塞 设置定时器 定时器到期时 利用 select 系统调用查看被监听的文件描述符 如果没有相应的事件发生 则立即返回 否则进行读写操作 利用 MiniGUI Lite 提供的 RegisterListenFD 函数在系统中注册监听文件描述符 并在被监听的文件描述符上发生指定的事件时 向某个窗口发送 MSG_FDEVENT 消息 由于前两种解决方法比较简单 这里我们重点讲述的第三种解决办法 MiniGUI Lite 为应用程序提供了如下两个函数及一个宏 #define MAX_NR_LISTEN_FD /* Return TRUE if all OK and FALSE on error */BOOL GUIAPI RegisterListenFD (int fd int type HWND hwnd void* context);/* Return TRUE if all OK and FALSE on error */BOOL GUIAPI UnregisterListenFD (int fd);MAX_NR_LISTEN_FD 宏定义了系统能够监听的最多文件描述符数 默认定义为 RegisterListenFD 函数在系统当中注册一个需要监听的文件描述符 并指定监听的事件类型(type 参数 可取 POLLIN POLLOUT 或者 POLLERR) 接收 MSG_FDEVENT 消息的窗口句柄以及一个上下文信息 UnregisterListenFD 函数注销一个被注册的监听文件描述符 在应用程序使用RegisterListenFD 函数注册了被监听的文件描述符之后 当指定的事件发生在该文件描述符上时 系统会将 MSG_FDEVENT 消息发送到指定的窗口 应用程序可在窗口过程中接收该消息并处理 MiniGUI 中的 libvcongui 就利用了上述函数监听来自主控伪终端上的可读事件 如下面的程序段所示(vcongui/vcongui c) /* 注册主控伪终端伪监听文件描述符 */ RegisterListenFD (pConInfo >masterPty POLLIN hMainWnd ); /* 进入消息循环 */ while (!pConInfo >terminate && GetMessage (&Msg hMainWnd)) { DispatchMessage (&Msg); } /* 注销监听文件描述符 */ UnregisterListenFD (pConInfo >masterPty); /* 虚拟控制台的窗口过程 */static int VCOnGUIMainWinProc (HWND hWnd int message WPARAM wParam LPARAM lParam){ PCONINFO pConInfo; pConInfo = (PCONINFO)GetWindowAdditionalData (hWnd); switch (message) { /* 接收到 MSG_FDEVENT 消息 则处理主控伪终端上的输入数据 */ case MSG_FDEVENT: ReadMasterPty (pConInfo); break; } /* 调用默认窗口过程 */ if (pConInfo >DefWinProc) return (*pConInfo >DefWinProc)(hWnd message wParam lParam); else return DefaultMainWinProc (hWnd message wParam lParam);} 在 节当中 我们还可以看到RegisterListenFD 函数的使用 显然 通过这种简单的注册监听文件描述符的接口 MiniGUI Lite 程序能够方便地利用底层的消息机制完成对异步事件的处理 MiniGUI Lite 与进程间通讯 简单请求/应答处理我们知道 MiniGUI Lite 利用了 UNIX Domain Socket 实现服务器和客户程序之间的通讯 为了实现客户和服务器之间的简单方便的通讯 MiniGUI Lite 中定义了一种简单的请求/响应结构 客户程序通过指定的结构将请求发送到服务器 服务器处理请求并应答 在客户端 一个请求定义如下(include/gdi h) typedef struct tagREQUEST { int id; const void* data; size_t len_data;} REQUEST;typedef REQUEST* PREQUEST;其中 id 是用来标识请求类型的整型数 data 是发送给该请求的关联数据 len_data 则是数据的长度 客户在初始化 REQUEST 结构之后 就可以调用 cli_request 向服务器发送请求 并等待服务器的应答 该函数的原型如下 /* send a request to server and wait reply */int cli_request (PREQUEST request void* result int len_rslt); 服务器程序(即 mginit)会在自己的消息循环当中获得来自客户的请求 并进行处理 最终会将处理结果发送给客户 在上述这种简单的客户/服务器通讯中 客户和服务器必须就每个请求类型达成一致 也就是说 客户和服务器必须了解每种类型请求的数据含义并进行恰当的处理 MiniGUI Lite 利用上述这种简单的通讯方法 实现了若干系统级的通讯任务 鼠标光标的管理 鼠标光标是一个全局资源 当客户需要创建或者销毁鼠标光标 改变鼠标光标的形状 位置 显示或者隐藏鼠标时 就发送请求到服务器 服务器程序完成相应任务并将结果发送给客户 层及活动客户管理 当客户查询层的信息 新建层 加入某个已有层 或者设置层中的活动客户时 通过该接口发送请求到服务器 其他一些系统级的任务 比如在新的 GDI 接口中 服务器程序统一管理显示卡中可能用来建立内存 DC 的显示内存 当客户要申请建立在显示内存中的内存 DC 时 就会发送请求到服务器 为了让应用程序也能够通过这种简单的方式实现客户和服务器之间的通讯 服务器程序可以注册一些定制的请求处理函数 然后客户就可以向服务器发送这些请求 为此 MiniGUI Lite 提供了如下接口 #define MAX_SYS_REQID x #define MAX_REQID x /* * Register user defined request handlers for server * Note that user defined request id should larger lishixin/Article/program/Oracle/201311/17973

C. 学习嵌入式Linux怎么应用开发

提供一下几种方案x0dx0ax0dx0a一、还按照《嵌入死linux应用开发完全手册》(韦东山)的内容来,但是嵌入式linux的开发环境自己搭建。当时我是按照《鸟哥的私房菜-基础篇》和《鸟哥的私房菜-服务器篇》两篇,整出一套开发平台,CentOS5.3 + samba/vsftpd + gcc / linux-gcc 。 window平台上的工具sourceinsight、secureCRT。 注意:我使用了四个月学会linux操作。不知道你是否会先学这两本书,再学习韦东山老师的嵌入式呢。学完之后看似学习了很多,出来外面之后,我又去在windows平台开发,而且现在用C#。_。现在看什么嵌入式系统都非常快,很容易理解架构,如何实现。可惜自己太年轻,没有资本和人脉,不然可以实现很多有意思的东西。现在正在尝试创业。x0dx0ax0dx0a二、寻找开发板,而不是书籍作为实验的途径。书籍只是辅助,辅助你实现某种功能。可以集中linux书籍、嵌入式开发书籍、单片机开发、编程语言。宋宝华的嵌入式书籍。开发板当时用的是飞凌的,由国嵌负责技术讲解和培训。讲了不少有用的东西。现在网上的开发板多,可以淘,但是不用太贵,作用不大。找前卫的技术开发,中国看似不行。前卫老师都没搞出什么东西,我们在基本是0基础的前提下,很难实现比较前卫的技术。打好基础,看似是唯一的选择。x0dx0ax0dx0a三、单独找台PC机,直接安装ubuntu11,买本ubuntu相关的书,他会交你怎样安装使用工具的。其实和第一种解决方式是一样的,书是别人在五(六)年前写的,不符合摩尔定理。所以没办法,我们在嵌入式方面的教育还是欠缺啊,出的书都少,记那么基本,还全是个人。没有什么教育机构。x0dx0ax0dx0a希望以上对你有用。

D. 典型嵌入式linux软件部分由哪些模块组成他们的功能及相互联系 Bootloader分为哪两阶段分

典型的嵌入式系统,软件部分从下到上,分别是boot,kernel,rootfs,fsimg和上层应用。
起到的作用分别是,引导内核,启动内核,挂载根文件系统,挂载实际文件系统,开启上层应用主循环。
你问的这些问题,每一点都可以单独拿出来,长篇大论的讲很久了。建议去网上先看相关的资料。贪多求快是不好的,一个知识点一个知识点的掌握。

E. 嵌入式linux和linux有什么不同.linux的作用是什么

Linux作为开源免费操作系统,以其作为系统的应用可以较方便的进行系统功能的裁剪和跨体系结构移植。

在不同的目标体系结构下(x86,ARM,PowerPC etc.),由于汇编指令集的不同,同一段代码利用不同的编译器和库文件生成的可执行代码是不同的。不同体系的Linux其开发工具是不同的。

嵌入式linux属于高度裁剪过的Linux,他将桌面Linux所具有的大部分应用功能(如GUI 工具,计算器,电子邮件 etc.)和部分系统功能省略,但集成了开发者希望嵌入式产品所具有的特殊应用功能(比如 一款以Linux为系统的触摸式海事导航仪可以根据功能需要去除不需要的功能块,但加入GPS定位,航速航向计算,航线规划,触摸检测和对应功能实现等功能)。

嵌入式系统往往是指系统的资源(如DRAM/FLASH ROM,功耗,工作频率 etc.)有较大限制且系统的工作环境相对多变和恶劣(如温湿度变化大,酸碱度腐蚀,外部撞击和振动,外部电磁干扰,静电导致的高压损坏电路 etc.)。这也就需要开发人员更多的发现和假想可能的突发情况并采取相应预防措施。大部分嵌入式系统对响应的时间限制和正确性也有极高的要求。

F. Linux和嵌入式Linux有什么区别

Linux是一种自由和开放源码的类Unix操作系统,存在着许多不同的Linux版本,但它们都使用了Linux内核。Linux可安装在各种计算机硬件设备中,比如手机、平板电脑、路由器、视频游戏控制台、台式计算机、大型机和超级计算机。Linux是一个领先的操作系统,世界上运算最快的10台超级计算机运行的都是Linux操作系统。嵌入式Linux系统就是利用Linux其自身的许多特点,把它应用到嵌入式系统里。随着微处理器的产生,价格低廉、结构小巧的CPU和外设连接提供了稳定可靠的硬件架构,那么限制嵌入式系统发展的瓶颈就突出表现在了软件方面。

G. 嵌入式软件开发(Linux/单片机/DLC/DSP…)什么意思

嵌入式软件开发就是撸代码,不过不是写一般的电脑软件,是给操作系统(linux、ucos、win ce嵌入式系统)撸、是给单片机(8051、stm32等等)撸。DLC不清楚(不好意思孤陋寡闻了)PLC倒是用过,DSP的全称为Digital Signal Process,即数字信号处理技术,DSP芯片即指能够实现数字信号处理技术的芯片。也是编程撸代码。个人见解
------萌萌的文艺青年

H. “干货”嵌入式Linux系统移植的四大步骤(上)


在学习系统移植的相关知识,在学习和调试过程中,发现了很多问题,也解决了很多问题,但总是对于我们的开发结果有一种莫名其妙的感觉,纠其原因,主要对于我们的开发环境没有一个深刻的认识,有时候几个简单的命令就可以完成非常复杂的功能,可是我们有没有想过,为什么会有这样的效果?


如果没有去追问,只是机械地完成,并且看到实验效果,这样做其实并没有真正的掌握系统移植的本质。


在做每一个步骤的时候, 首先问问自己,为什么要这样做,然后再问问自己正在做什么? 搞明白这几个问题,我觉得就差不多了,以后不管更换什么平台,什么芯片,什么开发环境,你都不会迷糊,很快就会上手。对于嵌入式的学习方法,我个人方法就是:从宏观上把握(解决为什么的问题),微观上研究(解决正在做什么的问题),下面以自己学习的arm-cortex_a8开发板为目标,介绍下自己的学习方法和经验。


嵌入式Linux系统移植主要由四大部分组成:


一、搭建交叉开发环境
二、bootloader的选择和移植
三、kernel的配置、编译、和移植
四、根文件系统的制作


第一部分:搭建交叉开发环境


先介绍第一分部的内容:搭建交叉开发环境,首先必须得思考两个问题,什么是交叉环境? 为什么需要搭建交叉环境?


先回答第一个问题,在嵌入式开发中,交叉开发是很重要的一个概念,开发的第一个环节就是搭建环境,第一步不能完成,后面的步骤从无谈起,这里所说的交叉开发环境主要指的是:在开发主机上(通常是我的pc机)开发出能够在目标机(通常是我们的开发板)上运行的程序。嵌入式比较特殊的是不能在目标机上开发程序(狭义上来说),因为对于一个原始的开发板,在没有任何程序的情况下它根本都跑不起来,为了让它能够跑起来,我们还必须要借助pc机进行烧录程序等相关工作,开发板才能跑起来,这里的pc机就是我们说的开发主机,想想如果没有开发主机,我们的目标机基本上就是无法开发,这也就是电子行业的一句名言:搞电子,说白了,就是玩电脑!


然后回答第二个问题,为什么需要交叉开发环境?主要原因有以下几点:


原因 1: 嵌入式系统的硬件资源有很多限制,比如cpu主频相对较低,内存容量较小等,想想让几百MHZ主频的MCU去编译一个Linux kernel会让我们等的不耐烦,相对来说,pc机的速度更快,硬件资源更加丰富,因此利用pc机进行开发会提高开发效率。


原因2: 嵌入式系统MCU体系结构和指令集不同,因此需要安装交叉编译工具进行编译,这样编译的目标程序才能够在相应的平台上比如:ARM、MIPS、 POWEPC上正常运行。


交叉开发环境的硬件组成主要由以下几大部分


1.开发主机
2.目标机(开发板)
3.二者的链接介质,常用的主要有3种方式:(1)串口线 (2)USB线 (3)网线


对应的硬件介质,还必须要有相应的软件“介质”支持:


1.对于串口,通常用的有串口调试助手,putty工具等,工具很多,功能都差不多,会用一两款就可以;


2.对于USB线,当然必须要有USB的驱动才可以,一般芯片公司会提供,比如对于三星的芯片,USB下载主要由DNW软件来完成;


3.对于网线,则必须要有网络协议支持才可以, 常用的服务主要两个


第一:tftp服务:

主要用于实现文件的下载,比如开发调试的过程中,主要用tftp把要测试的bootloader、kernel和文件系统直接下载到内存中运行,而不需要预先烧录到Flash芯片中,一方面,在测试的过程中,往往需要频繁的下载,如果每次把这些要测试的文件都烧录到Flash中然后再运行也可以,但是缺点是:过程比较麻烦,而且Flash的擦写次数是有限的;另外一方面:测试的目的就是把这些目标文件加载到内存中直接运行就可以了,而tftp就刚好能够实现这样的功能,因此,更没有必要把这些文件都烧录到Flash中去。


第二: nfs服务:

主要用于实现网络文件的挂载,实际上是实现网络文件的共享,在开发的过程中,通常在系统移植的最后一步会制作文件系统,那么这是可以把制作好的文件系统放置在我们开发主机PC的相应位置,开发板通过nfs服务进行挂载,从而测试我们制作的文件系统是否正确,在整个过程中并不需要把文件系统烧录到Flash中去,而且挂载是自动进行挂载的,bootload启动后,kernel运行起来后会根据我们设置的启动参数进行自动挂载,因此,对于开发测试来讲,这种方式非常的方便,能够提高开发效率。


另外,还有一个名字叫 samba 的服务也比较重要,主要用于文件的共享,这里说的共享和nfs的文件共享不是同一个概念,nfs的共享是实现网络文件的共享,而samba实现的是开发主机上 Windows主机和Linux虚拟机之间的文件共享,是一种跨平台的文件共享 ,方便的实现文件的传输。


以上这几种开发的工具在嵌入式开发中是必备的工具,对于嵌入式开发的效率提高做出了伟大的贡献,因此,要对这几个工具熟练使用,这样你的开发效率会提高很多。等测试完成以后,就会把相应的目标文件烧录到Flash中去,也就是等发布产品的时候才做的事情,因此对于开发人员来说,所有的工作永远是测试。


通过前面的工作,我们已经准备好了交叉开发环境的硬件部分和一部分软件,最后还缺少交叉编译器,读者可能会有疑问,为什么要用交叉编译器?前面已经讲过,交叉开发环境必然会用到交叉编译工具,通俗地讲就是在一种平台上编译出能运行在体系结构不同的另一种平台上的程序,开发主机PC平台(X86 CPU)上编译出能运行在以ARM为内核的CPU平台上的程序,编译得到的程序在X86 CPU平台上是不能运行的,必须放到ARM CPU平台上才能运行,虽然两个平台用的都是Linux系统。相对于交叉编译,平常做的编译叫本地编译,也就是在当前平台编译,编译得到的程序也是在本地执行。用来编译这种跨平台程序的编译器就叫交叉编译器,相对来说,用来做本地编译的工具就叫本地编译器。所以要生成在目标机上运行的程序,必须要用交叉编译工具链来完成。

这里又有一个问题,不就是一个交叉编译工具吗?为什么又叫交叉工具链呢?原因很简单,程序不能光编译一下就可以运行,还得进行汇编和链接等过程,同时还需要进行调试,对于一个很大工程,还需要进行工程管理等等,所以,这里 说的交叉编译工具是一个由 编译器、连接器和解释器 组成的综合开发环境,交叉编译工具链主要由binutils(主要包括汇编程序as和链接程序ld)、gcc(为GNU系统提供C编译器)和glibc(一些基本的C函数和其他函数的定义) 3个部分组成。有时为了减小libc库的大小,也可以用别的 c 库来代替 glibc,例如 uClibc、dietlibc 和 newlib。

那么,如何得到一个交叉工具链呢?是从网上下载一个“程序”然后安装就可以使用了吗?回答这个问题之前先思考这样一个问题,我们的交叉工具链顾名思义就是在PC机上编译出能够在我们目标开发平台比如ARM上运行的程序,这里就又有一个问题了,我们的ARM处理器型号非常多,难道有专门针对我们某一款的交叉工具链吗?若果有的话,可以想一想,这么多处理器平台,每个平台专门定制一个交叉工具链放在网络上,然后供大家去下载,想想可能需要找很久才能找到适合你的编译器,显然这种做法不太合理,且浪费资源!因此,要得到一个交叉工具链,就像我们移植一个Linux内核一样,我们只关心我们需要的东西,编译我们需要的东西在我们的平台上运行,不需要的东西我们不选择不编译,所以,交叉工具链的制作方法和系统移植有着很多相似的地方,也就是说,交叉开发工具是一个支持很多平台的工具集的集合(类似于Linux源码),然后我们只需从这些工具集中找出跟我们平台相关的工具就行了,那么如何才能找到跟我们的平台相关的工具,这就是涉及到一个如何制作交叉工具链的问题了。


通常构建交叉工具链有如下三种方法:


方法一 : 分步编译和安装交叉编译工具链所需要的库和源代码,最终生成交叉编译工具链。该方法相对比较困难,适合想深入学习构建交叉工具链的读者。如果只是想使用交叉工具链,建议使用下列的方法二构建交叉工具链。


方法二: 通过Crosstool-ng脚本工具来实现一次编译,生成交叉编译工具链,该方法相对于方法一要简单许多,并且出错的机会也非常少,建议大多数情况下使用该方法构建交叉编译工具链。


方法三 : 直接通过网上下载已经制作好的交叉编译工具链。该方法的优点不用多说,当然是简单省事,但与此同时该方法有一定的弊端就是局限性太大,因为毕竟是别人构建好的,也就是固定的,没有灵活性,所以构建所用的库以及编译器的版本也许并不适合你要编译的程序,同时也许会在使用时出现许多莫名其妙的错误,建议读者慎用此方法。

crosstool-ng是一个脚本工具,可以制作出适合不同平台的交叉编译工具链,在进行制作之前要安装一下软件:
$ sudo apt-get install g++ libncurses5-dev bison flex texinfo automake libtool patch gcj cvs cvsd gawk
crosstool脚本工具可以在http://ymorin.is-a-geek.org/projects/crosstool下载到本地,然后解压,接下来就是进行安装配置了,这个配置优点类似内核的配置。主要的过程有以下几点:
1. 设定源码包路径和交叉编译器的安装路径
2. 修改交叉编译器针对的构架

3. 增加编译时的并行进程数,以增加运行效率,加快编译,因为这个编译会比较慢。
4. 关闭JAVA编译器 ,减少编译时间
5. 编译
6. 添加环境变量
7. 刷新环境变量。
8. 测试交叉工具链

到此,嵌入式Linux系统移植四大部分的第一部分工作全部完成,接下来可以进行后续的开发了。



第二部分:bootloader的选择和移植


01 Boot Loader 概念


就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境,他就是所谓的引导加载程序(Boot Loader)。


02 为什么系统移植之前要先移植BootLoader?


BootLoader的任务是引导操作系统,所谓引导操作系统,就是启动内核,让内核运行就是把内核加载到内存RAM中去运行,那先问两个问题:第一个问题,是谁把内核搬到内存中去运行?第二个问题:我们说的内存是SDRAM,大家都知道,这种内存和SRAM不同,最大的不同就是SRAM只要系统上电就可以运行,而SDRAM需要软件进行初始化才能运行,那么在把内核搬运到内存运行之前必须要先初始化内存吧,那么内存是由谁来初始化的呢?其实这两件事情都是由bootloader来干的,目的是为内核的运行准备好软硬件环境,没有bootloadr我们的系统当然不能跑起来。

03 bootloader的分类


首先更正一个错误的说法,很多人说bootloader就是U-boot,这种说法是错误的,确切来说是u-boot是bootloader的一种。也就是说bootloader具有很多种类,


由上图可以看出,不同的bootloader具有不同的使用范围,其中最令人瞩目的就是有一个叫U-Boot的bootloader,是一个通用的引导程序,而且同时支持X86、ARM和PowerPC等多种处理器架构。U-Boot,全称 Universal Boot Loader,是遵循GPL条款的开放源码项目,是由德国DENX小组开发的用于多种嵌入式CPU的bootloader程序,对于Linux的开发,德国的u-boot做出了巨大的贡献,而且是开源的。

u-boot具有以下特点:

① 开放源码;
② 支持多种嵌入式操作系统内核,如Linux、NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS;
③ 支持多个处理器系列,如PowerPC、ARM、x86、MIPS、XScale;
④ 较高的可靠性和稳定性;
⑤ 高度灵活的功能设置,适合U-Boot调试、操作系统不同引导要求、产品发布等;
⑥ 丰富的设备驱动源码,如串口、以太网、SDRAM、FLASH、LCD、NVRAM、EEPROM、RTC、键盘等;
⑦ 较为丰富的开发调试文档与强大的网络技术支持;
其实,把u-boot可以理解为是一个小型的操作系统。

04 u-boot的目录结构


* board 目标板相关文件,主要包含SDRAM、FLASH驱动;
* common 独立于处理器体系结构的通用代码,如内存大小探测与故障检测;
* cpu 与处理器相关的文件。如mpc8xx子目录下含串口、网口、LCD驱动及中断初始化等文件;
* driver 通用设备驱动,如CFI FLASH驱动(目前对INTEL FLASH支持较好)
* doc U-Boot的说明文档;
* examples可在U-Boot下运行的示例程序;如hello_world.c,timer.c;
* include U-Boot头文件;尤其configs子目录下与目标板相关的配置头文件是移植过程中经常要修改的文件;
* lib_xxx 处理器体系相关的文件,如lib_ppc, lib_arm目录分别包含与PowerPC、ARM体系结构相关的文件;
* net 与网络功能相关的文件目录,如bootp,nfs,tftp;
* post 上电自检文件目录。尚有待于进一步完善;
* rtc RTC驱动程序;
* tools 用于创建U-Boot S-RECORD和BIN镜像文件的工具;

05 u-boot的工作模式


U-Boot的工作模式有 启动加载模式和下载模式 。启动加载模式是Bootloader的正常工作模式,嵌入式产品发布时,Bootloader必须工作在这种模式下,Bootloader将嵌入式操作系统从FLASH中加载到SDRAM中运行,整个过程是自动的。 下载模式 就是Bootloader通过某些通信手段将内核映像或根文件系统映像等从PC机中下载到目标板的SDRAM中运行,用户可以利用Bootloader提供的一些令接口来完成自己想要的操作,这种模式主要用于测试和开发。

06 u-boot的启动过程


大多数BootLoader都分为stage1和stage2两大部分,U-boot也不例外。依赖于cpu体系结构的代码(如设备初始化代码等)通常都放在stage1且可以用汇编语言来实现,而stage2则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。


1、 stage1(start.s代码结构)
U-boot的stage1代码通常放在start.s文件中,它用汇编语言写成,其主要代码部分如下:
(1) 定义入口。由于一个可执行的image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在rom(Flash)的0x0地址,因此,必须通知编译器以使其知道这个入口,该工作可通过修改连接器脚本来完成。
(2)设置异常向量(exception vector)。
(3)设置CPU的速度、时钟频率及中断控制寄存器。
(4)初始化内存控制器 。
(5)将rom中的程序复制到ram中。
(6)初始化堆栈 。
(7)转到ram中执行,该工作可使用指令ldrpc来完成。


2、 stage2(C语言代码部分)

lib_arm/board.c中的start armboot是C语言开始的函数,也是整个启动代码中C语言的主函数,同时还是整个u-boot(armboot)的主函数,该函数主要完成如下操作:
(1)调用一系列的初始化函数。
(2)初始化flash设备。
(3)初始化系统内存分配函数。
(4)如果目标系统拥有nand设备,则初始化nand设备。
(5)如果目标系统有显示设备,则初始化该类设备。
(6)初始化相关网络设备,填写ip,c地址等。
(7)进入命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。

07 基于cortex-a8的s5pc100bootloader启动过程分析


s5pc100支持两种启动方式,分别为USB启动方式和NandFlash启动方式:


1. S5PC100 USB启动过程

[1] A8 reset, 执行iROM中的程序
[2] iROM中的程序根据S5PC100的配置管脚(SW1开关4,拨到4对面),判断从哪里启动(USB)
[3] iROM中的程序会初始化USB,然后等待PC机下载程序
[4] 利用DNW程序,从PC机下载SDRAM的初始化程序到iRAM中运行,初始化SDRAM
[5] SDRAM初始化完毕,iROM中的程序继续接管A8, 然后等待PC下载程序(BootLoader)
[6] PC利用DNW下载BootLoader到SDRAM
[7] 在SDRAM中运行BootLoader

2. S5PC100 Nandflash启动过程

[1] A8 reset, 执行IROM中的程序
[2] iROM中的程序根据S5PC100的配置管脚(SW1开关4,拨到靠4那边),判断从哪里启动(Nandflash)
[3] iROM中的程序驱动Nandflash
[4] iROM中的程序会拷贝Nandflash前16k到iRAM
[5] 前16k的程序(BootLoader前半部分)初始化SDRAM,然后拷贝完整的BootLoader到SDRAM并运行
[6] BootLoader拷贝内核到SDRAM,并运行它
[7] 内核运行起来后,挂载rootfs,并且运行系统初始化脚本

08 u-boot移植(基于cortex_a8的s5pc100为例)


1.建立自己的平台

(1).下载源码包2010.03版本,比较稳定
(2).解压后添加我们自己的平台信息,以smdkc100为参考版,移植自己s5pc100的开发板
(3).修改相应目录的文件名,和相应目录的Makefile,指定交叉工具链。
(4).编译
(5).针对我们的平台进行相应的移植,主要包括修改SDRAM的运行地址,从0x20000000
(6).“开关”相应的宏定义
(7).添加Nand和网卡的驱动代码
(8).优化go命令
(9).重新编译 make distclean(彻底删除中间文件和配置文件) make s5pc100_config(配置我们的开发板) make(编译出我们的u-boot.bin镜像文件)
(10).设置环境变量,即启动参数,把编译好的u-boot下载到内存中运行,过程如下:
1. 配置开发板网络
ip地址配置:
$setenv ipaddr 192.168.0.6 配置ip地址到内存的环境变量
$saveenv 保存环境变量的值到nandflash的参数区

网络测试:
在开发开发板上ping虚拟机:
$ ping 192.168.0.157(虚拟机的ip地址)

如果网络测试失败,从下面几个方面检查网络:
1. 网线连接好
2. 开发板和虚拟机的ip地址是否配置在同一个网段
3. 虚拟机网络一定要采用桥接(VM--Setting-->option)
4. 连接开发板时,虚拟机需要设置成 静态ip地址

2. 在开发板上,配置tftp服务器(虚拟机)的ip地址
$setenv serverip 192.168.0.157(虚拟机的ip地址)
$saveenv
3. 拷贝u-boot.bin到/tftpboot(虚拟机上的目录)
4. 通过tftp下载u-boot.bin到开发板内存
$ tftp 20008000(内存地址即可) u-boot.bin(要下载的文件名)

如果上面的命令无法正常下载:
1. serverip配置是否正确
2. tftp服务启动失败,重启tftp服务
#sudo service tftpd-hpa restart

5. 烧写u-boot.bin到nandflash的0地址
$nand erase 0(起始地址) 40000(大小) 擦出nandflash 0 - 256k的区域
$nand write 20008000((缓存u-boot.bin的内存地址) 0(nandflash上u-boot的位置) 40000(烧写大小)

6. 切换开发板的启动方式到nandflash
1. 关闭开发板
2. 把SW1的开关4拨到4的那边
3. 启动开发板,它就从nandflash启动

I. linux系统与嵌入式linux有什么区别和关系

二者是同根生哦,联系:都属于linux,都必须符合通用的语法和结构;区别:前者属于大的通用的,后者属于适合嵌入式系统应用的,前者包含后者。比喻:前者相当于西瓜,后者相当于无籽西瓜

J. Flutter开发——Linux嵌入式应用开发

上文中 介绍了Linux平台下Flutter环境搭建和桌面应用开发,现在需要更深入了解如何将该应用运行在Linux系统的嵌入式设备上。

安装及示例

在 ~/.bashrc 中配置 export PATH=$PATH:/opt/flutter-elinux/bin

打开weston虚拟机,此时发现 flutter-elinux devices 连接设备变成两个,如下图

即可编译及运行基于wayland显示后端的demo

避坑

热点内容
服务器网卡硬件型号怎么看 发布:2024-05-19 18:36:41 浏览:665
修改pve服务器ip 发布:2024-05-19 18:31:52 浏览:468
微信密码忘记了如何取出里面的钱 发布:2024-05-19 18:27:35 浏览:329
vs2005反编译 发布:2024-05-19 18:26:34 浏览:363
ug启动语言脚本 发布:2024-05-19 18:25:57 浏览:874
缓存服务器技术 发布:2024-05-19 18:25:56 浏览:885
androidlistview横向 发布:2024-05-19 18:21:02 浏览:704
多看ftp 发布:2024-05-19 18:11:31 浏览:543
给定一个算法 发布:2024-05-19 17:50:08 浏览:864
恋爱生物种离线缓存 发布:2024-05-19 17:49:15 浏览:579