Linux-arm底层启动流程简介
ARM的启动过程详解
基于arm的芯片多数为复杂的片上系统,这种复杂系统里的多数硬件模块都是可配置的,需要由软件来设置其需要的工作状态。
因此在用户的应用程序之前,需要由专门的一段代码来完成对系统的初始化。
由于这类代码直接面对处理器内核和硬件控制器进行编程,一般都是用汇编语言。
一般通用的内容包括:中断向量表初始化存储器系统初始化堆栈初始化有特殊要求的断口,设备初始化用户程序执行环境改变处理器模式呼叫主应用程序中断向量表arm要求中断向量表必须放置在从0地址开始,连续8X4字节的空间内。
每当一个中断发生以后,arm处理器便强制把PC指针置为向量表中对应中断类型的地址值。
因为每个中断只占据向量表中1个字的存储空间,只能放置一条arm指令,使程序跳转到存储器的其他地方,再执行中断处理。
中断向量表的程序实现通常如下表示:AREA Boot,CODE,READONLYENTRYB ResetHandlerB UndefHandlerB SWIHandlerB PreAbortHandlerB DataAbortHandlerBB IRQHandlerB FIQHandler其中关键字ENTRY是指定编译器保留这段代码,因为编译器可能会认为这是一段亢余代码而加以优化。
链接的时候要确保这段代码被链接在0地址处,并且作为整个程序的入口。
初始化存储器系统存储器类型和时序配置通常Flash和SRAM同属于静态存储器类型,可以合用同一个存储器端口;而DRAM因为有动态刷新和地址线复用等特性,通常配有专用的存储器端口。
存储器端口的接口时序优化是非常重要的,这会影响到整个系统的性能。
因为一般系统运行的速度瓶颈都存在于存储器访问,所以存储器访问时序应尽可能的快;而同时又要考虑到由此带来的稳定性问题。
存储器地址分布一种典型的情况是启动ROM的地址重映射。
初始化堆栈因为arm有7种执行状态,每一种状态的堆栈指针寄存器(SP)都是独立的。
因此,对程序中需要用到的每一种模式都要给SP定义一个堆栈地址。
arm的启动过程
arm的启动过程ARM是一种广泛应用于嵌入式系统和移动设备的处理器架构。
在学习ARM的过程中,了解其启动过程是非常重要的。
本文将详细介绍ARM的启动过程。
ARM的启动过程可以分为四个主要阶段:复位阶段、启动阶段、初始化阶段和操作系统启动阶段。
在复位阶段,当ARM处理器上电或者接收到复位信号时,它会进入复位状态。
在这个阶段,处理器会初始化一些重要的寄存器,例如程序计数器(PC)和堆栈指针(SP)。
此外,处理器还会加载一些固定位置的向量表,这些向量表包含了处理器在不同中断或异常发生时所需要执行的代码。
接下来是启动阶段,处理器会根据向量表中指定的地址跳转到相应的启动代码。
启动代码的任务是设置处理器的工作模式和时钟频率。
在这个阶段,处理器会切换到特权模式,例如特权模式(SVC),以便能够访问特权指令和寄存器。
同时,处理器还会根据外部存储器中的配置信息来设置时钟频率,以确保处理器能够正常工作。
进入初始化阶段后,处理器会执行一系列初始化代码,包括初始化外部存储器、初始化外设和设置中断控制器等。
在这个阶段,处理器会根据配置信息初始化外部存储器,例如SDRAM或Flash存储器。
同时,处理器还会初始化外设,例如串口、GPIO和定时器等,以便与外部设备进行通信。
此外,处理器还会设置中断控制器,以便处理外部中断信号。
最后是操作系统启动阶段,在这个阶段,处理器会加载操作系统的启动代码,并跳转到操作系统的入口地址。
操作系统的启动代码会进一步初始化系统资源,例如内存管理单元(MMU)、进程管理和设备驱动等。
一旦操作系统初始化完成,处理器就可以开始执行操作系统的任务调度和应用程序的执行。
总结起来,ARM的启动过程包括复位阶段、启动阶段、初始化阶段和操作系统启动阶段。
在这个过程中,处理器会进行一系列的初始化操作,包括设置寄存器、加载向量表、设置工作模式和时钟频率、初始化外部存储器和外设、设置中断控制器以及加载操作系统的启动代码。
Arm_linux_启动分析
Arm linux 启动分析(1)王利明 walimi@ 宋振宇zhenyusong@ 2003-3-201.概述:在内核运行之前需要系统引导程序(Bootloader)完成加载内核和一些辅助性的工作,然后跳转到内核代码的起始地址并执行。
本文先分析了Bootloader 的初始化工作,接着从内核镜像的起始地址进行分析。
整个arm linux 内核的启动可分为三个阶段:第一阶段主要是进行cpu 和体系结构的检查、cpu 本身的初始化以及页表的建立等;第二阶段主要是对系统中的一些基础设施进行初始化;最后则是更高层次的初始化,如根设备和外部设备的初始化。
第一阶段的初始化是从内核入口(ENTRY(stext))开始到start_kernel 前结束。
这一阶段的代码在/arch/arm/head_armv.S 中。
2.Bootloader 2.1简介 本处介绍主要来自内核源代码下的Documentation/arm/Booting 文件,适合于arm linux 2.4.18-rmk6及以上版本。
Bootloader 主要作用是初始化一些必要的设备,然后调用内核,同时传递参数给内核。
主要完成如下工作:1. 建立和初始化RAM 。
2. 初始化一个串口。
3.4.建立内核的5. 调用内核镜像。
2.2功能详细介绍 1.建立和初始化RAM 。
要求:必须功能:探测所有的RAM 位置和大小,并对RAM 进行初始化。
2.初始化一个串口。
要求:可选,建议功能:Bootloader 应该初始化并启动一个串口。
这可以让内核的串口驱动自动探测哪个串口作为内核的控制台。
另外也可以通过给内核传递“console=”参数完成此工作。
3.检测机器的系统结构。
要求:必须功能:Bootloader 应该通过某种方法探测机器类型,最后传递给内核一个MACH_TYPE_xxx 值,这些值参看4要求:必须功能:Bootloader 必须创建和初始化内核的tagged list 。
Linuxarm底层启动流程简介
Linux开发驱动底层环境启动流程Uboot编译:rm -rf 删除命令tar xjf 解压uboot文件patch -p1 < ../u-boot-1.1.6.jz2440.patch 打补丁 -p1 指示忽略第一个斜杠前因为已经在当前目录。
打好补丁之后配置文件make 100ask24x0_config之后make配置文件是厂家提供好的。
Make后生成bin文件,在Windows下进入oflash目录烧写这个文件。
选择Open jtag S2C2440 nand flash 0块0 2 0 0 0这几个数字烧写之后进入启动界面之后uboot命令按help查看支持哪些命令。
?Md 查看 md命令Print 命令查看环境变量设置环境变量 set xxxx xx savereset重启Uboot 的终极目的就是要启动内核。
Make config 就相当于执行命令100ask24x0_config : unconfig@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0NULL s3c24x0MKCONFIG := $(SRCTREE)/mkconfig$(@:_config=) $(@ 表示目标文件100ask24x0 _config=) 表示替换掉他用后面的arm arm920t 100ask24x0 NULL s3c24x0 100ask24x0最后就执行这个命令Mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0找到脚本文件mkconfig #!/bin/sh表示他是用bin目录下sh解释执行,后面是传入的参数。
这个配置过程它做了一些连接工作,把arm board arch 链接到现在的文件。
编译时的make 做的工作:用到了上面配置的config.mk(.a文件表示所有编译好的文件打包成成的一个库)OBJS = cpu/arm920/xxxxLib +=xxxx.aALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)依赖$(obj)u-boot.bin文件$(obj)u-boot.bin他又依赖于$(obj)u-boot: depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \-Map u-boot.map -o u-boot得到的bin文件就是这个.a文件如何组织连接在lds连接文件有说明链接地址在0x33f80000就是说应该在这个地址运行比如从0x00000000 到0x08000000是128M空间2^27次方=2^7*2^10*2^10=128M搜索命令 grep “” - nR内存一共64M0x33f80000空出512KUBOOT做一些工作:进入管理模式、关看门狗中断、初始化存储控制器、设置栈IRQFIQ、重定位(NORflash不能像内存一样写)、从flash拷到sdram、到他该运行的地址0x33f80000、清BSS段、调用C函数从上往下依次是512K UBOOT 然后是用来实现malloc接下来是全局参数,在接下来就是各种模式的栈。
arm版本linux系统的启动流程
arm版本linux系统的启动流程ARM架构是一种常见的处理器架构,被广泛应用于嵌入式设备和移动设备中。
在ARM版本的Linux系统中,启动流程是非常重要的,它决定了系统如何从开机到正常运行。
本文将详细介绍ARM版本Linux系统的启动流程。
一、引导加载程序(Bootloader)引导加载程序是系统启动的第一阶段,它位于系统的固化存储器中,比如ROM或Flash。
在ARM版本的Linux系统中,常用的引导加载程序有U-Boot和GRUB等。
引导加载程序的主要功能是加载内核镜像到内存中,并将控制权转交给内核。
二、内核初始化引导加载程序将内核镜像加载到内存后,控制权被转交给内核。
内核初始化是系统启动的第二阶段,它主要完成以下几个步骤:1. 设置异常向量表:ARM架构中,异常是指硬件产生的中断或故障,比如系统调用、中断请求等。
内核需要设置异常向量表,以便正确处理异常。
2. 初始化处理器:内核对处理器进行初始化,包括设置页表、启用缓存、初始化中断控制器等。
3. 启动第一个进程:内核创建第一个用户进程(一般是init进程),并将控制权转交给它。
init进程是系统中所有其他进程的父进程,负责系统的初始化工作。
三、设备树(Device Tree)设备树是ARM版本Linux系统中的一种机制,用于描述硬件设备的相关信息。
在内核初始化过程中,内核会解析设备树,并建立设备树对象,以便后续的设备驱动程序使用。
设备树描述了硬件设备的类型、地址、中断等信息,以及设备之间的连接关系。
它使得内核能够在运行时自动识别和配置硬件设备,大大提高了系统的可移植性和灵活性。
四、启动初始化(Init)启动初始化是系统启动的第三阶段,它是用户空间的第一个进程(init进程)接管系统控制权后的操作。
启动初始化主要完成以下几个任务:1. 挂载根文件系统:启动初始化会挂载根文件系统,使得用户可以访问文件系统中的文件和目录。
2. 加载系统服务:启动初始化会加载并启动系统服务,比如网络服务、日志服务、时间同步服务等。
ARMLinux启动过程分析(1).
ARM Linux启动过程分析(1)摘要:嵌入式 Linux 的可移植性使得我们可以在各种电子产品上看到它的身影。
对于不同体系结构的处理器来说Linux的启动过程也有所不同。
本文以S3C2410 ARM处理器为例,详细分析了系统上电后 bootloader的执行流程及 ARM Linux的启动过程。
关键词:ARM Linux bootloader 启动过程Abstract:We can see embedded Linux in kinds of electronic productsb ecause of its portability. Linux’s start-up procedure for different processors is also different. This paper provides the analysis ofbootloader execution process and Linux kernel start-up procedure - taking the S3C2410 ARM processor as example. Keywords: ARM Linux bootloader start-up procedure 1. 引言 Linux 最初是由瑞典赫尔辛基大学的学生 Linus Torvalds在1991 年开发出来的,之后在 GNU的支持下,Linux 获得了巨大的发展。
虽然 Linux 在桌面 PC 机上的普及程度远不及微软的Windows 操作系统,但它的发展速度之快、用户数量的日益增多,也是微软所不能轻视的。
而近些年来 Linux 在嵌入式领域的迅猛发展,更是给 Linux 注入了新的活力。
一个嵌入式 Linux 系统从软件角度看可以分为四个部分:引导加载程序(bootloader), Linux 内核,文件系统,应用程序。
其中bootloader是系统启动或复位以后执行的第一段代码,它主要用来初始化处理器及外设,然后调用 Linux 内核。
ARM体系架构下的linux启动之一,从bootloader到linux内核
ARM体系架构下的linux启动之一,从bootloader到linux内核1. bootloader 的启动bootloader 本身叫做嵌入式系统的引导程序。
但是,它支持X86,MIPS,PowerPC,ARM 等多种体系架构。
对于操作系统的启动来讲,当机器开始上电时,首先加载bootloader,它用来完成最基本的硬件的初始化,然后加载Linux 内核。
用于ARM 的bootloader 一般为U-BOOT,用它来完成对linux 内核的加载设置,一般bootloader 烧写在开发板的Flash 里,包括Nor Flash 或Nand Flash,其中由于NorFlash 支持芯片内执行XIP(eXcute In Place),代码可以直接在FLASH 上执行,而NandFlash 需要把代码拷到RAM 中再去执行。
但是RAM 的处理速度比Flash 的处理速度要快得多,一般仍然把代码放在RAM 中执行。
一般的bootloader 需要完成以下五种功能:1)RAM 的初始化:为调用linux 内核做准备。
2)串口的初始化:由于一般的嵌入式系统开发板上没有视频终端,只能用串口进行开发,串口的初始化非常重要。
3)检测处理器类型:用来预处理加载内核的处理器类型的传递工作。
4)设置Linux 的启动参数:包括加载地址,启动方式(从本地分区或NFS 进行根文件系统加载),以及Linux 根文件系统的加载方式。
通常用一个标记列表来记录linux 内核启动的各个参数。
5)调用linux 内核镜像:此时ARM 的处理器中的几个特殊的寄存器值:r0=0,r1=处理器类型,r2=标记列表在RAM 中的位置。
2. linux kernel 的启动分析。
ARM-Linux内核移植之(一)——内核启动流程分析
ARM-Linux内核移植之(一)——内核启动流程分析Y-Kee转载请注明来自于衡阳师范学院08电2 Y-Kee /ayangke, QQ:843308498内核版本:2.6.22 为什么要采用这样一个较低的版本进行移植了,因为韦东山大牛说了,低版本的才能学到东西,越是高版本需要移植时做的工作量越少,学的东西越少。
内核启动分为三个阶段,第一是运行head.S文件和head-common.S,第三个阶段是允许第二是运行main.c文件对于ARM的处理器,内核第一个启动的文件是arc/arm/kernel下面的head.S文件。
当然arc/arm/boot/compress下面也有这个文件,这个文件和上面的文件略有不同,当要生成压缩的内核时zImage时,启动的是后者,后者与前者不同的时,它前面的代码是做自解压的,后面的代码都相同。
我们这里这分析arc/arm/kernel下面的head.S文件。
当head.S所作的工作完成后它会跳到init/目录下跌的main.c的start_kernel函数开始执行。
第一阶段:首先截取部分head.S文件,将后面重点要分析的代码高亮显示。
ENTRY(stext)msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode@ and irqs disabledmrc p15, 0, r9, c0, c0 @ get processor idbl __lookup_processor_type @ r5=procinfo r9=cpuidmovs r10, r5 @ invalid processor (r5=0)?beq __error_p @ yes, error 'p'bl __lookup_machine_type @ r5=machinfomovs r8, r5 @ invalid machine (r5=0)?beq __error_a @ yes, error 'a'bl __create_page_tables/** The following calls CPU specific code in a position independent* manner. See arch/arm/mm/proc-*.S for details. r10 = base of* xxx_proc_info structure selected by __lookup_machine_type* above. On return, the CPU will be ready for the MMU to be* turned on, and r0 will hold the CPU control register value.*/ldr r13, __switch_data @ address to jump to after@ mmu has been enabledadr lr, __enable_mmu @ return (PIC) address第一步,执行的是__lookup_processor_type,这个函数是检查处理器型号,它读取你的电路板的CPU型号与内核支持的处理器进行比较看是否能够处理。
Linux_arm_启动_c语言部分详解
//这个变量初始值为"h",如果这里设置成 softboot,它会将这个初始值变为"s" if (mdesc->soft_reboot)
reboot_setup("s");
//boot_params 如果为 0 则表示 bootloader 没有传参数 //一般默认为 0x30000100 位置,我们代码也是填的这个位置,4020 的 uboot 当然也要指定这个位置
//就是查找你是什么版本的处理器架构,最后就是调用 //了 lookup_processor_type 这个函数,它在汇编部分也提到过 setup_processor();
//machine_arch_type 就 是 我 们 的 机 器 号 0xc2 , 这 里 就 是 通 过 调 用 lookup_machine_type 函数来得到我们在 4020.c 中写的那个 machine_start 的结构 体。
if (tags->hdr.tag != ATAG_CORE) tags = (struct tag *)&init_tags;
if (mdesc->fixup) mdesc->fixup(mdesc, tags, &from, &meminfo);
//是通过标签 0x544100**来辨别的,因此 uboot 中有相应的标签字 if (tags->hdr.tag == ATAG_CORE) {
saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
// 分析 command line,看这个函数的代码你会发现为什么我们的 command line 不同参数之间是通过空格来分开,同一参数之间的不同值是通过逗号来区分
Arm启动流程解析
Arm启动流程解析谈到arm 的启动流程不得不说的是bootloader,但是我这篇文章主要来谈谈arm 启动流程的,所以bootloader 只是跟大家简介一下就ok。
这篇文章我会谈到以下内容:1、bootloader 简介以及其作用2、2440、6410、210 当下比较常见的3 款处理器的启动流程进行简单分析,通过这三款处理器的分析希望大家掌握arm 处理器的启动分析。
Ok 我们进入主题lBootloader 简介及其作用在我看来bootloader 的作用是初始化必要的硬件,引导内核启动。
(当然这是主要作用,今天的重点不在bootloader,所以在我后面的博文会继续谈到的)l 启动流程分析在分析启动流程的时候我们将会使用的文档是三星公司提供的芯片手册,通过手册我们搞清楚芯片的启动。
在分析启动流程之前我们首先要清楚不论是arm 的何种处理器,其都是从0x0 0 地址处开始执行程序的。
下面的分析我将会通过三个方面:1、芯片支持的启动方式2、地址布局3、启动流程1.2440a)启动方式由上图可知,S3C2440 支持两种启动模式:NAND 和非NAND(这里是Nor Flash),具体采用的方式取决于OM0、OM1 两个引脚的状态。
b)地址布局我们知道arm 从0 地址出运行代码那么我们的零地址处到底存放的是什么东西呢?我们通过地址布局图来分析从上图我们可以清楚的看到左边的是从Nor Flash 启动的地址布局,右边是从NAND 启动的地址布局,因为Nor Flash 内可以运行程序,所以我们在放bootloader 的时候放在0 地址处即可,所以我们重点分析从NAND 启动。
c)启动流程我们从地址布局图中可以看到,当我们从NAND 启动的时候0 地址处是BootSRAM(又叫做stepping stone 垫脚石),当我们上电时其会做以下事情1.上电后处理器自动将nandflash 前4KB的内容到boot sram 开始执行(由硬件完成)。
ARMlinux启动分析-Nathan.Yu的专栏-CSDN博客
ARMlinux启动分析-Nathan.Yu的专栏-CSDN博客linux启动分析(1)---bootloader启动内核过程我分析的是2.4.19的内核版本,是xscale的平台,参考了网上很多有价值的帖子,也加入了自己的一些看法,陆续总结成文字,今天是第一篇:内核一般是由bootloader来引导的,通过bootloader启动内核一般要传递三个参数,第一个参数放在寄存器0中,一般都为0,r0 = 0;第二个参数放在寄存器1中,是机器类型id,r1 = Machine Type Number;第三个参数放在寄存器2中,是启动参数标记列表在ram中的起始基地址;bootloader首先要将ramdisk(如果有)和内核拷贝到ram当中,然后可以通过c语言的模式启动内核:void (*startkernel)(int zero, int arch, unsigned int params_addr) = (void(*)(int, int, unsigned int))KERNEL_RAM_BASE;startkernel(0, ARCH_NUMBER, (unsigned int)kernel_params_start);其中KERNEL_RAM_BASE为内核在ram中启动的地址,ARCH_NUMBER是Machine Type Number,kernel_params_start 是参数在ram的偏移地址。
这时候就将全力交给了内核。
linux启动分析(2)---内核启动地址的确定内核编译链接过程是依靠vmlinux.lds文件,以arm为例vmlinux.lds文件位于kernel/arch/arm/vmlinux.lds,但是该文件是由vmlinux-armv.lds.in生成的,根据编译选项的不同源文件还可以是vmlinux-armo.lds.in,vmlinux-armv-xip.lds.in。
ARM Linux启动过程学习
ARM Linux 启动过程学习linux 根目录中的vmlinux.o 为arm-linux-ld link 得到的一个elf 格式的文件,这个文件包含kernel 下的head.o+driver+MM+FS+net 等其他o 文件。
使用kernel 目录下的vmlinux.lds link 脚本生成vmlinux elf 格式的可执行文件Vmlinux 使用arm-linux-objcopy 生成bin 格式的文件image。
仅仅包含指令和数据。
可以load 到sdram 的0x30008000 地址运行。
为什么非要load 到这个地址呢?通过跟踪Head.S 执行,发现在__lookup_machine_type 函数中,如果load 地址不是0x30008000,Ldmia r3, {r4, r5, r6}会出现错误,r4 的内容出现错误为了分析linux 启动过程,生成一个最小的kernel,然后使用AXD+JTAG 来进行单步跟踪生成一个tiny kernel 使用axd 跟踪500+K 的bin 文件,load 到0x30008000 地址进行跟踪首先执行的代码为compressed head.S 中的start.S unzip 了一些代码,重新放入0x30008000,然后再次从0x30008000 地址重新执行新的代码问了得到kernel 中的函数虚拟地址,需要生成system.map 文件。
下面的命令可以得到system.mapNM=arm-linux-nm/bin/sh /hdd/linux-2.6.28/scripts/mksysmap vmlinux System.mapARM Linux 启动过程:在CPU 执行kernel 中的第一个指令之前,bootloader 必须完成一些工作:。
arm-linux启动流程分析
arm-linux启动流程分析arm-linux启动流程分析一.概述 (1)二.init进程 (1)三.inittab文件简要说明 (1)四.arm-linux系统的启动分析 (3)一.概述本文将讲述arm-linux内核启动后到进入用户shell模式这段时间的启动流程,从上电到进入kernel的过程请参见sourcesafe下“personal/yangxiyuan/资料”目录下的“ARM-linux启动流程.htm”文档。
二.init进程init进程是内核启动后的第一个用户级进程,是系统中所有进程的父进程,init进程的主要任务是按照inittab文件所提供的信息创建进程,init进程繁衍出完成通常操作所需的子进程,这些操作包括:设置机器名、检查和安装磁盘及文件系统、启动系统日志、配置网络接口并启动网络和邮件服务,启动打印服务等。
三.inittab文件简要说明inittab文件中每一记录都从新的一行开始,每个记录项最多可有512个字符,每一项的格式通常如下:id: run level:action:process,解释如下:id字段:是最多4个字符的字符串,用来唯一标志表项。
run level字段:定义该记录项被调用时的运行级别,run level可以由一个或多个运行级别构成,也可以是空,空则代表运行级别0~6。
# 0 - halt (Do NOT set initdefault to this)# - 关闭计算机,安全关闭电源# 1 - Single user mode# - 进入单用户维护模式,卸下除root以外的所有文件系统并杀死所有用户进程# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)# - 多用户模式,无网络连接# 3 - Full multiuser mode# - 多用户模式,并以文本方式作为登陆方式# 4 - unused# 5 - X11# - 多用户模式,并以图形方式作为登陆方式# 6 - reboot (Do NOT set initdefault to this)# - 停止linux系统,并按照/etc/inittab默认的登记项重新引导系统。
ARM Linux内核启动流程
ARM Linux 内核启动流程操作ARM Linux 内核主要分为哪几个步骤,下面杭州硕数就为大家讲解一下这个启动的流程。
ARM Linux 内核综述启动分两步,首先是硬件相关部分,入口是arch/arm/kernel/head.S 代码文件中的ENTRY(stext)函数;然后是硬件无关部分,入口函数是init/main.c 代码文件中的start_kernel 函数。
ARM Linux 内核硬件相关部分 1. 我们平台是arm,自然硬件相关部分代码在arch/arm/里面。
2. 平台相关部分的核心代码自然在arch/arm/kernel/里面。
3. 找入口函数,必须从对应目录的Makefile 和链接脚本*.lds 入手!# ls arch/arm/kernel/得到一个Makefile 文件和一个vmlinux.lds 文件# vim arch/arm/kernel/Makefile看到有一句extra-y := $(head-y) init_task.o vmlinux.lds,则说明其使用链接脚本为vmlinux.lds还有一句head-y := head$(MMUEXT).o# vim arch/arm/kernel/vmlinux.lds看到有一句ENTRY(stext),则说明入口函数为stext4. 结合上面3 句关键的代码,可以推测stext 函数在arch/arm/kernel/head*.S 或arch/arm/kernel/head*.c# ls arch/arm/kernel/head*得到arch/arm/kernel/head-common.S arch/arm/kernel/head-nommu.S arch/arm/kernel/head.o arch/arm/kernel/head.S再结合Makefile 的默认规则%.o : %.S 或%.o : %.c可以知道arch/arm/kernel/head.o 与arch/arm/kernel/head.S 对应。
ARM启动过程分析
ARM 启动过程的理解:第一篇参考文章1.在板子上电的一开始,首先自动判断是否是autoboot模式(这是由硬件设计阶段,由硬件工程师对mcu的引脚连线决定的),我所使用的s3c2410是带有nandflash的,并切被设置成autoboot,从nandflash开始启动.2.在判断是autoboot模式后,mcu内置的nandflash控制器自动将nandflash的最前面的4k区域(这4k区域存放着bootloader的最前面4k代码)拷贝到samsung所谓的"steppingstone"里面(实际上是一块4k大小的SRAM).这一过程完全由硬件自动实现,不需软件控制.3.在拷贝完前4k代码后,nandflash控制器自动将"steppingstone"映射到arm地址空间0x00000000开始的前4k区域.4.在映射过程完成后.nandflash控制器将pc指针直接指向arm地址空间的0x00000000位置,准备开始执行"steppingstone"上的代码.5.而"steppingstone"上从nandflash拷贝过来的4k代码,是程序员写的bootloader的前4k代码.这个bootloader在之前写好,并已经被烧写到nandflash的0x00000000开始的最前面区域..而这"steppingstone"上的4k代码就是bootloader的前4k代码.6.在pc指向arm地址空间的0x00000000后,系统就开始执行指令代码.这4k代码的任务是:初始化硬件,设置中断向量表,设置堆栈,然后一个很重要的任务是,将nandflash的最前面区域的bootloader(包含4k启动代码)拷贝到SDRAM中去,bootloader 代码的大小是写好bootloader就确定的.然后只需要确定bootloader想映射到SDRAM的起始位置就ok.7.在完成对nandflash上的bootloader搬移后,找到4k代码的搬移代码最后一个指令的下一个指令在SDRAM的bootloader 的地址,然后跳转到该位置,继续执行bootloader的剩余代码(引导系统).现在有这么几个问题:在启动启动完成后,steppingstone会被映射到其他地方,可以作为一般存储使用;为加快终端响应,需要将sdram开始的代码重新映射到0x00000000开始的一段区域,这样两个虚拟地址空间映射到一个物理内存区域;本文来自CSDN博客,转载请标明出处:/martree/archive/2008/11/17/3321639.aspx第二篇系统初始化流程如下:禁止看门狗——》在中断控制器中屏蔽所有中断——》系统时钟设置——》初始化端口——》DMA设置——》cashe和总线设置——》存储器设置,初始化SDRAM——》初始化堆栈——》设置IRQ和FIQ的入口——》地址重映射通常系统初始化有两个阶段组成,分别为汇编和C写成。
ARM的启动过程
ARM芯片的启动程序的分析和总结(2009-02-04 14:35:26)转载分类:ARM标签:杂谈1、综述:目前大多基于ARM芯片的系统都是一个比较复杂的片上系统,多数硬件模块都是可配置的,可以通过软件来设置其需要的工作状态。
因此在运行用户的应用程序之前,需要由专门的一段代码来完成对系统的初始化。
这一段代码就称为启动程序。
由于这类代码直接面对处理器内核和硬件控制器进行编程,一般都是用汇编语言。
在ARM系统上电复位后,需要设置中断向量表、初始化各模式堆栈、设置系统时钟频率等,需要用ARM的汇编语言编写启动代码,由启动代码完成系统初始化以及跳转到用户C程序。
在ARM设计开发中,启动代码的编写是一个极重要的过程。
然而启动代码随具体的目标系统和开发系统有所区别,但通常包含以下部分:·向量表定义·地址重映射及中断向量表的转移·堆栈初始化·设置系统时钟频率·中断寄存器的初始化·进入C应用程序下面就结合PHILIPS的LPC2119的启动代码来分析与说明ARM7处理器的启动代码的编写。
1.1向量表定义ARM芯片上电或复位后,系统进入管理模式、ARM状态、PC(R15寄存器)指向0x00000000地址处。
中断向量表为每一个中断设置1个字的存储空间,存放一条跳转指令,通过这条指令使PC指针指向相应的中断服务程序入口,继而执行相应的中断处理程序。
LPC2119的中断向量表和其它基于ARM核的芯片中断向量表较类似,只要注意LPC2119要使向量表所有数据32位累加和为零(0x00000000-0x0000001C的8个字的机器码累加), 才能使用户的程序脱机运行。
LPC2119的中断向量表如图1所示。
1.2 地址重映射及中断向量表的转移ARM7处理器在复位后从地址0读取第一条指令并执行,因此系统上电后地址0必须是非易失的ROM/FLASH,这样才能保证处理器有正确可用的指令。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Linux开发驱动底层环境启动流程Uboot编译:rm -rf 删除命令
tar xjf 解压uboot文件
patch -p1 < ../u-boot-1.1.6.jz2440.patch 打补丁 -p1 指示忽略第一个斜杠前因为已经在当前目录。
打好补丁之后配置文件make 100ask24x0_config之后make
配置文件是厂家提供好的。
Make后生成bin文件,在Windows下进入oflash目录烧写这个文件。
选择Open jtag S2C2440 nand flash 0块
0 2 0 0 0这几个数字
烧写之后进入启动界面之后uboot命令按help查看支持哪些命令。
?Md 查看 md命令
Print 命令查看环境变量
设置环境变量 set xxxx xx save
reset重启
Uboot 的终极目的就是要启动内核。
Make config 就相当于执行命令
100ask24x0_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0
NULL s3c24x0
MKCONFIG := $(SRCTREE)/mkconfig
$(@:_config=) $(@ 表示目标文件100ask24x0 _config=) 表示
替换掉他用后面的arm arm920t 100ask24x0 NULL s3c24x0 100ask24x0
最后就执行这个命令
Mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0
找到脚本文件mkconfig #!/bin/sh表示他是用bin目录下sh解释执行,后面是传入的参数。
这个配置过程它做了一些连接工作,把arm board arch 链接到现在的文件。
编译时的make 做的工作:用到了上面配置的config.mk
(.a文件表示所有编译好的文件打包成成的一个库)
OBJS = cpu/arm920/xxxx
Lib +=xxxx.a
ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)
依赖$(obj)u-boot.bin文件
$(obj)u-boot.bin他又依赖于
$(obj)u-boot: depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
-Map u-boot.map -o u-boot
得到的bin文件就是这个
.a文件如何组织连接在lds连接文件有说明
链接地址在0x33f80000就是说应该在这个地址运行
比如从0x00000000 到0x08000000是128M空间
2^27次方=2^7*2^10*2^10=128M
搜索命令 grep “” - nR
内存一共64M0x33f80000空出512K
UBOOT做一些工作:进入管理模式、关看门狗中断、初始化存储控制器、设置栈IRQFIQ、重定位(NORflash不能像内存一样写)、从flash拷到sdram、到他该运行的地址0x33f80000、清BSS段、调用C函数
从上往下依次是512K UBOOT 然后是用来实现malloc接下来是全局参数,在接下来就是各种模式的栈。
接下来刚才调用的C函数在这里执行完成大部分初始化包括以下初始化。
在BOARD_INIT中定义了机器ID(有一个gd结构体在那个全局参数中),内核启动身后参数存放的位置。
0x30000100处内核存放在0x30008000期间还有页表。
最后进入main_loop()函数这个函数看是否设置了读秒的环境参数没有的话直接等待,如果设置了读秒的环节就会等待输入如果
没有输入的话就会直接执行bootcmd环境变量进而启动内核,有的话等待串口输入。
Bootcmd这个环境变量里是从nand读到0x30007fc0去读从kernel分区去读。
然后bootm 0x30007fc0就启动了内核。
环境变量是用run_commad去执行的他是怎么执行的?根据结构体每个命令都会有一个结构体比如bootcmd、{
.name
.fun()
}然后调用fun()就执行了命令
对于bootcmd中nand命令表示从nand中读,bootm表示从内存中读。
The_kernel()函数一旦运行,控制权就交给了系统。
Linux系统
Find -name “defconfig”
编译:patch -p1 < ../补丁文件
配置:一、make menuconfig
二、使用默认的配置在此基础上修改
三、使用厂家的配置文件
直接把厂家提供的config复制为.config因为menuconfig会根据.config出现相关配置选项最后会在auto.conf中说明出哪些被编译进内核哪些被编译成为模块同时生成autoconfig.h文件里面有#define CONFIG_DEBUG_NX_TEST_MODULE 1
我们在使用make menuconfig时,首先会确定架构arch,然后读取arch目录的Kconfig 中的配置宏定义,生成编译条目,然后读取Linux内核根目录下的.config选项,将.config 中的配置信息显示在图形界面上[*] [M] or []。
我们在图形界面中更改配置选项会自动保存到.config文件中。
编译过程根据.config随后生成auto.conf文件,它决定了makefile 中各个文件的编译类型,静态编译进内核、编译成模块、不编译;同时生成autoconf.h,它以C语言宏定义的形式表达了各个文件是否被编译,源码中会判断某文件是否被编译进行不同的处理。
Makefile:uiamge依赖Vmlinux
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
首先执行head.s文件
处理传进来的参数,判断是否支持这个单板
怎么判断?
利用一个宏把一个结构体里面有机器ID和传入变量位置等等强制转换为段放进lds连接文件。
然后一一比较。
然后建立页表
启动MMU
执行start_kernel完成各种初始化,处理传进来的参数之后调用rest_init->kernel_init->prepar_namespace->mount_root挂接好的话调用init_post执行应用程序。