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 ...
随机推荐
- 使用Nexus搭建Maven私服
1. 环境搭建 1.1 下载 http://www.sonatype.org/nexus/ NEXUS OSS [OSS = Open Source Software,开源软件--免费] NE ...
- 如何查看与刷新DNS本地缓存
如何查看与刷新DNS本地缓存 一.查看DNS本地缓存 在cmd窗口输入:ipconfig/displaydns 二.刷新DNS本地缓存 在cmd窗口输入:ipconfig/flushdns 之后输入: ...
- go语言中间的循环
在Go语言中只有很少的几个控制结构,它没有while或者do-while循环. 但是它有for.switch.if.而且switch接受像for那样可选的初始化语句.下面来认识一下他们 一.if语句 ...
- matlab灰度变彩色+白平衡算法实现
% matlab彩色图像分离通道并合并成处理后的彩色图像(彩色变灰度再变彩色) % 白平衡算法(灰度世界法)消除RGB受光照影响 clear all; close all; %读入原始图像 srcIm ...
- 【bzoj3625】【xsy1729】小朋友和二叉树
[bzoj3625]小朋友与二叉树 题意 我们的小朋友很喜欢计算机科学,而且尤其喜欢二叉树. 考虑一个含有n个互异正整数的序列c[1],c[2],...,c[n].如果一棵带点权的有根二叉树满足其所有 ...
- ArcGIS 10.3 安装及破解
系统环境:win7 64位操作系统. 一.ArcGIS 10.3包简介 ArcGIS 10.3 下载包含 1. ArcGIS for Desktop ArcGIS for Desktop简介: Ar ...
- HTML5自学笔记[ 15 ]canvas绘图基础6
关于线条的一些属性: lineCap,这个属性表示的是线条两端的样式,值有butt(默认)/round/square. lineJoin,这个属性表示线条相交的方式,值有miter(默认)/bevel ...
- 小例子(一)、MD5加密
一个MD5加密的小案例 代码如下: using System; using System.Text; using CCWin; using System.Security.Cryptography; ...
- 转:怎样在VMware ESXi上 克隆虚拟机
Cloning virtual machines on VMware ESXi 翻译自http://www.dedoimedo.com/computers/vmware-esxi-clone-mach ...
- uva 1639--精度处理方法之取对数(uva 1639)
1639 - Candy Time limit: 3.000 seconds 1639 CandyLazyChild is a lazy child who likes candy very much ...