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 <[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,
 }
};

时间: 2024-11-03 21:50:14

linux内核启动笔记的相关文章

linux内核启动第二阶段之setup_arch()函数分析-2.6.36

执行setup_arch()函数 回到start_kernel当中,569行,调用setup_arch函数,传给他的参数是那个未被初始化的内部变量command_line.这个setup_arch()函数是start_kernel阶段最重要的一个函数,每个体系都有自己的setup_arch()函数,是体系结构相关的,具体编译哪个体系的setup_arch()函数,由顶层Makefile中的ARCH变量决定: 它首先通过检测出来的处理器类型进行处理器内核的初始化,然后通过 bootmem_init

linux内核启动过程学习总结

下面是学习linux内核启动过程的记录 平台是:powerpc mpc8548 + linux2.6.23 内核 通用寄存器的作用r0 :在函数开始时使用r1 :存放堆栈指针,相当于ia32架构中的esp寄存器r2 :存放当前进程的描述符的地址r3 :存放第一个参数和返回地址r4-r10 :存放函数的参数r11 :用在指针的调用和当前一些语言的环境指针r12 :用于存放异常处理r13 :保留做为系统线程IDr14-r31 :作为本地变量,具有非易失性 Linux启动过程描述 第一步:使用Boot

Linux内核启动及根文件系统载入过程

上接博文<u-boot之u-boot-2009.11启动过程分析> Linux内核启动及文件系统载入过程 当u-boot開始运行bootcmd命令,就进入Linux内核启动阶段.与u-boot类似,普通Linux内核的启动过程也能够分为两个阶段,但针对压缩了的内核如uImage就要包含内核自解压过程了.本文以linux-2.6.37版源代码为例分三个阶段来描写叙述内核启动全过程.第一阶段为内核自解压过程,第二阶段主要工作是设置ARM处理器工作模式.使能MMU.设置一级页表等,而第三阶段则主要为

Linux内核启动及文件系统加载过程

上接博文<u-boot之u-boot-2009.11启动过程分析> 当u-boot开始执行bootcmd命令,就进入Linux内核启动阶段,与u-boot类似,普通Linux内核的启动过程也可以分为两个阶段,但针对压缩了的内核如uImage就要包括内核自解压过程了.本文以项目中使用的linux-2.6.37版源码为例分三个阶段来描述内核启动全过程.第一阶段为内核自解压过程,第二阶段主要工作是设置ARM处理器工作模式.使能MMU.设置一级页表等,而第三阶段则主要为C代码,包括内核初始化的全部工作

Linux内核启动

Linux内核启动过程概述 Linux的启动代码真的挺大,从汇编到C,从Makefile到LDS文件,需要理解的东西很多.毕竟Linux内核是由很多人,花费了巨大的时间和精力写出来的.而且直到现在,这个世界上仍然有成千上万的程序员在不断完善Linux内核的代码.今天我们主要讲解的是Linux-2.6.22.6这个内核版本.说句实话,博主也不确定自己能够讲好今天这个题目,因为这个题目太大太难.但是博主有信心,将自己学会的内容清楚地告诉大家,希望大家也能够有所收获. 1.启动文件head.S和hea

Linux内核启动及加载根文件系统

</pre></h1><p><span style="font-family:KaiTi_GB2312;font-size:18px;">上接博文<<a target=_blank href="http://blog.csdn.net/gqb_driver/article/details/8931775" style="text-decoration: none; font-family: 'Mi

linux内核启动引导过程

linux内核(uImage格式镜像,uImage = zImage_压缩的内核镜像 + 0x40字节大小的uboot格式信息头)的启动过程大体可以分为三个阶段: 第一:内核的自解压过程(汇编+C语言实现) 主要由.arch/arm/boot/compressed对zImage完成解压,并调用call_kernel跳转到下阶段代码. 第二:板级引导阶段(汇编实现) 主要进行cpu和体系结构的检查.cpu本身的初始化以及页表的建立等 第三:通用内核启动阶段(C语言实现:重点分析) 1. 进入ini

Linux内核启动参数

Linux内核启动参数   Console Options                         参数 说明 选项 内核配置/文件   console=Options 用于说明输出设备 ttyn 终端 ttySn[,options], ttyUSB0[,options] 串口uart,io,addr[,options],uart,mmio,addr[,options]&<60;     netconsole=[src-port]@[src-ip]/[dev],[target-por

可执行程序的装载和启动---linux内核学习笔记(七)

内容一:实验报告相关说明 真实姓名 谢润帮 原创作品转载请注明出处  所学课程:<Linux内核分析>MOOC课程   链接:http://mooc.study.163.com/course/USTC-1000029000 内容二:可执行文件的创建(自己本身对这块不熟,是通过查资料来学习的,篇幅有点多) 2.1 预处理阶段 预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行相应的转换,预处理过程还会删除程序中的注释和多余的空白字符. 其中预处理指令主要包括以下四个方面: 2