linux内核启动笔记
一、 1、解压 tar xjf linux-2.6.22.6.tar.bz2
2、打补丁 patch -p1 < ../linux-2.6.22.6_jz2440.patch
3、配置
a. make menuconfig
b. 使用默认的在上面修改 c.使用厂家的配置文件
b:
find -name "*defconfig*"
在/arch/arm/configs找到相似的配置文件 xxx_defconfig
make xxx_defconfig 结果是configuration written to .config make menu config
c: ls config_ok
cp config_ok .config
make menuconfig
make uImage
case 'k': {
strcpy(cmd_buf, "usbslave 1 0x30000000; nand erase kernel; nand write.jffs2 0x30000000 kernel $(filesize)");
run_command(cmd_buf, 0);
break;
}
二、 配置结果 生成config
配置项 CONFIG_DM9000 = Y
grep "CONFIG_DM9000" * -nwR
1.C源码 CONFIG_DM9000 宏来源于include/linux/autoconf.h
2.子目录makefile drivers/net/Makefile
3.include/config/auto.conf
4.include/linux/autoconf.h 定义为1
2: obj-$(CONFIG_DM9000) += dm9000.o
obj-y += xxx.o 为编译到内核
obj-m += yyy.o 最终编译为可加载模块 -》yyy.c->yyy.ko
make uImage 时
a..config-->autoconf.h
b..config-->auto.conf
分析Makefile:第一个文件、链接脚本
a.c b.c 组成一个模块
obi——m +=ab.o
ab-objs := a.o b.o
a.c ->a.o | | -->ab.ko
b.c->b.o
1、子目录下的Makefile
obj-y += xxx.o
obj-m += yyy.o
2、 make uImage --》 arch/arm/Makefile 被包含到顶层Makefile
include $(srctree)/arch/$(ARCH)/Makefile
zImage Image xipImage bootpImage
uImage: vmlinux uImage: vmlinux 头部 + 内核
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
vmlinux-init := $(head-y) $(init-y)
head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
init-y := init/
init-y := $(patsubst %/, %/built-in.o, $(init-y))
= init/built-in.o 把所有init下的文件编译为in.o
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
core-y := usr/
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
core-y := $(patsubst %/, %/built-in.o, $(core-y))
= usr/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
libs-y := lib/
libs-y1 := $(patsubst %/, %/lib.a, $(libs-y))
libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y))
libs-y := $(libs-y1) $(libs-y2)
=lib/built-in.o lib/lib.a drivers-y :
= drivers/built-in.o sound/built-in.o net-y := net//built-in.o
vmlinux-all := $(vmlinux-init) $(vmlinux-main)
vmlinux-lds := arch/$(ARCH)/kernel/vmlinux.lds
第一个文件arch/arm/kernel/head.s
链接脚本arch\arm\kernel/vmlinux.lds
0、判断是否支持这个cpu
1、处理u-boot传入的参数
arch/arm/kernel/head.s u-boot启动内核时传入的机器ID判断是否支持这个单板
2、因为使用地址为虚拟地址说以,建立页表
3、启用mmu
4、跳转到start_kernel 第一个c函数
。
。
。
挂接根文件系统
最终目的:应用程序
__lookup_machine_type:
adr r3, 3b @r3 = address of 3b real address ,phy address
ldmia r3, {r4, r5, r6} @r4 = "."the virtual address of 3b r5 = __arch_info_begin,r6 = __arch_info_end
sub r3, r3, r4 @ get offset between virt&phys
add r5, r5, r3 @ convert virt addresses to
add r6, r6, r3 @ physical address space
__arch_info_begin = .;
*(.arch.info.init)
__arch_info_end = .;
#define MACHINE_START(_type,_name) \
static const struct machine_desc __mach_desc_##_type \
__used \
__attribute__((__section__(".arch.info.init"))) = { \ .nr = MACH_TYPE_##_type, \
.name = _name,
#define MACHINE_END \
};
static const struct machine_desc __mach_desc_S3C2440 \
__used \
__attribute__((__section__(".arch.info.init"))) = { \
.nr = MACH_TYPE_S3C2440, \
.name = SMDK2440,
/* Maintainer: Ben Dooks <ben@fluff.org> */
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100, 0x30000100
.init_irq = s3c24xx_init_irq,
.map_io = smdk2440_map_io,
.init_machine = smdk2440_machine_init,
.timer = &s3c24xx_timer,
};
struct machine_desc {
/* * Note! The first four elements are used
* by assembler code in head-armv.S */
unsigned int nr; /* architecture number */
unsigned int phys_io;/* start of physical io */
unsigned int io_pg_offst; /* byte offset for io * page tabe entry */
const char *name; /* architecture name */
unsigned long boot_params; /* tagged list */
unsigned int video_start; /* start of video RAM */
unsigned int video_end; /* end of video RAM */
unsigned int reserve_lp0 :1; /* never has lp0 */
unsigned int reserve_lp1 :1; /* never has lp1 */
unsigned int reserve_lp2 :1; /* never has lp2 */
unsigned int soft_reboot :1; /* soft reboot */
void (*fixup)(struct machine_desc *, struct tag *, char **, struct meminfo *);
void (*map_io)(void);/* IO mapping function */
void (*init_irq)(void); struct sys_timer *timer; /* system tick timer */
void (*init_machine)(void);
};
setup_arch(&command_line);
setup_command_line(command_line); 处理传到内核阐述
static int __init root_dev_setup(char *line)
{
strlcpy(saved_root_name, line, sizeof(saved_root_name));
return 1;
}
__setup("root=", root_dev_setup);
#define __setup(str, fn) \
__setup_param(str, fn, fn, 0) #define __setup_param(str, unique_id, fn, early) \
static char __setup_str_##unique_id[] __initdata = str; \
static struct obs_kernel_param __setup_##unique_id \
__attribute_used__ \
__attribute__((__section__(".init.setup"))) \
__attribute__((aligned((sizeof(long))))) \
= { __setup_str_##unique_id, fn, early }
obsolete_checksetup
do_early_param
内核启动流程
arch/arm/kernel/head.s
start_kernel
setup_arch //解析u-boot传入的启动参数
setup_command_line //解析u-boot传入的启动参数
parse_early_param
do_early_param
__setup_start到 __setup_end;调用early函数
unknown_bootoption
obsolete_checksetup
__setup_start到 __setup_end;调用非early函数
rest_init
kernel_init
prepare_namespace
mount_root //挂接根文件系统
init_post // 执行应用程序
分析分区
代码里边写死的
grep "\"bootloader"\" * -nR
arch/arm/plat-s3c24xx/common-smdk.c:120: .name = "bootloader",
static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name = "bootloader",
.size = 0x00040000,
.offset = 0,
},
[1] = {
.name = "params",
.offset = MTDPART_OFS_APPEND, //紧接着上一个
.size = 0x00020000,
},
[2] = {
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = 0x00200000,
},
[3] = {
.name = "root",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
}
};
linux内核启动笔记的更多相关文章
- Linux内核启动过程概述
版权声明:本文原创,转载需声明作者ID和原文链接地址. Hi!大家好,我是CrazyCatJack.今天给大家带来的是Linux内核启动过程概述.希望能够帮助大家更好的理解Linux内核的启动,并且创 ...
- linux内核启动以及文件系统的加载过程
Linux 内核启动及文件系统加载过程 当u-boot 开始执行 bootcmd 命令,就进入 Linux 内核启动阶段.普通 Linux 内核的启动过程也可以分为两个阶段.本文以项目中使用的 lin ...
- 【转载】linux内核启动android文件系统过程分析
主要介绍linux 内核启动过程以及挂载android 根文件系统的过程,以及介绍android 源代码中文件系统部分的浅析. 主要源代码目录介绍Makefile (全局的Makefile)bioni ...
- Linux内核启动
Linux内核启动过程概述 Linux的启动代码真的挺大,从汇编到C,从Makefile到LDS文件,需要理解的东西很多.毕竟Linux内核是由很多人,花费了巨大的时间和精力写出来的.而且直到现在,这 ...
- 通过从代码层面分析Linux内核启动来探知操作系统的启动过程
通过从代码层面分析Linux内核启动来探知操作系统的启动过程 前言说明 本篇为网易云课堂Linux内核分析课程的第三周作业,我将围绕Linux 3.18的内核中的start_kernel到init进程 ...
- linux内核启动参数
Linux内核启动参数 Console Options 参数 说明 选项 内核配置/文件 console=Options 用于说明输出设备 tt ...
- Linux内核学习笔记-2.进程管理
原创文章,转载请注明:Linux内核学习笔记-2.进程管理) By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...
- Linux内核学习笔记-1.简介和入门
原创文章,转载请注明:Linux内核学习笔记-1.简介和入门 By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...
- Linux内核启动代码分析二之开发板相关驱动程序加载分析
Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c start_ke ...
随机推荐
- libevent源码安装及Linux自动编译功能总结
这个..那个..后来发现..直接用jumbo就可以安装libevent.不过,学习一些automake的知识还是有好处的. 03机器也安装了. 这几天在阅读libevent源码,发现参考资料是基于li ...
- for循环与for in循环
json是js里的一种数据格式.var obj={a:15,b:8,c:12} json数组对象 var arr=[15,8,12]; 数组alert(obj.a); ---15alert(obj[' ...
- a++累加
<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8&qu ...
- lftp
linux安装FTP工具 lftp及使用教程 来源:网络 发布时间:2013-05-24 15:21 字体:[大 中 小] 点击2510次 linux下可以直接通过FTP命令进行ftp上传下载,不 ...
- vim 空格和换行的删除和替换
%s/\s//g %s/\r//g %s/\n//g 把一个很长的一行按空格分为多行 :%s/ +/\r/g简单解释一下:%s :在整个文件范围查找替换/ :分隔符+ :匹配空格,其中“ ”表 ...
- spring 编程式事务管理和声明式事务管理
编程式事务管理 Spring 的编程式事务管理概述 在 Spring 出现以前,编程式事务管理对基于 POJO 的应用来说是唯一选择.用过 Hibernate 的人都知道,我们需要在代码中显式调用be ...
- easyui datagrid 设置列宽
<script> $(document).ready(function () { alert("sdf"); ...
- Lecture Notes: Macros
原论文链接失效,特在这里保存一份 http://www.apl.jhu.edu/~hall/Lisp-Notes/Macros.html Lisp functions take Lisp values ...
- JBPM工作流入门总结
关于JBPM工作流 1.工作流 工作流是一项分离业务操作和系统流程的技术.工作流由实体(Entity).参与者(Participant).流程定义(Flow Definition).工作流引擎(Eng ...
- 【bzoj1027】合金
[bzoj1027]合金 分析 数形结合+计算几何+Floyd最小环. http://blog.csdn.net/popoqqq/article/details/40539273 虽然这样占大家的很不 ...