【笔记】构建Linux 0.1(BeagleBone Black)

以下很多都是回忆,不一定准了。

注意这里的文章自动换行了。

 


我构建的目标平台为BeagleBone Black,
'http://beagleboard.org/'。

交叉编译工具为Sourcery CodeBench Lite,
'http://www.mentor.com/'。

要构建Linux,很简单,只有3个部分,
1,bootloader,即启动引导程序,我选择U-Boot。
2,Linux内核。
3,应用程序。

我还没研究是什么决定了32位和64位。

我主要的资料,
Running Linux
介绍Linux的书,这才叫入门级,了解下Linux的思想即可,书的内容可能有些过时,
这本书不是介绍怎么使用Linux的。如果想知道怎么使用Linux,
可看看Linux Pocket Guide,很薄。
鸟哥的书也不错,感觉挺详细的,好于大部分书,我没看。
我连shell脚本都不会写呢,很多命令没用过,这与构建Linux关系不大。

Building Embedded Linux Systems
教构建嵌入式Linux的,了解下思想即可。

http://www.linuxfromscratch.org/
教构建各种Linux的网站,最关键的是网站给出了Linux由哪些应用程序构成。
我没有用网站中的方式,sed那种命令不会。也是了解下思想即可。

If you can’t explain it simply, you don’t understand it well enough.
                                                   --Albert Einstein


BeagleBone Black有4种启动方式,我选择用SD卡。
准备SD卡,将SD卡插到电脑中,在我的系统中被识别为/dev/sdb。

分区:
# fdisk /dev/sdb
用法很简单,输入'm',就可得到帮助。
第一个分区64M,类型为FAT32 (LBA),加上启动标记。
第二个分区为余下的全部,类型默认为Linux,不必改。

参考过程是这样的,
输入'o',新建一个空DOS分区表,这会清除所有分区。
输入'p',会列出分区列表,此时应该没有。
输入'n'来添加新分区,直接'enter',接受默认为主分区,'enter'接受默认为第一分区,
'enter'接受默认的开始扇区,输入'+64M',设置分区大小为64M。
输入't',来改变分区类型,自动选择了第一个分区,输入l可列出所有分区列表的代码,
输入'c'选择W95 FAT32(LBA)。
输入'a',在第一分区设置可启动标记。
输入'n','enter'主分区,'enter'第二个,'enter'起始扇区,'enter'结束扇区。
输入'w',将改动写入分区表。

格式化:
# mkfs.vfat -F 32 /dev/sdb1
# mkfs.ext4 /dev/sdb2

第一个分区用来放U-Boot,板子启动后就会找一个叫MLO的文件,编译U-Boot后,就会生成
一个MLO,不必担心。
第二个分区用来放Linux系统。

sdb2被格式化后,里面自动有个lost+found,文件系统的结构中正好有一条:
/lost+found: Filesystem-specific recoverable data

===============================================================================
我的文件系统目录结构
/
/bin             --> /usr/bin/
/boot/
/dev/
/etc/
/home/
/home/root
/lib             --> /usr/lib/
/mnt/
/proc/
/run/
/sbin            --> /usr/bin/
/sys/
/tmp
/usr/
/usr/app/
/usr/bin/
/usr/include/
/usr/lib/
/usr/sbin       --> bin/
/usr/share/
/usr/share/man/
/var/
/var/run         --> /run/


===============================================================================
编译时的一些配置等,我为了方便调用,放到这里,不要看。

$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ export PATH=$PATH:/home/spy/Work/U-Boot/u-boot/tools
$ export CROSS_COMPILE=arm-none-linux-gnueabi-

# chown -R 0:0
# chgrp -v tty /usr/app/util-linux/bin/wall
# chown -R spy:users

找readelf结果中带"Shared library"的行
readelf -ld | grep "Shared library"

以可读写重新挂载根文件系统
mount -n -o remount,rw /

放到交叉编译器搜索库中的程序库
libcap,pam,ncurses,gdbm,db,iptables

coreutils与util-linux重复的命令。
kill

shadow与util-linux重复的命令。
{login,nologin,su}

shadow与coreutils重复的命令。
groups


===============================================================================

 

下面是编译软件的过程

 

U-Boot

============ http://www.denx.de/wiki/U-Boot/WebHome

$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ export CROSS_COMPILE=arm-none-linux-gnueabi-

$ make O=../u-boot distclean
$ make O=../u-boot am335x_boneblack_config
$ make O=../u-boot all
--------------------------------------------------------------------------------

源码中正好有am335x_boneblack这个配置文件,对应我的开发板,想知道可用的配置文件
看README吧,它会告诉你到另一个文件中找。

忘了是编译U-Boot还是Linux内核的时候,提示我的系统中缺少bc,用你的包管理器安上就好了。

/*------------------------------------------------------------------------------
摘自TI的wiki,让你了解MLO和u-boot.img是什么。
大概是AM335X芯片中的程序较小,只为了4种启动方式初始化,
然后找到MLO,运行MLO进一步初始化,如DDR3内存。
MLO最后找到u-boot.img,运行之。u-boot.img这个名字应该是在MLO的代码中指定的。
提示:TI的StarterWare中的2个文件叫MLO和app。

Two stage U-Boot design

This section gives an overview of the two stage U-Boot approach adopted for AM335X.

The size of the internal RAM in AM335X is 128KB out of which
18KB at the end is used by the ROM code. Also,
1 KB at the start (0x402f0000 - 0x402f0400) is secure and it cannot be accessed
This places a limit of 109KB on the size of the U-Boot binary which
the ROM code can transfer to the internal RAM and use as an initial stack
before initialization of DRAM.

Since it is not possible to squeeze in all the functionality
that is normally expected from U-Boot in < 110KB (after setting aside some space
for stack, heap etc) a two stage approach has been adopted.
Initial stage initalize only the required boot devices (NAND, MMC, I2C etc);
2nd full stage initall all other devices (ethernet, timers, clocks etc).
The 1st binary is generated MLO and the 2nd stage is generated as u-boot.img.
------------------------------------------------------------------------------*/

编译完后,现在就可以找找成就感了,
将MLO和u-boot.img复制到SD卡的第一个分区里;
将串口调试用的线与计算机相连,启动串口调试程序,如Putty。
将SD卡插入开发板,保持按下板子上的启动选择键,插上电源,板子会从SD卡启动,
可以松开启动选择键了。

Putty的窗口上会打印一些信息,你会看到一个1秒的倒计时,然后U-Boot会运行环境变量中
已经设置好的一些列命令,比如将Linux内核载入内存,但此时还没有内核文件,U-Boot会
停留在它自己的命令行中,你可以输入命令,如reset,这会让板子重启,倒计时的时候
按下计算机上的任意键,U-Boot就不会运行环境变量中的命令了,可玩一玩下面的演示。

给出U-Boot中的一些演示,输入help可显示所有命令。
help后接命令,可显示该命令的帮助。如"help help"。

U-Boot# mmc rescan
U-Boot# mmc list
OMAP SD/MMC: 0
 OMAP SD/MMC: 1
U-Boot# mmc dev
mmc0 is current device
U-Boot# mmc part

Partition Map for MMC device 0  --   Partition Type: DOS

Part    Start Sector    Num Sectors     UUID            Type
  1     2048            131072          29942d7e-01     0c Boot
  2     133120          15390720        29942d7e-02     83
U-Boot# ls mmc 0:1
   100688   mlo
   308232   u-boot.img
      510   uenv.txt

3 file(s), 0 dir(s)

U-Boot# ls mmc 0:2
<DIR>       4096 .
<DIR>       4096 ..
<SYM>          7 bin
<DIR>       4096 boot
<DIR>       4096 dev
<DIR>       4096 etc
<DIR>       4096 home
<SYM>          7 lib
<DIR>       4096 lost+found
<DIR>       4096 mnt
<DIR>       4096 proc
<DIR>       4096 run
<SYM>          7 sbin
<DIR>       4096 sys
<DIR>       4096 tmp
<DIR>       4096 usr
<DIR>       4096 var
U-Boot# mmcinfo
Device: OMAP SD/MMC
Manufacturer ID: 3
OEM: 5344
Name: SU08G
Tran Speed: 50000000
Rd Block Len: 512
SD version 3.0
High Capacity: Yes
Capacity: 7.4 GiB
Bus Width: 4-bit
U-Boot# mmc dev 1
mmc1(part 0) is current device
U-Boot# mmcinfo
Device: OMAP SD/MMC
Manufacturer ID: fe
OEM: 14e
Name: MMC02
Tran Speed: 52000000
Rd Block Len: 512
MMC version 4.41
High Capacity: No
Capacity: 1.8 GiB
Bus Width: 4-bit
U-Boot# mmc dev 0
mmc0 is current device
U-Boot#

fatls,ext4ls也可以显示文件,但对应某种文件系统。

 

 

 

 

Linux

============ http://www.kernel.org/

内核配置文件我在'https://github.com/beagleboard/kernel/tree/3.13/configs'找的,
复制一份名字改'.config'放到O指定的目录中。
这样就可以用'make oldconfig'了。
我的内核版本是Linux-3.13.5,并没有提示新的配置。
如果要修改的话,要注意systemd对内核的配置是有要求的,我并没有改。

$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin
$ export PATH=$PATH:/home/spy/Work/U-Boot/u-boot/tools
$ export CROSS_COMPILE=arm-none-linux-gnueabi-

$ make O=../linux ARCH=arm help
$ make O=../linux ARCH=arm mrproper
$ make O=../linux ARCH=arm oldconfig
$ make O=../linux ARCH=arm LOADADDR=0x80008000 uImage
$ make O=../linux ARCH=arm LOADADDR=0x80008000 dtbs
$ make O=../linux ARCH=arm LOADADDR=0x80008000 modules
$ make O=../linux ARCH=arm LOADADDR=0x80008000 INSTALL_MOD_PATH=/home/spy/Work/root modules_install
$ make O=../linux ARCH=arm LOADADDR=0x80008000 INSTALL_FW_PATH=/home/spy/Work/fw firmware_install
$ make O=../linux ARCH=arm LOADADDR=0x80008000 INSTALL_HDR_PATH=/home/spy/Work/root/hdr headers_install
--------------------------------------------------------------------------------

'make help'是否指定ARCH,输出内容是不同的。

uImage就是压缩后的Linux内核,编译时需要mkimage这个工具,编译U-Boot的时候会生成那个工具,
所以我编译内核之前指定了该工具的目录。

-dts  --> device tree source
-dtb  --> device tree blob
-dtbo --> device tree blob overlay
-dtc  --> device tree compile
没研究为什么编译设备树是dtbs,是在make help的帮助中看到的。

内核的配置中指定了很多把驱动编译成模块的,这部分需要'make modules'来单独编译。
我构建完的系统并没有用到这些modules,插个U盘是可用的。

编译完成后,可在输出文件夹的'arch/arm/boot'找到zImage, uImage和dts子文件夹,
dts里面有am335x-boneblack.dtb。zImage也是内核,也可以用,但我用的uImage。

最后那三个安装目录自己选个更好的吧。
modules会安在'lib/modules'和'lib/firmware'2个文件夹中。
/*------------------------------------------------------------------------------
安装modules的时候,可能会提示depmod出问题,据说正常,那不是处理交叉编译的模块的。
但我还是看到了depmod后应该出现的modules.dep文件。
depmod是用来构建模块依存关系的,目的是,当用insmod装载某模块的时候,可能会失败,
因为这个模块依赖的其他模块还没有装入内核,depmod构建完依赖关系后,用另外一个命令
装载模块,即可自动装载模块所依赖的其他模块。
------------------------------------------------------------------------------*/

firmware也安在'lib/firmware'中,但与modules中的不同。我目前不知道firmware是干什么的。

headers还是需要安装的,它就像glibc那样,编译程序时被调用。

--------------------------------------------------------------------------------

下面可以验证了。
将uImage文件,dts文件夹复制到SD卡第二个分区的/boot/里。
其实dts中应该只需am335x-boneblack.dtb。

启动开发板前应该了解下U-Boot如何载入Linux。
/*------------------------------------------------------------------------------
U-Boot中最关键的环境变量
bootcmd: This variable defines a command string that is automatically executed
         when the initial countdown is not interrupted.
         This command is only executed when the variable bootdelay is also defined!
bootargs: The contents of this variable are passed to the Linux kernel as boot
          arguments (aka "command line").

U-Boot中最关键的命令
run    - run commands in an environment variable

U-Boot启动后会运行bootcmd里的命令,所以要研究的话,从bootcmd开始。
------------------------------------------------------------------------------*/
提示:我的研究在后面。现在可不必研究直接看我的处理。

编译后的U-Boot是不能引导uImage的,通过printenv看U-Boot的环境变量,可看到
它找的是zImage,而且am335x-boneblack.dtb是在/boot/中找,不是/boot/dts/。
如果将zImage和am335x-boneblack.dtb放到/boot中应该能引导。

为了符合我的要求,要修改环境变量,可以用editenv修改环境变量后saveenv。
但还是别这么做了,我不知道它把环境变量保存到哪里去了。我以为把MLO和u-boot.img换回
原始的可以恢复默认的环境变量值,但不是这样,把SD卡格式化后也没用。
有可能是存到eMMC中了,我想尽各种办法破坏eMMC的数据,用了
'dd if=/dev/zero of=/dev/mmcblk1'也不行。
除了mmcblk1还有个mmcblk1boot,可能是存到那里了,记着那个设备比较奇怪,没有验证。
最后用'env default -a'然后'saveenv'恢复默认了。

另一个方法是创建一个uEnv.txt文件,将它和MLO放到一起,内容如下。
该文件中的环境变量会覆盖掉默认的环境变量。
/*
bootfile=uImage
loadfdt=load mmc ${bootpart} ${fdtaddr} ${bootdir}/dts/${fdtfile}
mmcloados=run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootm ${loadaddr} - ${fdtaddr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
mmcroot=/dev/mmcblk0p2 rw
mmcargs=setenv bootargs console=${console} ${optargs} root=${mmcroot} rootfstype=${mmcrootfstype} init=/usr/lib/systemd/systemd

*/
一共6行,最后一行空白。
改动不是很大,bootfile修改了内核名字,
loadfdt中只是在目录中加了“dts/”,
mmcloados主要是把bootz改成bootm。
mmcroot把只读改成了读写,原因是systemd启动后会创建一个machine-id到/etc中。
也许有其他办法,如/etc/fstab文件,但我为了简单没创建那个文件。
mmcargs只是在后面指定了init为systemd,也有其他方法,如init为指向systemd的软链接。

启动BeagleBone Black,待内核启动后会打印很多信息,最后你将目睹“kernel panic”,
这是因为我们目前并没有init程序,为了找到成就感,你可以编译下面
静态链接的“Hello world!”,放到某个目录中,然后在U-Boot的mmcargs变量中
把init指定为那个hello。

hello.c
/*-----------------------------
#include <stdio.h>

int main(int argc, char *argv)
{
  printf("Hello world!\n");
  sleep(999999999);
}

------------------------------*/

$ arm-none-linux-gnueabi-gcc -o hello -static hello.c
再次启动,最后你看到的将是"Hello world!"。

/*------------------------------------------------------------------------------
我分析了U-Boot的引导过程,如下,再往下是我的演示。

gpio set 53;   //这个是点亮LED灯的,其实并没有这个,是我在其他的U-Boot中看到的。
i2c mw 0x24 1 0x3e; //这个也没有,不知干什么的,激发下你的好奇心。
mmc dev 0; //将设备切换到'0',即SD卡,其实一开始就是'0',eMMC是'1'。
mmc rescan; //应该是检测设备是否存在吧。

gpio set 54;
load mmc 0 0x80200000 uEnv.txt;
env import -t 0x80200000 $filesi

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Beaglebone Black是一种开发板,可以运行不同的操作系统,如QNX和QT。它可以通过HDMI连接显示器,并具备在Beaglebone Black上安装和配置QT库的能力。 关于Beaglebone Black上的QT的安装和配置,可以参考文章"http://embedded.von-kannen.net/2014/05/21/qt-4-8-6-on-beaglebone-black/"提供的参考资料。 在开始安装和配置之前,需要先按照文章"Beaglebone Black——tslib编译与安装"中的步骤完成操作系统的安装和配置。在完成这些步骤后,可以继续下面的步骤,即在PC机上编译Qt源码、在Beaglebone Black上安装和配置Qt库,以及在PC机上安装和配置Qt Creator。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [BeagleboneBlack-QNX-QT:Beaglebone黑色(AM335X)HDMI(TDA19988)QNX QT](https://download.csdn.net/download/weixin_42171132/15089410)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Beaglebone Black——嵌入式QT开发环境搭建](https://blog.csdn.net/zy812248258/article/details/42554139)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值