# sleep 1 l version
打印U-BOOT版本信息 # version
U-Boot 1.1.4 (Jul 4 2006 - 12:42:27) l nand info
打印nand flash信息 # nand info
Device 0: Samsung K9F1208U0B at 0x4e000000 (64 MB, 16 kB sector) l nand device
显示某个nand设备 # nand device 0
Device 0: Samsung K9F1208U0B at 0x4e000000 (64 MB, 16 kB sector) ... is now current device l nand bad
# nand bad
Device 0 bad blocks: l nand read
nand read InAddr FlAddr size
InAddr: 从nand flash中读到内存的起始地址。 FlAddr: nand flash 的起始地址。
size: 从nand flash中读取的数据的大小。 # nand read 0x30008000 0 0x100000
NAND read: device 0 offset 0, size 1048576 ... 1048576 bytes read: OK l nand erease
nand erase FlAddr size
FlAddr: nand flash 的起始地址
size: 从nand flash中擦除数据块的大小 # nand erase 0x100000 0x20000
NAND erase: device 0 offset 1048576, size 131072 ... OK l nand write
nand write InAddr FlAddr size
InAddr: 写到Nand Flash中的数据在内存的起始地址 FlAddr: Nand Flash的起始地址 size: 数据的大小
# nand write 0x30f00000 0x100000 0x20000
NAND write: device 0 offset 1048576, size 131072 ... 131072 bytes written: OK l nboot
u-boot-1.1.4代码对于nboot命令的帮助不正确,修改如下: 正确的顺序为:
nboot InAddr dev FlAddr
InAddr: 需要装载到的内存的地址。
FlAddr: 在nand flash上uImage存放的地址 dev: 设备号
需要提前设置环境变量,否则nboot不会调用bootm #setenv autostart yes
# nboot 30008000 0 100000
Loading from device 0:
Created: 2006-07-06 7:31:52 UTC
Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 897428 Bytes = 876.4 kB Load Address: 30008000 Entry Point: 30008040
Automatic boot of image at addr 0x30008000 ... ## Booting image at 30008000 ... Starting kernel ...
2.7 u-boot 的移植过程
我们为当前移植的板子取名叫: teach2410, 在uboot中建立自己的开发板类型 2.7.1 修改Makefile修改
修改Makefile
[uboot@localhost uboot]#vi Makefile #为teach2410建立编译项 teach2410_config : unconfig
@./mkconfig $(@:_config=) arm arm920t teach2410 NULL s3c24x0 各项的意思如下:
arm: CPU的架构(ARCH)
arm920t: CPU的类型(CPU),其对应于cpu/arm920t子目录。 teach2410: 开发板的型号(BOARD),对应于teach2410目录。 NULL: 开发者/或经销商(vender)。 s3c24x0: 片上系统(SOC)
2.7.2 在board 子目录中建立teach2410
$cp rf board/smdk2410 board/teach2410 $cd board/teach2410
$mv smdk2410.c teach2410.c
2.7.3 在include/configs/中建立配置头文件
$cp include/configs/smdk2410.h include/configs/teach2410.h 2.7.4 编译
$make teach2410_config
$make CROSS_COMPILE=arm-linux- 2.7.5 u-boot移植过程中的调试方法
点灯
串口打印
使用u-boot的命令查看信息
3 第三章linux内核移植
3.1 Linux2.4.20的代码布局
l arch目录
arch是architecture的缩写,内核中与具体cpu和体系结构相关的代码以单独目录进行存放,而相应的头文件.h则分别放在include/asm目录下。
在每个cpu的子目录下,又进一步分解为boot,mm,kernel等子目录,分别包含与系统引导,内存管理,系统调用的进入与返回,中断处理以及其它内核代码依赖于cpu和系统结构的底层代码。
l kernel目录
linux大多数关键的核心功能都是在这个目录实现。(调度程序,进程控制,模块化,其它操作)
l mm目录
mm目录中的文件为Linux核心实现内存管理中体系结构无关的部分。这个目录包含换页及内存的分配和释放的函数,还有允许用户进程将内存区间映射到它们地址空间的各种技术。
l fs目录
所有的文件系统实现的代码。每个目录分别对应一种文件系统的实现,公用的源程序则用于“虚拟文件系统”vfs。
l ipc和lib目录
进程间通信和库函数各有一个小的专用目录。 l drivers
包括各种块设备与字符设备的驱动程序。 l net目录
包含各种不同网卡和网络规程的设备驱动程序。 l include目录
包含了所有的.h文件,同时依据arch的目录结构作相应的组织。
3.2 Linux2.6.11内核配置系统
首先分析了 Linux 内核中的配置系统结构,然后解释Makefile 和配置文件的格式以及配置语句的含义。最后,通过一个简单的例子,具体说明如何将自行开发的代码加入到 Linux 内核中。
3.2.1 配置系统的基本结构
Linux内核的配置系统由三个部分组成,分别是: l Makefile:分布在 Linux 内核源代码中的 Makefile,定义 Linux 内核的编译规则。 l 配置文件(Kconfig):给用户提供配置选择的功能。
l 配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)和配置
用户界面(提供基于字符界面、基于 Ncurses 图形界面以及基于 Xwindows 图形界面的用户配置界面,各自对应于 Make config、Make menuconfig 和 make xconfig)。
这些配置工具都是使用脚本语言,如 Tcl/TK、Perl 编写的(也包含一些用 C 编写的代码)。本文并不是对配置系统本身进行分析,而是介绍如何使用配置系统。所以,除非是配置系统的维护者,内核开发者无须了解它们的原理,只需要知道如何编写 Makefile 和配置文件就可以。所以,在本文中,我们只对 Makefile 和配置文件进行讨论。另外,凡是涉及到与具体 CPU 体系结构相关的内容,我们都以 ARM 为例,这样不仅可以将讨论的问题明确化,而且对内容本身不产生影响。 3.2.2 3.2.2.1
Makefile Makefile概述
Makefile 的作用是根据配置的情况,构造出需要编译的源文件列表,然后分别编译,并把目标代码链接到一起,最终形成 Linux 内核二进制文件。由于 Linux 内核源代码是按照树形结构组织的,所以 Makefile 也被分布在目录树中。Linux 内核中的 Makefile 以及与 Makefile 直接相关的文件有:
l Makefile:顶层 Makefile,是整个内核配置、编译的总体控制文件。
l .config:内核配置文件,包含由用户选择的配置选项,用来存放内核配置后的结果
(如 make menuconfig)。
l arch/*/Makefile:位于各种 CPU 体系目录下的 Makefile,如 arch/arm/Makefile,
是针对特定平台的 Makefile。
l 各个子目录下的 Makefile:比如 drivers/Makefile,负责所在子目录下源代码的管
理。
l scripts \\Makefile.*:规则文件,被所有的 Makefile 使用。
用户通过 make menuconfig配置后,产生了 .config。顶层 Makefile 读入 .config 中的配置选择。顶层 Makefile 有两个主要的任务:产生 vmlinux 文件和内核模块(module)。为了达到此目的,顶层 Makefile 递归的进入到内核的各个子目录中,分别调用位于这些子目录中的 Makefile。至于到底进入哪些子目录,取决于内核的配置。在顶层 Makefile 中,有一句:include arch/$(ARCH)/Makefile,包含了特定 CPU 体系结构下的 Makefile,这个 Makefile 中包含了平台相关的信息。位于各个子目录下的 Makefile 同样也根据 .config 给出的配置信息,构造出当前配置下需要的源文件列表,编译出与内核直接相连的目标文件,或者是模块。scripts/Makefile.* 为所有的makefile文件定义共有的规则。 3.2.2.2 3.2.2.2.1
Makefile分析 目标定义
目标定义是子目录 Makefile 中最重要的部分,定义了在本子目录下那些目标被编译,根据特殊的编译选项如何链接目标文件,同时控制哪些子目录要递归进入进行编译。
l 被编译到 Linux 内核 vmlinux 中的目标文件列表:
Makefile会编译所有的$(obj-y)中定义的文件,然后调用链接器将这些文件链接到built-in.o文件中。最终built-in.o文件通过顶层Makefile链接到vmlinux中。值得注意的是
$(obj-y)的文件顺序很重要。列表文件可以重复,文件第一次出现时将会链接到built-in.o中,后来出现的同名文件将会被忽略。文件顺序直接决定了他们被调用的顺序。
Example: #drivers/isdn/i4l/Makefile obj-$(CONFIG_ISDN) += isdn.o obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
当CONFIG_ISDN,CONFIG_ISDN_PPP_BSDCOMP定义为y时。会被编译到vmlinux。
l 被编译到模块的目标文件列表
以$(obj-m)定义的目标文件,被编译成为可加载的模块,一个模块可以由一个或者几个文件组成。当以一个文件组成时可以定义成如下形式:
Example:
#drivers/isdn/i4l/Makefile
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o (假设CONFIG_ISDN_PPP_BSDCOMP= m) 当一个模块有几个文件组成时,需要通过变量$(
Example:
#drivers/isdn/i4l/Makefile
obj-$(CONFIG_ISDN) += isdn.o
isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o (假设CONFIG_ISDN = m)
最终会生成模块isdn.o,此模块由isdn_net_lib.o isdn_v110.o isdn_common.o链接而成。
l 被编译到库文件的目标文件列表
所有包含在lib-y定义中的目标文件都将会被编译到该目录下一个统一的库文件中。值得注意的是lib-y定义一般被限制在 lib 和arch/$(ARCH)/lib 目录中。
Example:
#arch/i386/lib/Makefile lib-y := checksum.o delay.o 3.2.2.2.2
目录递归
Makefile文件负责当前目录下的目标文件,子目录中的文件由子目录中的makefile负责编译,编译系统使用obj-y 和 obj-m来自动递归编译各个子目录中的文件。
Example: #fs/Makefile obj-$(CONFIG_EXT2_FS) += ext2/ 如果在内核配置文件.config中,CONFIG_EXT2_FS被设置为y或者m,则内核makefile会自动进入ext2目录来进行编译。内核Makefile只使用这些信息来决定是否需要编译这个目录,子目录中的makefile规定哪些文件编译为模块,哪些文件编译进内核 3.2.2.2.3
编译选项
$(CC) 编译c文件 $(CC) 编译汇编文件 $(LD) 链接
l EXTRA_CFLAGS
EXTRA_AFLAGS, EXTRA_LDFLAGS,