一、 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 <[email protected]> */
.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,
}
};