当前位置:首页 > 嵌入式 > 嵌入式硬件
[导读]uclinux表示micro-control linux.即“微控制器领域中的Linux系统”,是Lineo公司的主打产品,同时也是开放源码的嵌入式Linux的典范之作。uCLinux主要是针对目标

uclinux表示micro-control linux.即“微控制器领域中的Linux系统”,是Lineo公司的主打产品,同时也是开放源码的嵌入式Linux的典范之作。uCLinux主要是针对目标处理器没有存储管理单元MMU(Memory Management Unit)的嵌入式系统而设计的。它已经被成功地移植到了很多平台上。由于没有MMU,其多任务的实现需要一定技巧。

uClinux是嵌入式Linux领域非常重要的分支,已成功应用于路由器、机顶盒、PDA等领域,与标准Linux在内存管理方面有着本质的区别。

Uclinux的配置和裁减也是利用的华恒科技提供的源码包(用于hhbf531学习板)。我们使用的开发板信息如下:

CPU:BF533

FLASH:S29AL004D-512KB

SDRAM:HY57V281620-16MB

这里我不敢说“uclinux的移植”,而只是以“配置与裁减”代之,是因为我觉得自己的工作真的谈不上什么移植。现成的源码包,所有的底层驱动都已经完成,我们所要做的只是选择自己需要的驱动、配置一下内核、做一些裁减工作而已。每每听到其他人提到“最近又完成了&TImes;&TImes;&TImes;平台的linux移植”,我都会有点担心:国内有多少工程师能真正从最初始的工作开始,完成一个平台的系统移植——应该很少吧。

下面,我分以下步骤简单介绍一下我的配置过程。

一,配置并在RAM中运行内核(不带根文件系统):

由于我们的flash空间有限,在没有裁减之前,就算不带根文件系统,也无法烧写到flash内保存;所以先尝试下载到RAM中运行。另外,我们目前的开发板上没有网络功能,只能通过串口下载,所以在这里配置内核的过程中,做一些简单裁减,以便节约下载时间。

解压源码包后,进入uclinux目录:

#cd uClinux-dist

设定交叉工具链:

#PATH=”/usr/local/bin/gcc-bfin-3.4-uclinux/bin/:$PATH”

进入配置:

#make menuconfig

运行后,进入“MainMenu”配置页,可以在此选择Vender/Product和Kernel/Library/Defaults等内容。根据我们使用的平台,我们选择:Vender-AnalogDevices,Product-HHBF533(或者HHBF531),Libc-uClibc;如果要配置内核和应用程序还要分别选中“Customize Kernel SetTIngs”、“Customize Vender/User Settings”。退出保存后,将依次进入配置内核和配置应用程序页。

如果想单独配置内核,可以进入目录linux-2.6.x/内运行“make menuconfig”。配置应用程序在这个源码包里好像没有单独的config选项。这些关于内核源码包结构的基本知识,需要大家提前了解。

下面,我们来配置内核。

配置一个可以在我们的SDRAM中运行的内核很简单,因为底层工作都已经完成。我们只需要配置一下处理器相关内容即可。处理器选项位于内核配置页的“Blackfin Processer Options”。进入该配置页,进行如下配置:

CPU - BF533

System type - BF533-HHBF

Board Customizations - 根据你的开发板时钟、SDRAM信息配置,其他不用修改。

Clock Settings - 取消“Re-programClocks while Kernel boots”,默认为u-boot的时钟配置。

其他选项不用修改,各项配置功能介绍见文档《附.Linux 2.6.19.x内核编译配置选项简介》。

以上配置正确后,下载到你的开发板上,应该就可以运行了。但通过串口下载速度太慢,我们先去掉一些不需要的驱动。由于我们没有网络功能,所以把网络及其驱动全部取消,可以裁减150KB左右的空间;我们也不需要音视频功能,所以把音视频驱动也取消,又可以减小很大空间。如此配置后,我们可以尝试下载到SDRAM中运行了。

现在,我们还不想裁减根文件系统,所以,我们想得到一个不带根文件系统的压缩内核镜像。由于华恒提供的源码包,编译后不能得到压缩的不带根文件系统的镜像,所以我们要通过修改Makefile得到我们需要的编译结果。

需要修改的Makefile位于uClinux-dist目录下,打开该Makefile,在“.PHONY:linux”项的”ln –f $(LINUXDIR)/vmlinux $(LINUXDIR)/linux;”语句后,添加以下内容。

 


这样在uClinux-dist目录下执行“make linux”就可以生成压缩的不带根文件系统的内核镜像了,该镜像文件为uImage.bin,位于linux-2.6.x目录内。现在,可以将得到的内核下载到SDRAM中运行了。因为是压缩内核,所以运行时要使用u-boot的bootm命令。至于u-boot命令的使用方法,自行学习。

Makefile也是编译内核的基础知识,需要大家逐步掌握。

这样,该步的工作就可以告一段落了。

下载到SDRAM中,如果解压后无法运行,先检查一下上述配置操作是否有误。如果确定无误,就需要分析内核的执行过程,仔细分析问题了。接下来简单介绍一下内核执行流程。

二,内核执行流程:

承接上篇《u-boot引导uclinux过程分析》,介绍内核启动流程。

A,内核vmlinux入口

u-boot执行“(*appl)(cmdline);”语句后,控制权就移交给linux内核,appl变量指向的地址就是linux内核的首地址。

Linux内核执行的第一个文件是/linux-2.6.x/arch/blackfin/mach-bf533/head.S。经过一系列的初始化,跳转到start_kernel()函数,即进入linux系统初始化阶段。

B, Linux系统初始化

Start_kernel()函数位于文件/linux-2.6.x/init/main.c中,是linux内核通用的初始化函数。无论对于什么体系结构的linux,都要执行这个函数。

 


Start_kernel()函数负责初始化内核各子系统,最后调用rest_init(),启动一个叫作init的内核线程,继续初始化。[!--empirenews.page--]

 


起始内核线程init的任务依然是初始化,只不过是一种更高层次的初始化。

 


 

函数do_basic_setup()是init进程中最重要的函数,与嵌入式系统关系最紧密的是其中的do_initcalls()函数,该函数与设备驱动程序加载有关。

函数prepare_namespace()函数主要目的是准备好系统的命名空间,其中最重要的函数是mount_root(),其功能是挂载根文件系统。

四个run_init_process()函数查找init进程程序并尝试执行。如果没有找到一个可以执行的init程序,则报告错误“Noinit found”。

C,初始化设备驱动

参考B中的do_basic_setup()函数。

D,挂接根文件系统

参考B中的prepare_namespace()函数。

E, 启动用户空间init进程

当内核挂载了根文件系统后,内核的启动工作就全部结束了,但系统还不能正常启动起来,因为还需要通过根文件系统上的init程序来完成一下最后的设置工作。这个init程序一般在/sbin、/etc或/bin目录下。

三,裁减内核(不带根文件系统)并烧写到flash中:

该步承接上步的工作。由于上步已经做了一定的裁减,该步只需要在此基础上进一步裁减即可。该步工作相对叫简单,只需要将不需要的驱动选项取消即可,当然要注意保证内核的依赖关系。

我们的flash容量为512KB,u-boot占有64KB空间,剩下的只有448KB。另外,根文件系统大约还需要100KB空间,所以内核大小要控制在350KB以内。我们先尝试将不需要的驱动和选项全部取消,让内核运行起来。

在“二,配置并在RAM中运行内核(不带根文件系统)”的基础上,我们进一步删除的驱动包括:

l 取消“Loadble module support”支持

l 取消“Block layer”支持

l 取消“Bus options”所有支持

l 取消“Power management options”支持

l 取消“CPU Frequency scaling”支持

l 取消“Profiling Support”支持

l 取消“Security options”支持

l 取消“Cryptographic options”支持

l 取消除了串口和MTD以外的所有硬件驱动支持

l 取消内部RTC驱动

l 取消对ELF格式文件支持

取消以上选项后,内核可以控制在350KB以内了。所以,不需进一步修改Makefile来裁减内核了。这样就可以下载并烧写到flash内保存了。

四,配置应用程序和裁减根文件系统:

根文件系统挂载到内核有两种基本方式:独立于内核存放通过MTD分区识别并挂载和链接到内核数据段通过ramdisk挂载(两种方式都是我自己概括的,可能描述上有些不尽合理,仅供参考)。不论那种方式,都需要MTD驱动支持,所以内核要支持MTD并配置正确,保持华恒源码包原MTD配置即可。

HHBF5XX 的Linux BSP 使用ext2 格式的ramdisk 作为根文件系统,直接链接到内核数据段,所以这里介绍这种方式。另一种方式这里不作介绍,其相关资料更丰富。

与根文件系统(ramfs)相关的链接内容如下,位于文件/linux-2.6.x/arch/Blackfin/Kernel/vmlinux.lds.S中。

 


内核通过__initramfs_start和__initramfs_end找到根文件系统的img,这两个变量在文件/linux-2.6.x/init/Initramfs.c中被引用。

介绍完根文件系统的挂载方式,我们来介绍如何配置和裁减应用程序。

由于flash容量限制,而且我们也并不需要很多应用程序的支持,所以我们可以只保留最简单的init、sh、ls、cd等应用程序,其他应用全部裁减掉。注意必须保证要有init和sh,否则内核无法运行或没有shell界面。另外,为了进一步裁减体积,我们利用busybox制作根文件系统,busybox的介绍文档网上非常多,这里不再介绍。

按照以上分析,我们来配置应用程序和busybox。

按照“一,配置并在RAM中运行内核(不带根文件系统)”中介绍的方法进入应用程序配置页。只需选中Busybox内的BusyboxSVN,其余选项全部取消,完全用busybox代替。

然后,我们来配置busybox。进入busybox目录,运行配置命令:

#cd user/busybox-svn

#make menuconfig

除了按照我们上面介绍的,保留最基本的应用程序之外,其他全部取消;还有一点需要特别注意。就是在“Build options”选择中选中编译成静态库,而不要编译成共享库,这样在根文件系统挂载时省去很多麻烦,虽然最后得到的内核体积会稍微增大一下。共享库的应用可以在内核运行成功后,进一步学习。

这样配置得到的根文件系统已经裁减了很大体积,但下载到SDRAM中运行时会发现根文件系统占有的内存空间仍然很大,始终保持12.5MB空间。这是因为,根文件系统的运行空间是在生成镜像时指定的。要裁减占有的内存空间,可以如下修改。

#vi vender/HHTech/BF533-HHBF/Makefile

修改第14行的“BLOCKS = 12800”为较小的值,比如说4096等,必须是256的整数倍,否则内核运行时根文件系统报错。这样修改后,根文件系统占有的flash和SDRAM空间都会相应减小。

通过以上裁减后,带有根文件系统的内核镜像完全可以控制在448KB以内,下载保存到flash后运行,你就可以看到可爱的“uClinux”欢迎界面了。[!--empirenews.page--]

如果要进一步裁减根文件系统,可以修改和删除vender/HHTech/BF533-HHBF/目录下的相关文件,具体操作不再详述。

uClinux的多进程处理

uClinux没有mmu管理存储器,在实现多个进程时(fork调用生成子进程)需要实现数据保护。 uClinux的fork和vfork:uClinux的fork等于vfork。实际上uClinux的多进程管理通过vfork来实现。这意味着 uClinux系统fork调用完程后,要么子进程代替父进程执行(此时父进程已经sleep)直到子进程调用exit退出,要么调用exec执行一个新的进程,这个时候将产生可执行文件的加载,即使这个进程只是父进程的拷贝,这个过程也不能避免。当子进程执行exit或exec后,子进程使用 wakeup把父进程唤醒,父进程继续往下执行。   uClinux的这种多进程实现机制同它的内存管理紧密相关。 uClinux针对nommu处理器开发,所以被迫使用一种flat方式的内存管理模式,启动新的应用程序时系统必须为应用程序分配存储空间,并立即把应用程序加载到内存。缺少了MMU的内存重映射机制,uClinux必须在可执行文件加载阶段对可执行文件reloc处理,使得程序执行时能够直接使用物理内存。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

史胜辉,在MTK工作了11年,一直在基带芯片的USB驱动领域做开发和验证。从最开始做USB2.0/3.0 IP验证和驱动开发到后面带领团队做上层协议驱动开发,以及跟硬件设计部门合作开发全新的USB硬件加速器。

关键字: 基带芯片 驱动领域 驱动开发

点击上方名片关注我们朱老师推荐语:此岗位为AIoT终身成长大会员同学提供的自己公司的岗位内推,总部在深圳,是一家专业从事闭路电视监控设备、会议摄像机的研发、制造、销售的高科技企业,有学过嵌入式课程或者海思项目的同学,想换...

关键字: 开发工程师 linux驱动 驱动开发

最近在学习MIPI接口的LCD驱动开发与调试,这里我主要用的是MIPI-DSI接口,它学习起来真的是太复杂了,特别是对于我这种很久都没写驱动来说更是头疼,但是头疼归头疼,工作咱们还是要完成的,那就只能硬着头皮往下肝吧!首...

关键字: MIPI 驱动开发 调试

关注、星标嵌入式云IOT技术圈,精彩及时送达来源|  Linux与SoC整理出了6种驱动开发时与设备注册、设备树相关的调试方法,彼此间没有优先级之分,每种方法不一定是最优解,但可以作为一种debug查找问题的手段,快速定...

关键字: 驱动开发

最近在学习MIPI接口的LCD驱动开发与调试,这里我主要用的是MIPI-DSI接口,它学习起来真的是太复杂了,特别是对于我这种很久都没写驱动来说更是头疼,但是头疼归头疼,工作咱们还是要完成的,那就只能硬着头皮往下肝吧!首...

关键字: MIPI 驱动开发 调试

哈喽,我是老吴,我来继续分享我的学习心得啦。gpio和pinctrl子系统在内核里的使用率非常高,和嵌入式产品的关联非常大。从这两个子系统开始学习驱动开发是个不错的入门选择。本文目录:一、gpio 与 pinctrl二、...

关键字: gp pi 驱动开发

前阵子工作上做了一些关于 ADC 的支持,由于现在 ADC 相关的支持都被移动到了 IIO (Industrial I/O) 子系统下,我查阅了一些关于 IIO 资料,包括书籍、文章、内核文档和代码。个人感觉最好的入门文...

关键字: IO 驱动开发 嵌入式

来源:知乎,作者: 埃尔维斯·刘能 链接:https://www.zhihu.com/question/34686343/answer/308464284 前言:上班划水在知乎看到一个帖子,网友问: 现在要选个方向,嵌入...

关键字: 嵌入式 驱动开发 ADI IC厂商

作者:程序员最幽默(ID:humor1024) 【0】 网传互联网公司加班表 【1】 互联网工作生存指南 【2】 据说,互联网公司员工上课座位如下 【3】 当代互联网企业真实写照 【4】 互联网公司排位,你同意吗? 【5...

关键字: 互联网 程序员 驱动开发 BSP

来源 :https://github.com/juwikuang/china_job_survey ▍趋势 2020年4月,中国大陆程序员平均工资14249元。 ▍一线城市工资 ▍各主要程序员城市工资变化 ▍异常的城市...

关键字: 程序员 驱动开发 编程语言 人工智能
关闭
关闭