组会1
1
操作系统:负责管理计算机中各种软硬件资源并控制各类软件运行(就是介于硬件和应用软件系统之间的软件,是人与计算机通信的桥梁)
组成部分:内核、驱动程序、接口库、外围
常见操作系统 :
操作系统(嵌入式)通常分为实时操作系统和非实时操作系统。
常见的实时系统有:ThreadX、FreeRTOS、ucOS;常见的非实时系统有:windows、linux、Android。
两类操作系统的主要区别在于任务调度处理方式不同,常用的任务调度方式有两种:基于任务优先级的任务调度方式和基于时间片的任务调度方式。
Stm32为什么不能移植Linux操作系统 (freertos linux)
什么芯片可以移植linux系统 MMU 内存管理单元
Cortex-M下的处理器没有内存管理单元MMU
Linux操作系统对MMU(内存管理单元)有极强的依赖
*MMU内存管理单元 物理地址,虚拟地址*
Linux 内核启动的时候会初始化 MMU,设置好内存映射,设置好以后 CPU 访问的都是虚拟地址。做Linux驱动的时候,我们不能直接操作寄存器,要用映射函数之后才能操作
我们能直接编译Linux源码吗 像freertos一样
2
Linux系统 bootloader、linux kernel(linux内核)、rootfile(根文件系统)
Linux 的移植主要包括3部分:
移植「bootloader 代码」, Linux 系统要启动就必须需要一个 bootloader 程序,也就说芯片上电以后先运行一段bootloader程序。 这段bootloader程序会先初始化DDR等外设, 然后将Linux内核从flash(NAND,NOR FLASH,SD,MMC 等)拷贝到 DDR 中,最后启动 Linux 内核。 bootloader 有很多,常用的就是 U-Boot。
移植「Linux 内核」,Linux内核由一系列程序组成,包括负责响应中断的中断服务程序、负责管理多个进程从而分享处理器时间的调度程序、负责管理地址空间的内存管理程序、网络、进程间通信的系统服务程序等。内核负责管理系统的硬件设备。
移植「根文件系统(rootfs)」,Linux 中的根文件系统更像是一个文件夹或者叫做目录,在这个目录里面会有很多的子目录。根目录下和子目录中会有很多的文件,这些文件是 Linux 运行所必须的,比如库、常用的软件和命令、设备文件、配置文件等等。根文件系统里面包含了一些最常用的命令和文件。
「U-Boot、Linux kernel和rootfs」 这三者一起构成了一个完整的Linux系统,一个可以正常使用、功能完善的Linux系统。
![50](/2023/11/29/%E7%BB%84%E4%BC%9A1/3.png)
Linux内核主要提供进程管理,内存管理,文件系统,设备驱动,网络协议等一些系统最基本的功能。原生的Linux内核没有界面
我们可以比较一下Linux内核源码和根文件系统的内存大小
移植freertos 直接编译 我们能直接下载Linux源码然后编译一下吗
3
U-Boot移植
U-Boot 是一个主要用于嵌入式系统的引导加载程序,可以支持多种不同的计算机系统结构,包括PPC、ARM、AVR32、MIPS、x86、68k、Nios与MicroBlaze。这也是一套在GNU通用公共许可证之下发布的自由软件。
① 开放源码;
② 支持多种嵌入式操作系统内核,如Linux、NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS, android;
③ 支持多个处理器系列,如PowerPC、ARM、x86、MIPS;
有很多现成的 bootloader 软件可以使用,比如 U-Boot、vivi、RedBoot 等
uboot 是一个遵循 GPL 协议的开源软件, 是一个裸机(无操作系统)代码,可以看作是一个裸机综合例程。这段bootloader程序会先初始化DDR等外设,然后将Linux内核从flash(NAND,NOR FLASH,SD,MMC 等)拷贝到 DDR 中,最后启动 Linux 内核。当然了,bootloader 的实际工作要复杂的多,但是它最主要的工作就是启动 Linux 内核,为了完成一些任务,uboot中必须初始化一部分硬件。比如uboot要在刷机时LCD上显示进度条就必须能驱动LCD,比如uboot能够通过串口提供操作界面就必须驱动串口,比如uboot要实现网络功能就必须驱动网卡芯片。
*uboot 官方的 uboot 代码*
uboot官方支持的硬件型号大而全,它主要的任务就是适应性强和泛化能力强,因此,官方的uboot,功能都比较抽象,尽可能不做具体的特定硬件相关的功能。而实际的硬件产品,又需要特定硬件的驱动与功能。
*半导体厂商的 uboot 代码* *√√√*
*开发板厂商的 uboot 代码*
在uboot源码里Makefile非常重要,Makefile里代码量非常大,分析可以了解uboot的启动流程。比如我们采用那种编译方式,导出那些变量给子Makefile,引用其他一些文件,匹配我们设置目标架构、交叉编译器和配置文件,生成一些文件。
*Makefile 文件描述了整个工程的编译、连接等规则。其中包括:工程中的哪些源文件需要编译以及如何编译、需要创建哪些库文件以及如何创建这些库文件、如何最后产生我们想要的可执行文件。尽管看起来可能是很复杂的事情,但是为工程编写Makefile 的好处是能够使用一行命令来完成“自动化编译”,一旦提供一个(通常对于一个工程来说会是多个)正确的 Makefile。编译整个工程你所要做的事就是在shell 提示符下输入make命令。整个工程完全自动编译,极大提高了效率。*
*Makefile基本规则*
还有readme
编 译 uboot 的 时 候 需 要 设 置 目 标 板 架 构 和 交 叉 编 译 器
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
mx6ull_14x14_ddr512_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12
*交叉编译器 一个在 X86 架构上可以编译 ARM 架构代码的 gcc编译器,即「交叉编译器」。*
ARCH,也就是指定架构,这里肯定是 arm; CROSS_COMPILE 用于指定编译器,只需要指明编译器前缀就行了,比如 arm-linux-gnueabihf-gcc 编译器的前缀就是“arm-linux-gnueabihf-”;最后一个参数 distclean 就是清除工程。
mx6ull_14x14_ddr512_emmc_defconfig用于配置 uboot。前面说了 uboot 是 bootloader 的一种,可以用来引导Linux,但是 uboot 除了引导 Linux 以外还可以引导其它的系统,而且 uboot 还支持其它的架构和外设,比如 USB、网络、SD 卡等。这些都是可以配置的,需要什么功能就使能什么功能。所以在编译 uboot 之前,一定要根据自己的需求配置 uboot。
其中 V=1 用于设置编译过程的信息输出级别;-j 用于设置主机使用多少线程编译uboot,最好设置成我们虚拟机所设置的核心数,如果在 VMware 里面给虚拟就分配了 4 个核,那么使用-j4 是最合适的,这样 4 个核都会一起编译。
下载到开发板测试
命令:setenv 和 saveenv Ping nfs tftp
在操作系统中一般被指定为操作系统运行环境的一些参数,如果没有配置相应的uboot环境变量,就会去执行代码中设定的相应变量,如果相应的uboot环境变量不为空就是优先去执行uboot环境变量对应的值(命令,指定的一些参数)
setenv bootargs ‘console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw’
Saveenv
1 、 console
用来设置linux终端,/dev/ttymxc0,后面的115200是串口波特率
2,root
设置跟文件系统的位置root=/dev/mmcblk1p2 用于指明根文件系统存放在mmcblk1设备的分区 2中,/dev/mmcblk1在本系统中 表示 EMMC
root 后面的rootwait rwrootwait 表示等待 mmc 设备初始化完成以后再挂载,否则会出错。rw表示跟文件系统是可以读写的。不加则只能进行读操作。
mmc dev 1 //切换到 EMMC
fatload 命令用于将指定的文件读取到 DRAM 中
我们将 EMMC 分区 1 中的 zImage 文件读取到 DRAM 中的0X80800000 地址处
————————————————
*bootcmd* 保存着 uboot 默认命令,uboot 倒计时结束以后就会执行 bootcmd 中的命令。这些命令一般都是用来启动 Linux 内核的,就是读zimag和设备树,可以在 uboot 启动以后进入命令行设置 bootcmd 环境变量的值。如果 EMMC 或者 NAND 中没有保存 bootcmd 的值,那么 uboot 就会使用默认的值,板子第一次运行 uboot 的时候都会使用默认值来设置 bootcmd 环境变量。
*bootargs* 保存着 uboot 传递给 Linux 内核的参数,根据这个Linux会读取到rootfs
uboot 的移植并不是说我们完完全全的从零开始将 uboot 移植到我们现在所使用的开发板。NXP 官方 uboot 中默认都是 NXP 自己的开发板,虽说我们可以直接在官方的开发板上直接修改,使 uboot 可以完整的运行在我们的板子上。或者开发平台上。
先在 configs 目录下创建默认配置文件,复制 mx6ull_14x14_evk_emmc_defconfig,然后重命名为 mx6ull_alientek_emmc_defconfig
CONFIG_SYS_EXTRA_OPTIONS=”IMX_CONFIG=board/freescale/mx6ull_alientek_
emmc/imximage.cfg,MX6ULL_EVK_EMMC_REWORK”
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6ULL_ALIENTEK_EMMC=y
CONFIG_CMD_GPIO=y
在 目 录 include/configs 下 添 加 I.MX6ULL-ALPHA 开 发 板 对 应 的 头 文 件 , 复 制include/configs/mx6ullevk.h,并重命名为 mx6ull_alientek_emmc.h,
在 board/freescale 目录下,在这个目录下有个名为 mx6ullevk 的文件夹,复制 mx6ullevk,将其重命名为 mx6ull_alientek_emmc
1、修改 mx6ull_alientek_emmc 目录下的 Makefile 文件
2,修改 mx6ull_alientek_emmc 目录下的 imximage.cfg 文件
3,修改 mx6ull_alientek_emmc 目录下的 Kconfig 文件
4、修改 mx6ull_alientek_emmc 目录下的 MAINTAINERS 文件
如果使用其他分辨率的 LCD 就需要修改 LCD 驱动,
因为正点原子开发板的网络芯片复位引脚和 NXP 官方开发板不一样,因此需要修改驱动。
mx6ull_alientek_emmc.h 和 mx6ull_alientek_emmc.c 这两个文件。
一般修改 LCD 驱动重点注意以下几点:
①、LCD 所使用的 GPIO,查看 uboot 中 LCD 的 IO 配置是否正确。
②、LCD 背光引脚 GPIO 的配置。
③、LCD 配置参数是否正确。
uboot 移植到此结束,简单总结一下 uboot 移植的过程:
①不管是购买的开发板还是自己做的开发板,基本都是参考半导体厂商的 demo 板,而半导体厂商会在他们自己的开发板上移植好 uboot、linux kernel 和 rootfs 等,最终制作好 BSP包提供给用户。我们可以在官方提供的 BSP 包的基础上添加我们的板子,也就是俗称的移植。
②我们购买的开发板或者自己做的板子一般都不会原封不动的照抄半导体厂商的 demo板,都会根据实际的情况来做修改,既然有修改就必然涉及到 uboot 下驱动的移植。
③一般 uboot 中需要解决串口、NAND、EMMC 或 SD 卡、网络和 LCD 驱动,因为 uboot的主要目的就是启动 Linux 内核,所以不需要考虑太多的外设驱动。
④、在 uboot 中添加自己的板子信息,根据自己板子的实际情况来修改 uboot 中的驱动。uboot 的启动流程,加上 uboot 顶层 Makefile 的分析,还是不少的!这也仅仅是 uboot 启动流程分析,里面的东西很多也比较复杂,我也一脸懵逼,只简单的介绍一下,大概有什么东西,移植的一个简单过程。
后面是Linux操作系统和跟文件系统的移植:
Linux操作系统的移植和uboot类似:配置,编译,移植;当然我们也需要适配开发板;
跟文件系统主要用buildroot构建好就可以能正常使用,配置文件按需修改。