内核启动流程分析(一)编译体验

目录

2.打补丁

3.配置

总结

配置方式

配置体验

4.编译

链接

链接脚本

5.烧写内核


1.总体概述 

2.打补丁

  1. 解压 tar xjf linux-2.6.22.6.tar.bz2
  2. 打补丁,cat下补丁文件知道需要忽略第一个/ patch -p1 < linux-2.6.22.6_jz2440.patch
  3. 打包下生成的文件tar cjvf linux2.6.22_ok.tar.bz2 linux-2.6.22.6

3.配置

总结

  1. .config通过make自动生成autoconf.hauto.conf
  2. 源代码中通过autoconf.h决定代码编译,无论配置为m或者y都编译,因为头文件都定义为1
  3. 子目录的makefile通过auto.conf中的y/m决定编译为模块.ko还是编译到内核.这个文件是被顶层的Makefile包含

配置方式

配置有三种方法:

1、make menuconfig 每一项都配置,非常多的选项,图形界面配置

mark

2、使用默认配置后执行make menuconfig

        ①查看下默认配置,使用find -name "*defconfig*"搜索,找到很多配置文件,比如在arch/arm下有文件夹configs保存默认配置

./arch/arm/configs/realview_defconfig
./arch/arm/configs/hackkit_defconfig
./arch/arm/configs/lpd270_defconfig
.......
./arch/arm/configs/s3c2410_defconfig

      ②进入这个目录查看下相关的config,发现 s3c2410_defconfig与我们的单板最为接近

cd arch/arm/configs/
ls
make s3c2410_defconfig

     ③使用对应的最接近的默认配置make s3c2410_defconfig

     ④执行 make menuconfig.最后提示所有配置项目写入.config

book@book-desktop:~/stu/kernel/linux2.6/linux-2.6.22.6$ make s3c2410_defconfig
drivers/serial/Kconfig:235:warning: multi-line strings not supported
.......
#
# configuration written to .config
#

      ⑤如果报错,则是因为make版本过新

book@book-vm:~/work/linux-2.6.22.6$ make s3c2410_defconfig
Makefile:416: *** mixed implicit and normal rules: deprecated syntax
Makefile:1449: *** mixed implicit and normal rules: deprecated syntax
make: *** No rule to make target 's3c2410_defconfig'。 停止。

原因:是由于我的系统的make工具太新,make的旧版规则已经无法兼容新版。

1.在makefile中将416行代码
config %config: scripts_basic outputmakefile FORCE
改为
%config: scripts_basic outputmakefile FORCE
2.在makefile中将1449行代码
/ %/: prepare scripts FORCE
改为
%/: prepare scripts FORCE

3、使用厂家提供的配置config_ok,直接复制为名为.config,即cp config_ok .config,再执行 make menuconfig实际上方式2最终也是产生这个.config文件,make menuconfig使用到这个.config文件。

配置体验

输入Y编译进内核
输入N 不包含
输入M编译为模块,所谓模块就类似于驱动,可以后置加载
输入?进入查看具体的配置项
输入 / 搜索

比如我们配置网络DM9000,按下图进入配置

mark

mark

mark

mark

4.编译

uboot启动的是uImage格式的linux kernel, 就是带有头部信息的程序文件

make uImage

从编译流程分析下编译过程

rm vmlinux #先删除
make uImage V=1  # V=1 表示更加详细显示命令

摘录下最后的日志记录

链接

文件的顺序在外部定义.第一个文件为arch/arm/kernel/head.o,具体的段由链接脚本决定.这个链接命令实际也是存在.vmlinux.cmd中的

  arm-linux-ld -EL  -p --no-undefined -X -o vmlinux -T arch/arm/kernel/vmlinux.lds arch/arm/kernel/head.o arch/arm/kernel/init_task.o  init/built-in.o --start-group  usr/built-in.o  arch/arm/kernel/built-in.o  arch/arm/mm/built-in.o  arch/arm/common/built-in.o  arch/arm/mach-s3c2410/built-in.o  arch/arm/mach-s3c2400/built-in.o  arch/arm/mach-s3c2412/built-in.o  arch/arm/mach-s3c2440/built-in.o  arch/arm/mach-s3c2442/built-in.o  arch/arm/mach-s3c2443/built-in.o  arch/arm/nwfpe/built-in.o  arch/arm/plat-s3c24xx/built-in.o  kernel/built-in.o  mm/built-in.o  fs/built-in.o  ipc/built-in.o  security/built-in.o  crypto/built-in.o  block/built-in.o  arch/arm/lib/lib.a  lib/lib.a  arch/arm/lib/built-in.o  lib/built-in.o  drivers/built-in.o  sound/built-in.o  net/built-in.o --end-group .tmp_kallsyms2.o


#-T arch/arm/kernel/vmlinux.lds 
arch/arm/kernel/head.o 
arch/arm/kernel/init_task.o
#这个与makefile中的是对应的
vmlinux-init := $(head-y) $(init-y)
head-y      := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o

链接脚本

arch/arm/kernel/,文件里面的段按照顺序,比如代码段是先放.text.head,**一开始是放“ *”(指所有文件)的 “ .text.head”段。**再放init,文件的顺序由外部决定. 链接脚本 vmlinux.lds 是由 vmlinux.lds.S 文件生成的。

SECTIONS
{

 . = (0xc0000000) + 0x00008000;     #这个是虚拟地址

 .text.head : {                     #先放所有文件的 .text.head 段
  _stext = .;
  _sinittext = .;
  *(.text.head)
 }

 .init : { /* Init code and data        */ #再接着是放所有文件的“ .init.text”段。
   *(.init.text)
  _einittext = .;
  __proc_info_begin = .;
   *(.proc.info.init)
  __proc_info_end = .;
  __arch_info_begin = .;
   *(.arch.info.init)
  __arch_info_end = .;
  __tagtable_begin = .;
   *(.taglist.init)
  __tagtable_end = .;
  . = ALIGN(16);
  __setup_start = .;
   *(.init.setup)
  __setup_end = .;
  __early_begin = .;
   *(.early_param.init)
  __early_end = .;
  __initcall_start = .;
   *(.initcall0.init) *(.initcall0s.init) *(.initcall1.init) *(.initcall1s.init) *(.initcall2.init) *(.initcall2s.init) *(.initcall3.init) *(.initcall3s.init) *(.initcall4.init) *(.initcall4s.init) *(.initcall5.init) *(.initcall5s.init) *(.initcallrootfs.init) *(.initcall6.init) *(.initcall6s.init) *(.initcall7.init) *(.initcall7s.init)
  __initcall_end = .;
  __con_initcall_start = .;
   *(.con_initcall.init)
  __con_initcall_end = .;
  __security_initcall_start = .;
   *(.security_initcall.init)
  __security_initcall_end = .;

  . = ALIGN(32);
  __initramfs_start = .;
   usr/built-in.o(.init.ramfs)
  __initramfs_end = .;

  . = ALIGN(4096);
  __per_cpu_start = .;
   *(.data.percpu)
  __per_cpu_end = .;

  __init_begin = _stext;
  *(.init.data)
  . = ALIGN(4096);
  __init_end = .;

 }

5.烧写内核

编译完成后在/linux-2.6.22.6/arch/arm/boot生成uImage,在uboot下输入k进入烧写,使用dnw烧写程序,具体的k实现了什么命令,查看下uboot代码,在cmd_menu.c定义

strcpy(cmd_buf, 

"usbslave 1 0x30000000; nand erase kernel; 
nand write.jffs2 0x30000000 kernel $(filesize)");

run_command(cmd_buf, 0);

然后就可以通过b启动

转载:https://www.cnblogs.com/zongzi10010/p/10023694.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值