Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1261820
  • 博文数量: 548
  • 博客积分: 7597
  • 博客等级: 少将
  • 技术积分: 4224
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-15 13:21
个人简介

嵌入式软件工程师&&太极拳

文章分类

全部博文(548)

文章存档

2014年(10)

2013年(76)

2012年(175)

2011年(287)

分类: LINUX

2011-02-20 20:23:01

内核:
应用程序(app)
标准C库 libs, POSIX
文件系统(VFS)
系统调用
内存管理,文件管理,进程调度,网络功能
70%的代码为设备驱动->操作硬件

bootloder和内核都是一种环境,干的事差不多,而bootloder只是引启内核,内核启动起来bootloder就没有用了
为什么不直接用内核而要用bootloder?
	因为内核太大,不可能每次装系统都要烧ROM,而bootloder精简专门为引导内核的

内核就是给上层应用程序提供运行环境的程序

代码仓库:
svn	 取代了cvs  常用
vss   windows
git


看内核源代码:
tree -L 2 > tree.txt    打印几级目录代码 , -L 指定目录的级数
COPYING   版权
CREDITS     人员  
Documentation    文档,kernel帮助文档
Makefile     最顶级的makefile
README      介绍功能
arch		支持的体系结构 (arch->cpu->soc->board)
	arm26	支持thumb
	cris		Axis 出的,外部摄像头的精简指令集
	frv		Fujitsu FR-V 出的嵌入式体系结构
	h8300	Hitachi h8/300 8bit/16bit RISC
	i386	80x86, AMD, Intel
	ia64	64-bit Itanium工作站用的,服务器或大型机
	m32r	M32R 处理器
	m68K	Motorola  摩托   32位的处理器
	mk68knommu	 不支持mmu的32位处理器
	mips	32位 RISC  在ARM之前最流行的嵌入式CPU (最常用的)
	parisc	HP9000工作站
	ppc		PowerPC  老apple 的处理器,Motorola和IBM, Apple
	ppc64	64位的PowerPc
	s390	IBM 大型机	
	sh		SuperH 嵌入式处理器
	sh64	64-bit  SuperH 嵌入式
	sparc	Sun 工作站,
	sparc64	64-bit Sun 工作站
	um		用户态Linux虚拟平台
	v850	NEC V850
	x86_64	AMD, Intel 64位
	xtensa  

crypto:   实现了常用的加密算法
drivers:   实现设备驱动的代码
	acpi  	电源管理   
	base	公共的
	block	块设备 
	char	字符设备
	cpufreq	 实现cpu频率
	crypto	加密算法
	firmware	Pc机用的固件
	ide		ide硬件接口
	i2c		i2c接口
	input	输入像键盘
	l3		音频总线
	misc	混杂类设备
	mmc	sd卡实现
	mtd		flash驱动
	net		网卡设备驱动 
	parport	并口驱动 
	PCI		pci总线
	pcmcia	插无线网卡的那种
	scsi		总线
	serial	串口	
	USB	USB
	video	视频相关的	

fs:	文件系统的实现
include : 头文件
	acpi	电源
	asm-	对应体系结构的硬件代码相对
	asm-generic	体系结构通用的
	linux	kernel 编程最多的 ,最常看的

init:   内核启动代码,关中断,设置mmu等 
	内核的入口就是从main.c开始看起

ipc:   实现进程间通讯的代码
kernel: 实现核心的东西,如进程调度
lib:	内核现实的一些库
mm: 内存管理		
net:  实现网络协议栈	
qt2440_config 内核配配置文件
scripts: 脚本工具,不需要内核代码,只是为了编译内核用的工具
security: 安全方面 
sound: 声卡,2.6内核还没有完善的就是声卡
usr: 用户态用的东西

看内核代码主要看:
	init/main.c 
	include/linux
	drivers/char
	drivers/base
	arch/arm
	README
	documentation
	ipc / kernel 跟驱动无关,和操作系统相关的,主要是进程管理

打patch:
	diff -Nur  源版本目录   修改后的目录  > 1.patch   生成patch在一级目录     
	patch -p1  <  1.path   忽略一级目录打补丁	用patch时要在目录里面忽略上级目录使用
		看Patch  +是新的东西   -代表 旧的东西

	patch -R < 1.path    恢复打patch之前的


内核 Makefile:
	先看vi Documentation/kbuild/makefiles.txt
	分为五种:
		顶层Makefile   ,决定哪些目录被编译
		./config    配置内核文件
		arch/Makefile  跟体系结构相关的Makefile, 决定怎么编译文件
		跟内核代码无关的Makefile,为内核编译服务的用的	
		对应每个子目录下的Makefile,	决定哪些文件被编译

	obj-y     要编译到内核里,是不可以再取出来
	obj-m    代表像模块式可以插入或出来的
	 多个文件编译成一个模块:	
		obj-m += c.o
		c-objs = a.o b.o

编译内核后把arch/arm/boot/zImage 转换成uImage ,因为u-boot不认zImage,所以要用u-boot里的工具mkimage来转换成u-boot能认的格式
	./mkimage -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -n "linux kernel" -d ./zImage uImage

-a  指定内核的地址
-e  指定栈指的地址 
-d 用哪个文件导入


Kconfig :  和makefile成双出现,为图形配置
	Documentation/kbuild/kconfig-language.txt 说明文档	
	
	menu  菜单名
	
	config TEST
		bool "x"	

	config XXX
		bool  "自定义名字"     这样可以选择要不要编译到内核里
		tristate  "自定义名字"      选择要不要编译到内核里和要不要编译成模块
		depends on   TEXT 	 依赖于TEST,即前面的TEST下的选项没有选中,这XXX里的东西就不会显示

	endmenu          菜单结束

	source "路径/Kconfig"   路径必须是自己要编译的路径

arch/arm/Kconfig   这个必须要写    source "自己程序Kconfig的路径"

make menuconfig   有[] 代表要不要编译到内核里,只有两个选项, <> 代表要不要编译到成模块或要不要编译进内核
menuconfig读的是默认配置文件->.config 文件,即自行去修改.config文件也行
	Code maturity level options  代码级别,就是要不要编译测试阶段的代码
	General setup   		
	System Type      内核移植时用的最多
	Bus support		
	Kernel Features   支持不支持抢栈
	Boot options 	      内核启动参数
	Floating point emulation    支持不支持浮点运算
	Userspace binary formats     支持不支持elf eof等 
	Power management option    电源管理选项
	Networking		网络协议栈,支持哪些协议栈
	Device Drivers     	设备驱动
	File systems   	选择文件系统
	profiling support	 
	kernel hacking		调试功能选项
	security options		安全相关的选项	
	cryptographic options		加密算法
	library routines		运行库
	
	Load an Alternate....    	   加载配置文件
	Save Configuration.....     保存配置文件

make config   文本选项 ,没有什么用
内核剪裁就是哪些东西要编译哪些东西不要编译

预习:
	char 字符设备驱动
	高级char 字符设备
	内存管理
	进程调度
	并发
	linux 中断体系
	软中断
	时间,延时
	linux设备模型 2.6内核特性


自己写的程序要在内核里使用怎么编译:
make bzImage   不会编译模块文件
make modules   只会编译模块文件
make modules clean   删除编译过的模块文件,但是会删除所有的编译过的模块文件
make M=指定要编译的模块目录 modules    编译指定目录的模块,清除也是,只要加上clean
make -C 指定顶级目录 M=`pwd` modules   在子目录里也可编译,也可不在子目录,即你要在哪个版本内核里插入使用,就用哪个版本内核里的makefile来编译, 
	 -C 可以指定用哪个kernel的makefile来编译

X86机的内核源码在:/usr/src/kernel/

在内核里编程:
	代表必须包含头文件  #include 和 #include 
	在内核里打印函数为printk(); 和printf的区别就是printk有打印级别
		printk(<0~7>"内容"); 有8个级别,格式就是<>里写0~7指定级别,一般不用,默认即可
							
入口:	在代表后面写一个宏module_init(入口函数名); 入口函数为是像以前写的Main函数一样
出口:	内核资料珍贵,所以执行完要把资源释放掉,再在后面定个宏module_exit(释放函数名); 

linux工具:	insmod  test.ko  把ko模块插入到内核   执行时会去调用module_init()这个宏
			rmmod  test.ko  把Ko模块移除内核	     执行时会去调用module_exit()这个宏
			lsmod    查看ko模块在不在

提示:module license 'unspecified' taints kernel  警告,能插入
	MODULE_LICENSE("GPL");  在代码里加入这个内核定义的宏就不会提示   

modinfo test.ko   查看这个模块的描述
	在代码里加入如下,就可以在modinfo里看到	
	MODULE_AUTHOR("kyo");    模块的作者
	MODULE_DESCRIPTION("This is usb module for print driver"); 模块的描述
	MODULE_VERSION("v0.1"); 模块的版本

	/lib/modules/2.6.18-128.e15/source 指定X86机的内核编译路径

模块传参:  不常用
	#include   要包含这个头文件
 	module_param(变量,类型,S_IRUGO);   这个宏传参
	insmod test.ko 变量=2  这样就可以把参数传给变量改变成2

提供给别人调用的函数:
	EXPORT_SYMBOL(函数名);

内核编程注意:
	不能使用C库
	linux内核必须遵守GNC和C
	不能访问非法内存
	尽量少用浮点运算
	内核的栈是定长的,非常小,8K大小的栈,资源宝贵啊,多用环形Buf或多线程一个读一个写
	内核并发和竞态
	注意可移植
	



阅读(724) | 评论(0) | 转发(0) |
0

上一篇:test2.c

下一篇:2010_3_15.kernel

给主人留下些什么吧!~~