您的位置:首页 > 其它

S5PV210的kernel移植

2015-10-17 14:19 411 查看
1、先熟悉源码目录结构

2、然后通过源码分析,熟悉kernel执行过程

3、尝试进行修改添加kernel

kernel移植初体验

1)进入源码目录,在linux下解压,因为在windows下解压,会出现相同文件提示覆盖那些,因为windows不区分大小写,而且还有一些链接文件在。

2)修改 Makefile 中的体系结构 ARCH 和交叉编译器前缀 CROSS_COMPILE

vim Makefile

修改 191 和 192 行为如下:

ARCH ?= arm

CROSS_COMPILE ?= /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-

3)使用 SMDKV210 的缺省配置文件

make arch/arm/configs/smdkv210_android_defconfig

若出现找不到 smdkv210_android_defconfig,则执行如下操作

cp arch/arm/configs/smdkv210_android_defconfig .config

make smdkv210_android_defconfig

4) 配置内核,修改串口

make menuconfig

若出现*** Unable to find the ncurses libraries or the 错误,则执行

解决方法:sudo apt-get install libncurses5-dev

修改底层消息和底层调试串行端口为 UART0:

System Type --->

(0) S3C UART to use for low-level messages

Kernel hacking --->

(0) S3C UART to use for low-level debug

通常要配的是:内核输出串口,对应的开发板型号

关于NAND flash分区,参考:
http://blog.chinaunix.net/uid-30227644-id-4993889.html http://blog.csdn.net/yjp19871013/article/details/6933455 http://blog.chinaunix.net/uid-25119314-id-351866.html
5) 确定机器码

vim arch/arm/tools/mach-types

在 433 行可以看出,SMDKV210 评估板的机器码是 2456(16 进制是 0x998) :

2433 smdkv210 MACH_SMDKV210 SMDKV210 2456

6) 确定内核的加载地址和参数地址

vim arch/arm/mach-s5pv210/Makefile.boot

可以看出,内核的加载地址和参数地址分别为 0x20008000 和 0x20000100,bootloader

启动内核前应该将内核拷贝到 0x20008000,并将参数放到 0x20000100。

zreladdr-y += 0x20008000

params_phys-y := 0x20000100

7) 编译内核

make uImage -j 2

-j 2 指定了编译时的线程数,使用 2 个线程可加快编译的速度

注意:如果出错:没法生成uImage

拷贝mkimage到linux的/sbin /bin 即可。

mkimage是把zImage生成uImage

内核的加载地址的确是 0x20008000,进入点地址也是 0x20008000,u-boot

支持的Linux内核映像uImage也可用了,否则不会进入到内核执行,引导不成功,

需要结合uboot里的设置而定。

如果内核启动出现这样的错误:can't run '/etc/init.d/rcS': No such file or directory;请用

vi 把/etc/init.d/rcS 文件中的乱码“^M”删掉。

进行简单源码分析

顶层makfile 执行make menuconfig

1.创建两个目录

mkdir -p include/linux include/config

2.进入scritps/kconfig目录下,编译出mconf

menuconfig: scripts/kconfig/mconf

3.直接执行mconf,并且将arch/arm/Kconfig当做参数送给mconf

然后mconf arch/arm/Kconfig到底做了什么?

1)画出可操作的菜单界面

2)界面可以交互

3)所有的界面操作是可以保存到.config文件

可以尝试自定义一个菜单。

实例:1

1、菜单的创建

# vim arch/arm/Kconfig

menu "hello world"

endmenu

保存退出,重新执行

#make menuconfig

看看有什么变化?只是生成了一个简单的菜单,里面没有选项。

2、选项的添加

在menu与endmenu之间加入以下代码

config HELLO

bool "hello"

default y

保存退出,重新执行

#make menuconfig

看下有什么变化

实例:2

1、修改源码

#vim arch/arm/kconfig

在文件的开头,添加发下内容

menu "helloworld"

source "helloworld/Kconfig"

endmenu

2、增加下级kconfig

在顶层的目录下,创建测试目录:

#mkdir helloworld

#vim helloworld/Kconfig

添加如下内容:

config HELLO

tristate "printf hello"

default y

---help---

Printf something such of gec210_hello

config WORLD

tristate "printf world"

default y

---help---

Printf something such of gec210_hello

保存退出。

3、执行make menuconfig

看一下是否出现相应的内容。

再看.config

实例3:

1、在顶层makefile中添加

drivers-y := drivers/ sound/ firmware/ helloworld/

2、在二级目录中添加makefile

#cd helloworld/

添加以下内容:

obj-$(CONFIG_HELLO) += hello.o

obj-$(CONFIG_WORLD) += world.o

保存退出。

3、添加源代码

#vim hello.c

添加以下内容

#include <linux/kernel.h>

int test_hello(void)

{

printk(">>>>>>>>>>>>>>>>>>>>>> hi,hello <<<<<<<<<<<<<<<<<<\n");

return 0;

}

保存退出。

同理创建world.c

#include <linux/kernel.h>

int test_world(void)

{

printk(">>>>>>>>>>>>>>>>>>>>>> hi,world <<<<<<<<<<<<<<<<<<\n");

return 0;

}

内核启动过程分析

顶层Makefile

arch/arm/kernel/head.S

arch/arm/kernel/head-common.S

...

arch/arm/kernel/vmlinux.lds

ENTRY(stext) // 代码入口

setmode
PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9

1.查看是否支持处理器编号

mrc p15, 0, r9, c0, c0
@ 处理器的ID号

bl __lookup_processor_type
@ r5=procinfo r9=cpuid

movs r10, r5
@ invalid processor (r5=0)?

beq __error_p
@ yes, error 'p'

2.查看是否支持机器编号

bl __lookup_machine_type
@ r5=machinfo

movs r8, r5
@ invalid machine (r5=0)?

beq __error_a
@ yes, error 'a'

3.获取启动参数 bootargs

bl __vet_atags

4.创建页表

bl __create_page_tables

5.

ldr r13, __switch_data

.long __mmap_switched

__mmap_switched:

.....

b start_kernel
// init/main.c

start_kernel:

/* 详细的各个模块的初始化 */

setup_arch(&command_line);

sched_init();

init_IRQ();

init_timers();

......

console_init();
// 控制台初始化

.....

/* 创建两个方向的线程 */

rest_init();

kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);

kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);

kernel_init // 用于启动1号进程 init

kthreaddd // 内核进程的管理线程

schedule();

cpu_idle();

kernel_init

1. 驱动部分初始化

do_basic_setup();

2. rootfs的控制台初始化

if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)

printk(KERN_WARNING "Warning: unable to open an initial console.\n");

(void) sys_dup(0);

(void) sys_dup(0);

3.挂载文件系统到dram

prepare_namespace();

mount_root();

4.启动1号进程

init_post();

run_init_process("/sbin/init");

总结:

1、arch/arm/kernel/head.S是第一个文件,总的入口就在这个文件

2、uImage是uboot专用的镜像文件,它是在zImage之前加上一个长度为0x40的头信息(tag),

在头信息内说明了该镜像文件的类型、加载 位置、生成时间、大小等信息.换句话说,若直接从uImage的0x40位置开始执行,则zImage和uImage没有任何区别

启动方式不一样

手动启动:tftp 40000000 zImage ;go 0x40000000

自动启动:tftp 40000000 uImage ;bootm 0x40000000

注意:

1、机器码对应

只要保持两个文件(u­boot的board/fs2410/fs2410.c与linux内核的arch/arm/machs3c2410/mach­smdk2410.c)参照对象的码值一样就可以了!

2、启动到kernel starting ...停止的话,参考:
http://www.linuxidc.com/Linux/2011-04/34796.htm http://blog.sina.com.cn/s/blog_6340cd9c010106pu.html http://www.mcuzone.com/bbs/simple/?t9071.html http://www.aichengxu.com/view/38299
3、如果编译出的是zImage转为uImage就在内核源码的arch/arm/boot/下执行如下命令

mkimage -A arm -O linux -T kernel -C none -a 20008000 -e 20008000 -n xxkernel -d zImage uImage

注意-a 和-e

二是在性能微调选项选择tab键补全功能。 ->Busybox Settings ->Busybox library Tuning ->Command line editing ->Tab completion

4、编译内核或uboot时

lib/asm-offsets.c:1: error: bad value (armv4) for -mtune= switch

make[1]: *** [lib/asm-offsets.s] Error 1

没有指定交叉编译工具链。设置环境变量,或者make时带上CROSS_COMPILE参数。如make CROSS_COMPILE=arm-none-linux-gnueabi-
http://bbs.csdn.net/topics/390769229
5、有内核启动信息输出终端后,如果到最后说5秒自动重启,可能是因为没有移植LCD驱动,而且保证下有文件系统在。

内核移植完之后,有些还需要一些接口模块功能的移植。

还要检查下u-boot的环境变量bootargs启动参数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: