欢迎访问电子工程网!   登录 | 免费注册 ]   

yd2763132的个人空间 http://www.eechina.com/space-uid-36266.html [收藏] [复制] [分享] [RSS]

博客

移植笔记

已有 328 次阅读2011-5-13 22:02 |个人分类:linux

附加uboot移植笔记
  硬件平台:优龙 FS2410 开发板
  Bootloader: uboot.1.1.6
  Os 内核: linux-2.6.14.1
  根文件系统格式:cramfs
  编译情况:在编译 u-boot 和 linux 内核时出现一些情况。
   在使用 cross-3.3.2 交叉编译环境编译 uboot 时没有出现任何问题,在编译 linux 内核时出现 arm-linux-gcc 版
  本过低。使用 cross-3.4.1 交叉编译环境编译 uboot 出现软浮点数错误,而编译内核正常。
编译busybox-1.1.3时使用3.3.2交叉编译器出错,使用3.4.1编译可通过。
新问题产生error: variable or field `__user' declared void
解决方法:arm-linux-gcc 3.4.1编译e2fsprogs-libs的时候报告错误fd.h:342: error: variable or field `__user’ declare
void,经查gcc 3.4.1中新增类型 __user ,需要引入编译器定义头文件,在引用#include 的前面加上#include linux/compiler.h,可以解决这个编译错误

   在编译过程中,起初出现找不到交叉编译工具,但是查看环境变量路径已设置好,通过 arm-linux-gcc –v 命
  令查看其版本,出现缺少某一动态库,使用 yum install 下载该动态库后正常。
  总结:在使用过程中要准备多套高低版本的交叉编译环境,以方便使用。
  Uboot 移植
  在此插入一个小知识点:
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  .globl _armboot_start
   _armboot_start: .word _start
  ldr r2, _armboot_start
  在_armboot_start 地址处定义字 start(内存中),将 start 值于 R2----------
  而在 c 语言中引用_armboot_start,其并不是纯地址而是地址中的变量值(start)即(*p)类是
  _start 是 uboot 映像在 SDRAM 中的重定位地址
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  具体 uboot 的原理可以看 2410 移植手册,只说说 uboot 的大致工作的函数流程:
   上电开始执行 \cpu\arm920t\start.s 函数,完成基本的 cpu 配置和 bootloader 搬运后跳到 \lib_arm\board.c 中的
  start_armboot 执行 c 语言,先在 bootloader 的底下建立 gd_t 和 bd_t 结构体保存电路板的配置参数,再在参数下面
  分配给应用程序使用的堆(deap)空间,再通过 init_fnc_t *init_sequence 数组将电路的外围器件初始化。(若配
  置 nand flash 和虚拟文件设置则完成相应的初始化函数),再设置环境变量初始化(对于环境变量的设置可以参考
  include/configs/lubbock.h 头文件,但是在建立新的平台后一般会有自己的头文件 nclude/configs/***.在建立时可
  以参照前文件),再将一些 ip 地址等参数保存到 gd_t 和 bd_t 结构体。完成上述初始化动作后,开始进入/common/
  main.c 中的 main_loop 函数,如果定义了 CONFIG_BOOTDELAY 配置并且 bootcmd 设置了读取 flash 命令后 bootm 命令
  就为自启动内核(反之需等待输入引导命令),在 CONFIG_BOOTDELAY 定义的时间内没有按键输入则根据 CONFIG_BOO
  TCOMMAND(环境变量为 bootcmd,一般定义为"nboot 0x30008000 0 0x40000\;bootm",为了消除第一次烧写 flash
  出现 crc 错误,故而此命令最好"saveenv\;nboot 0x30008000 0 0x40000\;bootm")自动调用 run_command 函数执行
  bootm 命令而引导内核工作;若没有定义 CONFIG_BOOTDELAY,则将一直等待命令的输入,命令输入后调用 run_comma
  nd 函数执行对应的命令;若输入的是 bootm 命令则引导内核,具体命令的格式和增加新命令的方法参考 include/com
  mand.h 文件中的定义(命令是;为分隔标志的,即可以输入多个命令)。
   无论自启动还是输入命令引导启动,多是使用 bootm 命令来引导内核.bootm 对应./command/cmd_bootm.c 文件中
  的 do_bootm 函数。当 bootm 没有输入地址时将使用 CFG_LOAD_ADDR 作为缺省地址。因为需要将 CFG_LOAD_ADDR 地址的 数据复制到 header 地址进行内核头文件校验,所以要使 bootcmd 的读取 flash 命令存放 sdram 地址和 CFG_LOAD_ADDR 相等否则会出现魔数错误提示(最好是将存放 sdram 地址于 CFG_LOAD_ADDR 相等)。先判断 cpu 的体系结构后,再比 较内核头文件中的地址是否于 CFG_LOAD_ADDR 相等;相等则不需要复制,不相等则复制到头文件定义的地址处(先判 断内核是否为压缩文件,是则解压后再复制。如果在选择 flash 大小时,对于 2M 的空间有时不够则可以将内核压缩以 节省空间,应该是先压缩 zImage 后加头文件以通过头文件校验)。
   注意:uboot 中存在小瑕疵,对于解压和地址不同时的复制由于没有复制头文件,其直接将内核复制到 hdr->ih_
  load 即头文件地址处,而内核指向 hdr->ih_ep 内核入口处而使得内核不能正常运行(除非在制作 uImage 将两地址设
  为相等);考虑到正规性两地址不应该相等所以把解压和复制的地址由 hdr->ih_load 改为 hdr->ih_ep)。
   再进入/lib_arm/armlinux.c 中的 do_bootm_linux 函数。如果想加快执行速度则可以使用 ramdisk 格式将根文件
  系统也复制到 sdram 中,该函数会先校验根文件和内核数据。最后通过使用旗标将CPU标识数和内核启动参数传递到内核,控制权 交给内核后 bios 完成其使命(要使内核启动,至少要定义 CONFIG_SETUP_MEMORY_TAGS 和CONFIG_CMDLINE_TAG 这样 才能将启动参数传递给内核。 对于新移植平台可参考 2410 手册。
  根文件系统制作和说明 需要使用 busybox,tinyLogin ,thttpd 三种软件包。 busybox 提供大部分的使用命令和引导脚本文件 linuxrc; tinyLogin 提供和用户组有关的命令;thttpd 提供远 端登录功能。 需要添加的文件后 passwd ,shadow,group 登录用户配置文件; /etc/profile 提供给应用程序环境变量以交代库路径和工具路径; 创建 /etc/fstab 文件提供文件系统信息; /etc/init.d/rcS 文件提供/bin/mount -a 命令来挂载/etc/fstab 中定义的文件系统;不过这些挂载动作在 linuxrc 脚 本中已经作了,所以脚本中可以不使用挂载文件系统。 /etc/inittab 文件是指示/sbin/init 这个进程的动作表格,init 进程将根据此表格完成一系列动作;
   ::sysinit:/etc/init.d/rcS 表示先进行 rcS 提供的挂载命令来挂载/etc/fstab 文件中文件系统,
   ::askfirst:-/bin/ash 表示通过串口来运行内核的 shell;在 shell 运行之前先运行 profile 文件设置环境变量;
  注意一点,由于 busybox 提供的 shell 名称为 ash 故而在 linuxrc 和 rcS 脚本中的!#bin/sh 改为!#bin/ash,以及 inittab
  中的::askfirst:-/bin/sh 改为::askfirst:-/bin/ash,不然会出现错误。

附:linuxrc文件命令
#!/bin/ash

echo "mount /etc as ramfs"
/bin/mount -n -t ramfs ramfs /etc
(
-n 不将加载信息记录在/etc/mtab文件中
-t<文件系统类型> 指定设备的文件系统类型 ramfs
ramfs /etc中的ramfs是某一ramfs设备
)
/bin/cp -a /mnt/etc/* /etc

echo "re­-create the /etc/mtab entries"
/bin/mount -f -t cramfs -o remount,ro /dev/mtdblock/2 /
(-f 不实际加载设备
-t<文件系统类型> 指定设备的文件系统类型 cramfs
-o remount,ro 以只读模式重新加载设备
////////////////////////////////////////////////////////////////////////////////
-o<选项> 指定加载文件系统时的选项。有些选项也可在/etc/fstab中使用。这些选项包括:
loop:用来把一个文件当成硬盘分区挂接上系统
async 以非同步的方式执行文件系统的输入输出动作。
atime 每次存取都更新inode的存取时间,默认设置,取消选项为noatime。
auto 必须在/etc/fstab文件中指定此选项。执行-a参数时,会加载设置为auto的设备,取消选取为noauto。
defaults 使用默认的选项。默认选项为rw、suid、dev、exec、anto nouser与async。
dev 可读文件系统上的字符或块设备,取消选项为nodev。
exec 可执行二进制文件,取消选项为noexec。
noatime 每次存取时不更新inode的存取时间。
noauto 无法使用-a参数来加载。
nodev 不读文件系统上的字符或块设备。
noexec 无法执行二进制文件。
nosuid 关闭set-user-identifier(设置用户ID)与set-group-identifer(设置组ID)设置位。
nouser 使一位用户无法执行加载操作,默认设置。
remount 重新加载设备。通常用于改变设备的设置状态。
ro 以只读模式加载。
rw 以可读写模式加载。
suid 启动set-user-identifier(设置用户ID)与set-group-identifer(设置组ID)设置位,取 消选项为nosuid。
sync 以同步方式执行文件系统的输入输出动作。
user 可以让一般用户加载设备。
//////////////////////////////////////////////////////////////////////////////////
)

echo "mount /dev/shm as tmpfs"
/bin/mount -n -t tmpfs tmpfs /dev/shm
与ramfs一样定义

echo "mount /proc as proc"
/bin/mount -n -t proc none /proc
none:因为proc为虚拟文件系统无设备

echo "mount /sys as sysfs"
/bin/mount -n -t sysfs none /sys
none:因为sysfs为虚拟文件系统无设备

exec /sbin/init


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 立即注册

回顶部