学习方法:(分阶段学习)-----内核学习是一个长期的过程
1.学习使用内核提供的接口函数 (涉及到很多操作系统知识,编程规范)
2.找到一个函数如do_fork来学习进程管理模块
3.通过kmalloc函数来学习进程管理,通过do_irq学习中断管理
1.U-BOOT配置与烧写常用命令 (生成u-boot.bin)(u-boot下载地址:)
(1) u-boot配置及烧写
tar xzvf*.zip
tar xjvf*.bz2
配置:make TQ210_config 运行:make ARCH=armCROSS_COMPILE=arm-linux-
大约 2分钟后编译完成,生成u-boot.bin,然后烧写到开发板中
烧写准备:网线连接,下载线连接,电源线连接 (ping通就可以),将u-boot.bin复制到tftp服务器目录下 (固化到开发板起始处)
tftp30000000 u-boot.bin /*下载到内存中*/
nand erase0 100000 /*擦除1M空间*/
nand write30000000 0 100000 /*将30000000处内容写1M到硬盘开始处*/
(2) u-boot命令详解
help:察看当前单板所支持的命令
printenv:打印环境变量
setenv:添加、修改、删除环境变量
saveenv:保存环境变量
tftp:通过网络下载文件
bootmaddr:执行程序,addr是执行地址
nand erase起始地址start 长度len --- 擦除start处开始的,长度为len的区域
nand write内存起始地址 flash起始地址 长度len --- 将内存起始地址处,长度为len的数据,写入flash起始地址处
nand read 内存起始地址 flash起始地址 长度len---将flash起始地址处,长度为len的数据,读到内存起始地址处
附:
<1> 配置 U-Boot
TQ210: makeTQ210_config
Smart210: make smart210_config
OK210: make forlinx_linux_config
OK6410: make forlinx_nand_ram256_config
Tiny6410: make tiny6410_config
TQ2440: make TQ2440_config
Mini2440: make mini2440_config
<2> 下载与运行
TQ210: tftp 0xc0008000 uImage
Smart210: tftp 0x20000000 uImage
OK210: tftp 0xc0008000 uImage
OK6410: tftp 0xc0008000 uImage
Tiny6410: tftp 0xc0008000 uImage
TQ2440: tftp 0x31000000
Mini2440: tftp 0x31000000 uImage
2.内核配置与编译
(1) 为什么要配置内核
硬件需求 软件需求 ----选出需要的,去掉不要的
(2) 内核配置方法
makeconfig:基于文本模式的交互式配置
makemenuconfig:基于文本模式的菜单型配置 (更好一些)
编译时比选的
<> 不选的
(3) 内核配置结果:放在.config中
(4) 内核编译:make uImage j 2
编译好的内核位于arch/
(5) 清理内核:make clean make distclean
mkimage工具讲解:(编译内核时将mkimage移动到/bin目录下)
uboot源代码的tools/目录下有mkimage工具,这个工具可以用来制作不压缩或者压缩的多种可启动映象文件.
mkimage在制作映象文件的时候,是在原来的可执行映象文件的前面加上一个0x40字节的头,记录参数所指定的信息,这样uboot才能识别这个映象是针对哪个CPU体系结构的,哪个OS的,哪种类型,加载内存中的哪个位置, 入口点在内存的那个位置以及映象名是什么
./mkimage -n 'U-boot' -A arm -O linux -T firmware -Cnone -d u-boot.bin u-boot.img
-A ==> set architecture to 'arch'
-O ==> set operating system to 'os'
-T ==> set image type to 'type'
-C ==> set compression type 'comp'
-a ==> set load address to 'addr' (hex)
-e ==> set entry point to 'ep' (hex)
-n ==> set image name to 'name'
-d ==> use image data from 'datafile'
-x ==> set XIP (execute in place)
参数说明:
-A 指定CPU的体系结构:
取值 表示的体系结构
alpha Alpha
arm A RM
x86 Intel x86
ia64 IA64
mips MIPS
mips64 MIPS 64 Bit
ppc PowerPC
s390 IBM S390
sh SuperH
sparc SPARC
sparc64 SPARC 64 Bit
m68k MC68000
-O 指定操作系统类型,可以取以下值:
openbsd、netbsd、freebsd、4_4bsd、linux、svr4、esix、solaris、irix、sco、dell、ncr、lynxos、vxworks、psos、qnx、u-boot、rtems、artos
-T 指定映象类型,可以取以下值:
standalone、kernel、ramdisk、multi、firmware、script、filesystem
-C 指定映象压缩方式,可以取以下值:
none 不压缩
gzip 用gzip的压缩方式
bzip2 用bzip2的压缩方式
-a 指定映象在内存中的加载地址,映象下载到内存中时,要按照用mkimage制作映象时,这个参数所指定的地址值来下载
-e 指定映象运行的入口点地址,这个地址就是-a参数指定的值加上0x40(因为前面有个mkimage添加的0x40个字节的头)
-n 指定映象名
-d 指定制作映象的源文件
/mkimage -A arm-O linux -C gzip -a 0x20008000 -e 0x20008000 -d linux.bin.gz uImage
-a参数后是内核的运行地址,-e参数后是入口地址
<1> 如果我们没用mkimage对内核进行处理的话,那直接把内核下载到0x30008000再运行就行,内核会自解压运行(不过内核运行需要一个tag来传递参数,而这个tag建议是由bootloader提供的,在u-boot下默认是由bootm命令建立的)。
<2>如果使用mkimage生成内核镜像文件的话,会在内核的前头加上了64byte的信息,供建立tag之用。bootm命令会首先判断bootm xxxx 这个指定的地址xxxx是否与-a指定的加载地址相同。
(1)如果不同的话会从这个地址开始提取出这个64byte的头部,对其进行分析,然后把去掉头部的内核复制到-a指定的load地址中去运行之
(2)如果相同的话那就让其原封不同的放在那,但-e指定的入口地址会推后64byte,以跳过这64byte的头部
3.内核模块
(1) 特点:<1> 模块本身并不被编译进内核文件(zImage或者bzImage)
<2> 可以根据需求,在内核运行期间动态的安装或卸载
(2) 范例
// hello.c
#include
#include
static int hello_init(void)
{
printf(KERN_WARNING"Hello,world!n");
return 0;
}
static void hello_exit(void)
{
printf("KERN_INFO"Goodbye,world!n");
}
module_init(hello_init);//加载内核模块
module_exit(hello_exit);//卸载内核模块
Makefile:
obj -m := hello.o
KDIR := /lib/modules/2.6.../build # 内核代码路径
all:
make -C$(KDIR) M=$(PWD) modules
(3) 安装与卸载
安装:insmod (insmod hello.ko)
卸载:rmmod (rmmod hello)
查看:lsmod
(4) 模块声明
MODULE_LICENSE("遵循的协议") --- 申明该模块遵守的许可证协议,如:“GPL“、”GPL v2“等
MODULE_AUTHOR("作者") --- 申明模块的作者
MODULE_DESCRIPTION("模块的功能描述") --- 申明模块的功能
MODULE_VERSION("V1.0")--- 申明模块的版本
(5) 模块参数
应用程序中:int main(int argc,char**argv) argc表示命令行输入的参数个数,argv中保存输入的参数
内核模块中:通过宏module_param指定保存模块参数的变量,模块参数用于在加载模块时传递参数给模块
module_param(name,type,perm)
name:变量的名称
type:变量类型,bool:布尔型 int:整型 charp:字符串型
perm是访问权限,S_IRUGO:读权限 S_IWUSR:写权限
例如:
inta = 3;
char*st;
module_param(a,int,S_IRUGO);
module_param(st,charp,S_IRUGO);
(6) 符号导出
内核符号的导出使用宏:EXPORT_SYMBOL(符号名)
(7) 总结
对比应用程序,内核模块具有以下不同:
<1>.应用程序是从头(main)到尾执行任务,执行结束后从内存中消失。
<2>.内核模块的初始化函数结束时,模块仍然存在于核中,直到卸载函数被调用,模块才从内核中消失。
4.Linux内核制作 (生成uImage)(www.kernel.com)
解压: tar xzvf *.zip
tarxjvf *.bz2
步骤:
(1) 清理 make distclean
(2) 配置 make menuconfig ARCH=arm
(3) 编译 make uImage ARCH=arm CROSS_COMPILE=arm-linux-
提示:mkimage not found ---mkimage帮助加文件头
在u-boot的tools目录中,移动mkimage到/bi
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』