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 ...
随机推荐
- Mysql插入数据的时候,中文乱码问题的解决
如果在Mysql中插入数据的时候,没有特定指定编码,可能会产生一系列的问题,例如,如果用insert语句的时候,可能提示incorrect values,等...究其原因,实际上无非是要让数据库和表中 ...
- epoll函数与参数总结学习 & errno的线程安全
select/poll被监视的文件描述符数目非常大时要O(n)效率很低:epoll与旧的 select 和 poll 系统调用完成操作所需 O(n) 不同, epoll能在O(1)时间内完成操作,所以 ...
- 基本分类方法——KNN(K近邻)算法
在这篇文章 http://www.cnblogs.com/charlesblc/p/6193867.html 讲SVM的过程中,提到了KNN算法.有点熟悉,上网一查,居然就是K近邻算法,机器学习的入门 ...
- Phoenix - Hbase与SQL
Phoenix - Hbase与SQL 2016-10-23 杜亦舒 Phoenix是什么 简单来说,Phoenix 是一个可以让我们通过SQL的方式操作HBase数据库的框架. HBase是一个No ...
- hdu_2089 不要62
数位动态规划 数位动态规划是求解一个大区间[L, R]中间满足条件Q的所有数字的个数(或者和,或其他)的一种方法.它通过分析每一位上的数字,一般用 dp[len][digit][...] 来表 ...
- OneProxy主从延迟检测
OneProxy具有主从延迟检测功能,检测方式有两种. 1.通过MySQL本身提供的延迟信息,即在从库中执行show slave status; 查看Seconds_Behind_Master值: 2 ...
- 【转】 Linux下的多线程编程
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/原文链接:http://www.cnblogs.com/gnuhpc/archive/2012/12/07/280 ...
- 【CITE】C# 如何 实现一个窗体和另一个窗体始终保持相对的位置
C# 如何 实现一个窗体和另一个窗体始终保持相对的位置,任由一个窗体移动,当点击按钮时,弹出的另一个窗体也与之保持相对位置(如左上角)你根据第一个窗体的location去算第二个窗体的location ...
- Nodejs开发框架Express3.0开发手记–从零开始
转载请注明出处: http://blog.fens.me/nodejs-express3/ 程序代码已经上传到github有需要的同学,自行下载. https://github.com/bsspiri ...
- SqlServer关闭与启用标识(自增长)列
1 --添加新列 2 ALTER TABLE TABLENAME ADD ID int 3 --赋值 4 UPDATE TABLENAME SET ID = IDENTITY_ID 5 --删除标识列 ...