已阅读5页,还剩34页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Linux内核开发框架学习一、 常见linux内核文件的区别1、 vmlinux 编译出来的最原始的内核文件,未压缩。2、 zImagevmlinux经过gzip压缩后的文件。3、 bzImage bz表示“big zImage”,不是用bzip2压缩的。两者的不同之处在于,zImage解压缩内核到低端内存(第一个640K),bzImage解压缩内核到高端内存(1M以上)。如果内核比较小,那么采用zImage或bzImage都行,如果比较大应该用bzImage。4、 uImageU-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的tag。5、 vmlinuzbzImage/zImage文件的拷贝或指向bzImage/zImage的链接。6、 initrd“initial ramdisk”的简写。一般被用来临时的引导硬件到实际内核vmlinuz能够接管并继续引导的状态。二、 linux内核源码目录结构1、 arch目录包括了所有和体系结构相关的核心代码。它下面的每一个子目录都代表一种Linux支持的体系结构,例如i386就是Intel CPU及与之相兼容体系结构的子目录。PC机一般都基于此目录。 2、 include目录包括编译核心所需要的大部分头文件,例如与平台无关的头文件在include/linux子目录下。 3、 init目录包含核心的初始化代码(不是系统的引导代码),有main.c和Version.c两个文件。这是研究核心如何工作的好起点。 4、 mm目录包含了所有的内存管理代码。与具体硬件体系结构相关的内存管理代码位于arch/*/mm目录下。 5、 drivers目录是系统中所有的设备驱动程序。它又进一步划分成几类设备驱动,每一种有对应的子目录,如声卡的驱动对应于drivers/sound。 6、 ipc目录包含了核心进程间的通信代码。 7、 modules目录存放了已建好的、可动态加载的模块。 8、 fs目录存放Linux支持的文件系统代码。不同的文件系统有不同的子目录对应,如ext3文件系统对应的就是ext3子目录。 9、 Kernel内核管理的核心代码放在这里。同时与处理器结构相关代码都放在arch/*/kernel目录下。 10、 net目录里面是核心的网络部分代码,其每个子目录对应于网络的一个方面。 11、 lib目录包含了核心的库代码,不过与处理器结构相关的库代码被放在arch/*/lib/目录下。 12、 scripts目录包含用于配置核心的脚本文件。 13、 documentation目录该目录是对其它每个目录作用的具体说明。三、 Uboot加载内核的流程uboot通过执行bootm 0x81000000指令来启动 do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv)bootm_start(cmdtp, flag, argc, argv);ret = bootm_load_os(images.os, &load_end, 1);boot_fn = boot_osimages.os.os;/ 选择启动函数,即do_bootm_linuxboot_fn(0, argc, argv, &images);/ 执行do_bootm_linuxint do_bootm_linux(int flag, int argc, char *argv, bootm_headers_t *images)intmachid = bd-bi_arch_number;void(*theKernel)(int zero, int arch, uint params);/ theKernel指向内核入口地址theKernel = (void (*)(int, int, uint)images-ep;/ 在启动内核之前做一些清理工作cleanup_before_linux ();/ 启动内核theKernel (0, machid, bd-bi_boot_params);在启动内核之前,uboot必须为uImage准备以下准备:1 CPU 寄存器的设置:R00;R1Machine ID(即Machine Type Number,定义在linux/arch/arm/tools/mach-types);R2内核启动参数在 RAM 中起始基地址;2 CPU 模式:必须禁止中断(IRQs和FIQs);CPU 必须 SVC 模式;3 Cache 和 MMU 的设置:MMU 必须关闭;指令 Cache 可以打开也可以关闭;数据 Cache 必须关闭;uImage中64字节的头信息结构体如下:#define IH_NMLEN32/* Image Name Length*/typedef struct image_header uint32_tih_magic;/* Image Header Magic Number*/uint32_tih_hcrc;/* Image Header CRC Checksum*/uint32_tih_time;/* Image Creation Timestamp*/uint32_tih_size;/* Image Data Size*/uint32_tih_load;/* Data Load Address*/uint32_tih_ep;/* Entry Point Address*/uint32_tih_dcrc;/* Image Data CRC Checksum*/uint8_tih_os;/* Operating System*/uint8_tih_arch;/* CPU architecture*/uint8_tih_type;/* Image Type*/uint8_tih_comp;/* Compression Type*/uint8_tih_nameIH_NMLEN;/* Image Name*/ image_header_t;四、 linux内核的配置机制及其编译过程1、 配置系统的基本结构Linux内核的配置系统由三个部分组成,分别是:1) Makefile:分布在 Linux 内核源代码根目录及各层目录中,定义 Linux 内核的编译规则;2) 配置文件(config.in(2.4内核,2.6内核)):给用户提供配置选择的功能;3) 配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)和配置用户界面(提供基于字符界面、基于 Ncurses 图形界面以及基于 Xwindows 图形界面的用户配置界面,各自对应于 Make config、Make menuconfig 和 make xconfig)。2、 Linux内核配置相关的文件1) Linux内核根目录下的scripts文件夹:scripts文件夹存放的是跟make menuconfig配置界面的图形绘制相关的文件,我们作为使用者无需关心这个文件夹的内容。2) arch/$ARCH/Kconfig文件、各层目录下的Kconfig文件:当我们执行make menuconfig命令出现上述蓝色配置界面以前,系统帮我们做了以下工作:首先系统会读取arch/$ARCH/目录下的Kconfig文件生成整个配置界面选项(Kconfig是整个linux配置机制的核心),默认生成的界面是所有参数都是没有值的。ARCH环境变量的值由linux内核根目录下的makefile文件决定的,在makefile下有此环境变量的定义:ARCH ?= arm或者通过 make ARCH=arm menuconfig命令来指定。3) Linux内核根目录下的makefile文件、各层目录下的makefile文件:4) Linux内核根目录下的的.config文件、arm/$ARCH/下的config文件:默认配置选项存放在arch/$ARCH/configs下,对于arm来说就是arch/arm/configs文件夹,此文件夹中有许多选项,系统会读取哪个呢?内核默认会读取linux内核根目录下.config文件作为内核的默认选项,我们一般会根据开发板的类型从中选取一个与我们开发板最接近的系列到Linux内核根目录下。.config文件与我们的板子并不是完全匹配,这时我们可以选择直接修改.config文件然后执行make menuconfig命令读取新的选项。.config文件与我们的板子并不是完全匹配,这时我们可以选择直接修改.config文件然后执行make menuconfig命令读取新的选项。5) Linux内核根目录下的 include/generated/autoconf.h文件:当你保存make menuconfig选项时,系统会除了会自动更新.config外,还会将所有的选项以宏的形式保存在Linux内核根目录下的 include/generated/autoconf.h文件下。内核中的源代码就都会包含以上.h文件,跟宏的定义情况进行条件编译。当我们需要对一个文件整体选择如是否编译时,还需要修改对应的makefile文件。 最后我们会发现,整个linux内核配置过程中,留给用户的接口其实只有各层Kconfig、makefile文件以及对应的源文件。 比如我们如果想要给内核增加一个功能,并且通过make menuconfig控制其生成过程: 首先需要做的工作是:修改对应目录下的Kconfig文件,按照Kconfig语法增加对应的选项; 其次执行make menuconfig选择编译进内核或者不编译进内核,或者编译为模块,.config文件和autoconf.h文件会自动生成; 再次修改对应目录下的makefile文件完成编译选项的添加; 最后执行make zImage命令进行编译。3、 Kconfig文件分析分布在各目录下的Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了所属目录源文件相关的内核配置菜单。在内核配置make menuconfig(或xconfig等)时,从Kconfig中读出配置菜单,用户配置完后保存到.config(在顶层目录下生成)中。在内核编译时,主Makefile调用这个.config,就知道了用户对内核的配置情况。上面的内容说明:Kconfig就是对应着内核的配置菜单。假如要想添加新的驱动到内核的源码中,可以通过修改Kconfig来增加对我们驱动的配置菜单,这样就有途径选择我们的驱动,假如想使这个驱动被编译,还要修改该驱动所在目录下的Makefile。Kconfig的语法结构。Kconfig每个菜单项都有一个关键字标识,最常见的就是config。语法:config symboloptionssymbol就是新的菜单项,options是在这个新的菜单项下的属性和选项其中options部分有:1) 类型定义:每个config菜单项都要有类型定义,bool:布尔类型, tristate三态:内建、模块、移除, string:字符串, hex:十六进制, integer:整型例如config HELLO_MODULEbool hello test modulebool类型的只能选中或不选中,tristate类型的菜单项多了编译成内核模块的选项,假如选择编译成内核模块,则会在.config中生成一个CONFIG_HELLO_MODULE=m的配置,假如选择内建,就是直接编译成内核影响,就会在.config中生成一个CONFIG_HELLO_MODULE=y的配置.2) 依赖型定义depends on或requires指此菜单的出现是否依赖于另一个定义config HELLO_MODULEbool hello test moduledepends on ARCH_PXA 这个例子表明HELLO_MODULE这个菜单项只对XScale处理器有效,即只有在选择了ARCH_PXA, 该菜单才可见(可配置)。3) 帮助性定义只是增加帮助用关键字help或-help-4、 内核的Makefile 文件分析内核的Makefile分为5个组成部分: 1) Makefile 最顶层的Makefile 2) .config 内核的当前配置文档,编译时成为顶层Makefile的一部分3) arch/$(ARCH)/Makefile 和体系结构相关的Makefile 4) s/ Makefile.* 一些Makefile的通用规则 5) kbuild Makefile 各级目录下的大概约500个文档,编译时根据上层Makefile传下来的宏定义和其他编译规则,将源代码编译成模块或编入内核。顶层的Makefile文档读取 .config文档的内容,并总体上负责build内核和模块。Arch Makefile则提供补充体系结构相关的信息。 s目录下的Makefile文档包含了任何用来根据kbuild Makefile 构建内核所需的定义和规则。(其中.config的内容是在make menuconfig的时候,通过Kconfig文档配置的结果)顶层Makefile文件:vmlinux-init := $(head-y) $(init-y)vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)vmlinux-all := $(vmlinux-init) $(vmlinux-main)vmlinux-lds := arch/$(SRCARCH)/kernel/vmlinux.ldsexport KBUILD_VMLINUX_OBJS := $(vmlinux-all)/ 内核需要添加的模块init-y:= init/drivers-y:= drivers/ pifm/ switch/ sound/ firmware/net-y:= net/libs-y:= lib/core-y:= usr/head-y:= arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o5、 Vmlinux.lds文件分析位于arch/arm/kernel/vmlinux.ldsOUTPUT_ARCH(arm)/* 输出格式 */ENTRY(stext)/* 定义_start作为入口点 */jiffies = jiffies_64;SECTIONS . = 0x80000000 + 0x00008000;/* 定义当前段的偏移量 */ .init : /* Init code and data*/ _stext = .;/ 初始化代码段 _sinittext = .; *(.head.text) *(.init.text) *(.cpuinit.text) *(.meminit.text) _einittext = .; _proc_info_begin = .; *(..init) _proc_info_end = .; _arch_info_begin = .; *(..init) _arch_info_end = .; _tagtable_begin = .; *(.taglist.init) _tagtable_end = .; _pv_table_begin = .; *(.pv_table) _pv_table_end = .; . = ALIGN(16); _setup_start = .; *(.init.setup) _setup_end = .; _initcall_start = .; *(.initcallearly.init) _early_initcall_end = .; *(.initcall0.init) *(.initcall0s.init) *(.initcall1.init) *(.initcall1s.init) *(.initcall2.init) *(.initcall2s.init) *(.initcall3.init) *(.initcall3s.init) *(.initcall4.init) *(.initcall4s.init) *(.initcall5.init) *(.initcall5s.init) *(.initcallrootfs.init) *(.initcall6.init) *(.initcall6s.init) *(.initcall7.init) *(.initcall7s.init) _initcall_end = .; _con_initcall_start = .; *(.con_initcall.init) _con_initcall_end = .; _security_initcall_start = .; *(.security_initcall.init) _security_initcall_end = .; . = ALIGN(4); _initramfs_start = .; *(.init.ramfs) . = ALIGN(8); *(.) _init_begin = _stext; *(.init.data) *(.cpuinit.data) *(.meminit.data) . = ALIGN(8); _ctors_start = .; *(.ctors) _ctors_end = .; *(.init.rodata) *(.cpuinit.rodata) *(.meminit.rodata) . = ALIGN(1 12); .data.percpu : AT(ADDR(.data.percpu) - 0) _per_cpu_load = .; _per_cpu_start = .; *(.data.percpu.first) . = ALIGN(1 12); *(.data.percpu.page_aligned) *(.data.percpu.readmostly) *(.data.percpu) *(.data.percpu.shared_aligned) _per_cpu_end = .; . = ALIGN(1 12); _init_end = .; /* * unwind exit sections must be discarded before the rest of the * unwind sections get included. */ /DISCARD/ : *(.ARM.exidx.exit.text) *(.ARM.extab.exit.text) *(.ARM.exidx.cpuexit.text) *(.ARM.extab.cpuexit.text) .text : /* Real text segment*/ _text = .; /* Text and read-only data*/ _exception_text_start = .; *(.exception.text) _exception_text_end = .; . = ALIGN(8); *(.text.hot) *(.text) *(.ref.text) *(.devinit.text) *(.devexit.text) *(.text.unlikely) . = ALIGN(8); _sched_text_start = .; *(.sched.text) _sched_text_end = .; . = ALIGN(8); _lock_text_start = .; *(.spinlock.text) _lock_text_end = .; . = ALIGN(8); _kprobes_text_start = .; *(.kprobes.text) _kprobes_text_end = .; *(.fixup) *(.gnu.warning) *(.rodata) *(.rodata.*) *(.glue_7) *(.glue_7t) . = ALIGN(4); *(.got) /* Global offset table*/ . = ALIGN(1 12); .rodata : AT(ADDR(.rodata) - 0) _start_rodata = .; *(.rodata) *(.rodata.*) *(_vermagic) *(_markers_strings) *(_tracepoints_strings) .rodata1 : AT(ADDR(.rodata1) - 0) *(.rodata1) . = ALIGN(8); _jump_table : AT(ADDR(_jump_table) - 0) _start_jump_table = .; *(_jump_table) _stop_jump_table = .; .pci_fixup : AT(ADDR(.pci_fixup) - 0) _start_pci_fixups_early = .; *(.pci_fixup_early) _end_pci_fixups_early = .; _start_pci_fixups_header = .; *(.pci_fixup_header) _end_pci_fixups_header = .; _start_pci_fixups_final = .; *(.pci_fixup_final) _end_pci_fixups_final = .; _start_pci_fixups_enable = .; *(.pci_fixup_enable) _end_pci_fixups_enable = .; _start_pci_fixups_resume = .; *(.pci_fixup_resume) _end_pci_fixups_resume = .; _start_pci_fixups_resume_early = .; *(.pci_fixup_resume_early) _end_pci_fixups_resume_early = .; _start_pci_fixups_suspend = .; *(.pci_fixup_suspend) _end_pci_fixups_suspend = .; .builtin_fw : AT(ADDR(.builtin_fw) - 0) _start_builtin_fw = .; *(.builtin_fw) _end_builtin_fw = .; .rio_ops : AT(ADDR(.rio_ops) - 0) _start_rio_switch_ops = .; *(.rio_switch_ops) _end_rio_switch_ops = .; _ksymtab : AT(ADDR(_ksymtab) - 0) _start_ksymtab = .; *(_ksymtab) _stop_ksymtab = .; _ksymtab_gpl : AT(ADDR(_ksymtab_gpl) - 0) _start_ksymtab_gpl = .; *(_ksymtab_gpl) _stop_ksymtab_gpl = .; _ksymtab_unused : AT(ADDR(_ksymtab_unused) - 0) _start_ksymtab_unused = .; *(_ksymtab_unused) _stop_ksymtab_unused = .; _ksymtab_unused_gpl : AT(ADDR(_ksymtab_unused_gpl) - 0) _start_ksymtab_unused_gpl = .; *(_ksymtab_unused_gpl) _stop_ksymtab_unused_gpl = .; _ksymtab_gpl_future : AT(ADDR(_ksymtab_gpl_future) - 0) _start_ksymtab_gpl_future = .; *(_ksymtab_gpl_future) _stop_ksymtab_gpl_future = .; _kcrctab : AT(ADDR(_kcrctab) - 0) _start_kcrctab = .; *(_kcrctab) _stop_kcrctab = .; _kcrctab_gpl : AT(ADDR(_kcrctab_gpl) - 0) _start_kcrctab_gpl = .; *(_kcrctab_gpl) _stop_kcrctab_gpl = .; _kcrctab_unused : AT(ADDR(_kcrctab_unused) - 0) _start_kcrctab_unused = .; *(_kcrctab_unused) _stop_kcrctab_unused = .; _kcrctab_unused_gpl : AT(ADDR(_kcrctab_unused_gpl) - 0) _start_kcrctab_unused_gpl = .; *(_kcrctab_unused_gpl) _stop_kcrctab_unused_gpl = .; _kcrctab_gpl_future : AT(ADDR(_kcrctab_gpl_future) - 0) _start_kcrctab_gpl_future = .; *(_kcrctab_gpl_future) _stop_kcrctab_gpl_future = .; _ksymtab_strings : AT(ADDR(_ksymtab_strings) - 0) *(_ksymtab_strings) _init_rodata : AT(ADDR(_init_rodata) - 0) *(.ref.rodata) *(.devinit.rodata) *(.devexit.rodata) _param : AT(ADDR(_param) - 0) _start_param = .; *(_param) _stop_param = .; . = ALIGN(1 12); _end_rodata = .; . = ALIGN(1 12); _etext = .; /* End of text and rodata section */ . = ALIGN(8192); _data_loc = .; .data : AT(_data_loc) _data = .; /* address in memory */ _sdata = .; /* * first, the init task union, aligned * to an 8192 byte boundary. */ . = ALIGN(8192); *(.data.init_task) . = ALIGN(1 12); _nosave_begin = .; *(.data.nosave) . = ALIGN(1 12); _nosave_end = .; . = ALIGN(32); *(.data.cacheline_aligned) /* * The exception fixup table (might need resorting at runtime) */ . = ALIGN(32); _start_ex_table = .; *(_ex_table) _stop_ex_table = .; /* * and the usual data section */ *(.data) *(.ref.data) *(.data.shared_aligned) *(.devinit.data) *(.devexit.data) . = ALIGN(32); _start_tracepoints = .; *(_tracepoints) _stop_tracepoints = .; . = ALIGN(8); _start_verbose = .; *(_verbose) _stop_verbose = .; . = ALIGN(32); . = ALIGN(32); CONSTRUCTORS _edata = .; _edata_loc = _data_loc + SIZEOF(.data); . = ALIGN(0); _bss_start = .; . = ALIGN(0); .sbss : AT(ADDR(.sbss) - 0) *(.sbss) *(.scommon) . = ALIGN(0); .bss : AT(ADDR(.bss) - 0) *(.bss.page_aligned) *(.dynbss) *(.bss) *(COMMON) . = ALIGN(0); _bss_stop = .; _end = .; .stab 0 : *(.stab) .stabstr 0 : *(.stabstr) .stab.excl 0 : *(.stab.excl) .stab.exclstr 0 : *(.stab.exclstr) .stab.index 0 : *(.stab.index) .stab.indexstr 0 : *(.stab.indexstr) .comment 0 : *(.comment) .comment 0 : *(.comment) /* Default discards */ /DISCARD/ : *(.exit.text) *(.cpuexit.text) *(.memexit.text) *(.exit.data) *(.cpuexit.data) *(.cpuexit.rodata) *(.memexit.data) *(.memexit.rodata) *(.exitcall.exit) *(.discard) *(.discard.*) /DISCARD/ : *(.alt.smp.init) /* * These must never be empty * If you have to comment these two assert statements out, your * binutils is too old (for other reasons as well) */ASSERT(_proc_info_end - _proc_info_begin), missing CPU support)ASSERT(_arch_info_end - _arch_info_begin), no machine record defined)通过分析vmlinux文件的头信息来查看各个段:objdump -headers vmlinuxvmlinux: file format elf32-littleSections:Idx Name Size VMA LMA File off Algn 0 .note.gnu.build-id 00000024 00000000 00000000 00008000 2*2 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .init 000322eb 80008000 80008000 00010000 2*5 CONTENTS, ALLOC, LOAD, CODE 2 .text 003d736c 8003b000 8003b000 00043000 2*6 CONTENTS, ALLOC, LOAD, READONLY, CODE 3 _ksymtab 00005a10 80413000 80413000 0041b000 2*2 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 _ksymtab_gpl 00003138 80418a10 80418a10 00420a10 2*2 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 _kcrctab 00002d08 8041bb48 8041bb48 00423b48 2*2 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 _kcrctab_gpl 0000189c 8041e850 8041e850 00426850 2*2 CONTENTS, ALLOC, LOAD, READONLY, DATA 7 _ksymtab_strings 000132da 804200ec 804200ec 004280ec 2*0 CONTENTS, ALLOC, LOAD, READONLY, DATA 8 _param 00000c38 804333c8 804333c8 0043b3c8 2*2 CONTENTS, ALLOC, LOAD, READONLY, DATA 9 .data 0003e780 80434000 80434000 0043c000 2*6 CONTENTS, ALLOC, LOAD, DATA 10 .bss 0003ab38 80472780 80472780 0047a780 2*6 ALLOC 11 .ARM.attributes 0000002b 00000000 00000000 0047a780 2*0 CONTENTS, READONLY 12 .comment 0000a1c1 00000000 00000000 0047a7ab 2*0 CONTENTS, READONLY6、 linux内核启动过程分析第一个head.S文件arch/arm/boot/compressed/head.S是linux内核启动过程执行的第一个文件,其执行过程如图所示:压缩Vmlinux选用的链接文件是arch/arm/boot/compressed/vmlinux.lds,这个lds文件包含由arch/arm/boot/compressed/vmlinux.lds.in生成的各段入口。ENTRY(_start)SECTIONS /DISCARD/ : *(.ARM.exidx*) *(.ARM.extab*) . = TEXT_START; _text = .; .text : 展开如下表:假定zImage在内存中的初始地址为0x30008000(这个地址由bootloader决定,位置不固定)1、初始状态 链接文件arch/arm/boot/compressed/vmlinux.lds中的连接地址都是位置无关的,即都是以0地址为偏移的。而此时内核已被bootloader搬移到了SDRAM中。链接地址应该加上这个偏移。 */源码分析:.alignstart:.typestart,#function#function /type指定start这个符号是函数类型.rept8/重复8次movr0, r0,movr0, r0/空操作,让前面所取指令得以执行。.endrb1f/向前跳转/*魔数0x016f2818是在bootloader中用于判断zImage的存在,而zImage的判别的magic number为0x016f2818,这个也是内核和bootloader约定好的。*/.word0x016f2818.wordstart.word_edata/r1和r0中分别存放着由bootloader传递过来的architecture ID和指向标记列表的指针。1:movr7, r1movr8, r2/*这也标志着u-boot将系统完全的交给了OS,bootloader生命终止。之后会读取cpsr并判断是否处理器处于supervisor模式从u-boot进入kernel,系统已经处于SVC32模式;而利用angel进入则处于user模式,还需要额外两条指令。之后是再次确认中断关闭,并完成cpsr写入*/#ifndef _ARM_ARCH_2_mrsr2, cpsr get current modetstr2, #3 not user?bnenot_angelmovr0, #0x17/0x17是angel_SWIreason_EnterSVC半主机操作swi0x123456/0x123456是arm指令集的半主机操作编号not_angel:mrsr2, cpsrorrr2, r2, #0xc0msrcpsr_c, r2/这里将cpsr中I、F位分别置“1”,关闭IRQ和FIQ#elseteqppc, #0x0c000003 turn off interrupts#endif.text/指令adr是基于PC的值来获取标号LC0的地址的,由于内核已被搬移,标号LC0的地址不是以地址0为偏移的/这中间就存在一个固定的地址偏移,在s3c2410中是0x30008000.adrr0, LC0ldmiar0, r1, r2, r3, r4, r5, r6, ip, spsubsr0, r0, r1/这里获得当前运行地址与链接地址的偏移量,存入r0中为0x30008000./如果不需要重定位,即内核没有进行过搬移,就跳转。如果内核代码是存于NANDflash中的/是需要搬移的。beqnot_relocatedaddr5, r5, r0/修改内核映像基地址此时r5=0x30008000addr6, r6, r0/修改got表
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 公司单板加工工设备技术规程
- 硝酸铵生产工岗位职业健康技术规程
- 软件可靠性评估-第2篇-洞察与解读
- 浙江省温州市苍南县金乡卫城中学2025-2026学年数学高一上期末质量检测试题含解析
- 内蒙古乌兰察布集宁区2025-2026学年数学高二第一学期期末调研试题含解析
- 全球航标市场需求分析-洞察与解读
- 领导力与团队协作-洞察与解读
- 新疆阿克苏地区库车县乌尊镇乌尊中学2025年高一上数学期末达标检测模拟试题含解析
- 海南热带海洋学院《嵌入式技术及应用》2024-2025学年第一学期期末试卷
- 山东省菏泽市鄄城县第一中学2025-2026学年高一上物理期末检测模拟试题含解析
- 2025年运输经理招聘面试参考题库及答案
- 北欧风格室内设计讲解
- 2025专职消防员聘用合同
- 2025亚洲烟草产业市场供求状况及投资前景规划研究报告
- 边界联检工作总结
- XX集团董事会2025年度工作报告
- 全科医学科慢性病综合管理指南
- 2026年气溶胶灭火系统市场研究报告
- 兄弟放弃继承协议书
- 矿山个人劳务合同范本
- 2025年消防日消防月主题知识培训
评论
0/150
提交评论