一、linux内核的核心功能:
1、进程管理和进程通信
2、内存管理(内存分配,内存映射)
3、文件系统(yaffs2、nfs、vfat(fat16和fat32)、vfs...)
4、设备管理(字符、块、网络)
5、网络功能(四层:应用程层、传输层、网络层、网络接口层(用户空间:应用层;其他三层在内核空间))
================================================================================================
二、操作系统带来的优势:
1、多任务的,让不同的任务实现不同的功能,程序代码比较清晰
2、多任务,任务是可以调度的,提高系统的实时性。
3、操作系统有内核空间和用户空间,提高了系统的稳定性
4、提供网络协议
5、提供一些软件的库(jpeg、madlib、...)
6、通信协议方便移植:http、telnet、voip......
================================================================================================
三、在内核移植的时候,源码包的来源:
1、芯片原厂/代理商(安富利、富昌、大联大、科通.....)
2、kernel官网:www.kernel.org
3、第三方
注意:
我们选择的内核源码包,必须要支持目标CPU,最好能支持该CPU的某一块板子。(SMDKV210--->s5pv210)
================================================================================================
四、移植三星提供的内核源码包 ---android_kernel_2.6.35_smdkv210.tar.bz2
1、解压
#sudo tar -jxvf android_kernel_2.6.35_smdkv210.tar.bz2
#sudo chmod 777 android-kernel-samsung-dev/ -R
-------------------------------------------------------------------------
2、linux内核源码的结构
与GEC210平台相关的源码:
arch/arm/mach-s5pv210/
arch/arm/plat-s5p/
drivers/
--------------------------------------------------------------------------
3、如何编译针对SMDKV210平台的源码
1)设置交叉编译的工具链
修改内核源码顶层路径下的Makefile文件
ARCH
?= $(SUBARCH)
CROSS_COMPILE
?=
改成:
ARCH
?= arm
CROSS_COMPILE
?= /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-
2)使用smdkv210的默认配置
# cp arch/arm/configs/smdkv210_android_defconfig .config
或
# make smdkv210_android_defconfig
3)内核配置
make menuconfig
4)编译 ---> zImage --->运行在SMDKV210平台上
make -j 4
LD arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready
注意:
make clean
make distclean :make clean + .config配置文件
----------------------------------------------------------------------------
4、内核移植过程:
1)该内核的控制台
SDMKV210: serial3(uart2) ---> GEC210: serial1(uart0)
#make menuconfig
System Type --->
(0) S3C UART to use for low-level messages
Kernel hacking --->
(0) S3C UART to use for low-level debug
2)修改内核中,使用的内存的地址宏定义:
SMDKV210平台,内存范围:0x2000_0000~0x5FFF_FFFFF
GEC210平台,内存范围:0x3000_0000~0x4FFF_FFFFF
(1) arch/arm/mach-s5pv210/Makefile.boot
zreladdr-y := 0x30008000 ---->zImage reload address ,内核的加载地址. # setenv bootcmd 'nand read 0x30008000 0x600000 0x5000000; bootm 0x30008000'
params_phys-y := 0x30000100 ---->uboot在启动内核的时候,会传递参数给内核。uboot将这个放到某个地址上0x30000100。
(2)vim arch/arm/mach-s5pv210/include/mach/memory.h
#if defined(CONFIG_MACH_SMDKV210)
#define PHYS_OFFSET UL(0x30000000)
#else
#define PHYS_OFFSET UL(0x30000000)
#endif
(3)vim arch/arm/mach-s5pv210/include/mach/map.h
#if defined(CONFIG_MACH_SMDKV210)
#define S5PV210_PA_SDRAM (0x30000000)
#else
#define S5PV210_PA_SDRAM (0x30000000)
#endif
#define S5P_PA_SDRAM S5PV210_PA_SDRAM
3)去掉PMIC驱动
make menuconfig时,需要注意的一些配置方法:
[ ] -->只有两个选项:[*] --- Y :将该模块(某个功能、某个驱动)编译到内核映像中
[ ] --- N :编译后的内核源码映像不是用该功能模块
< > -->有三种配置选项: <*> --- Y :将该模块(某个功能、某个驱动)编译到内核映像中
--- M :将该驱动编译成一个独立的模块(*.ko),在内核源码的目录中。而不是在内核映像中。
我们可以将该*.ko拷贝跟文件系统中,使用命令安装驱动:#insmod *.ko
< > --- N :编译后的内核源码映像不是用该功能模块
()-->设置的是树值或者字符串:输入回车--->删掉原来的值-->写入新的值
注意:
1.针对内核配置以后,需要保存配置的内容
scripts/kconfig/mconf arch/arm/Kconfig
#
# configuration written to .config
#
2.在使用make distclean的时候,.config会被删除。所以一般每次配置完以后,需要将.config进行备份。
#cp .config GEC210_defconfig
4)修改nand的分区:
分区后的结果:
[ 1.288695] S3C NAND Driver, (c) 2008 Samsung Electronics
[ 1.293768] S3C NAND Driver is using hardware ECC.
[ 1.298445] NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)
[ 1.307004] Creating 5 MTD partitions on "s5pv210-nand":
[ 1.312284] 0x000000000000-0x000000100000 : "uboot"
[ 1.318097] 0x000000100000-0x000000600000 : "recovery"
[ 1.324370] 0x000000600000-0x000000b00000 : "kernel"
[ 1.329321] 0x000000b00000-0x000000e00000 : "ramdisk"
[ 1.333640] 0x000000e00000-0x000010000000 : "root"
5)移植驱动
LCD驱动(platform模型)
DM9000驱动
蜂鸣器
usb
....
6)编译
注意:
针对SMDKV210平台,主初始化文件:varch/arm/mach-s5pv210/mach-smdkc110.c
针对GEC210平台,主初始化文件:varch/arm/mach-s5pv210/mach-gec210.c
----------------------------------------------------------------------------
5、生成uImage
一般都使用zImage,但是也会使用uImage,uImage是在zImage的前面加了一个64B的头。
1)该64B的头包含的信息????
uboot源码: include/image.h
/*
* Legacy format image header,
* all data in network byte order (aka natural aka bigendian).
*/
typedef struct image_header {
uint32_t
ih_magic;
/* Image Header Magic Number
*/
uint32_t
ih_hcrc;
/* Image Header CRC Checksum
*/
uint32_t
ih_time;
/* Image Creation Timestamp
*/
uint32_t
ih_size;
/* Image Data Size
*/
uint32_t
ih_load;
/* Data
Load Address
*/
uint32_t
ih_ep;
/* Entry Point Address
*/
uint32_t
ih_dcrc;
/* Image Data CRC Checksum
*/
uint8_t
ih_os;
/* Operating System
*/
uint8_t
ih_arch;
/* CPU architecture
*/
uint8_t
ih_type;
/* Image Type
*/
uint8_t
ih_comp;
/* Compression Type
*/
uint8_t
ih_name[IH_NMLEN];
/* Image Name
*/
} image_header_t;
2)如何生成uImage
使用一个工具mkimage,该工具是在uboot源码包中,uboot/tools
在 arch/arm/boot 路径下:
#mkimage -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -n 'linux-2.6.35.7' -d zImage uImage
-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)
-----------------------------------------------------------------------------
6、机器码
针对某一个具体的硬件平台,uboot和kernel都有一个机器码,分别在二者的源码中设置。
需要注意的问题是:二者的机器码必须要一致;否则kernel就不能启动。
1)uboot中,机器码定义的位置:(可以通过环境变量来设置:setenv machid 0x998)
include/configs/smdkv210single.h
#define MACH_TYPE 2456
2)在内核中定义的机器码:通过设备名字找到机器码
在kernel的主初始化文件的最后定义一个machine宏
MACHINE_START(GEC210, "GEC210") //定义了机器的名字:GEC210
.phys_io = S3C_PA_UART & 0xfff00000,
.io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5pv210_init_irq,
.map_io = smdkc110_map_io,
.init_machine = smdkc110_machine_init, //主初始化函数
.timer = &s5p_systimer,
MACHINE_END
该名字(GEC210)会跟一个机器码相关:
arch/arm/tools/mach-types
gec210 MACH_GEC210 GEC210 2456
-----------------------------------------------------------------------------
7、如何在内核的配置菜单中,增加自己配置项。
原理:
kbuild :Kconfig --- 配置菜单(make menuconfig),并且设置一个配置选项CONFIG_xxxxx,该选项的值:Y、M、N
Makefile--- 管理源码的编译过程,根据配置选项(CONFIG_xxxxx)的值(YMN)来确定该源码如何编译?