head.s 分析

【步兵 经验篇】断点续传 【步兵 经验篇】断点续传 By EOS.虽然 基于cocos写的,但是也可以用于其他地方,核心是curl库,只要引用就可以实现。 既然curl库本身是有断点续传的接口的,不用岂不可惜?用途断点续传其实主要应用于游戏中资源的下载,代码才几K?完全没有必要,而且还降低了其他 问题的可能性,但是资源就不一样了,像现在很多游戏,都为了压缩包体,把各种资源都在, 进入游戏第一次进行下载,又或者后续的资源 阅读详情

linux/arch/arm/boot/compressed/head.S

这是ARM-Linux运行的第一个文件,这些代码是一个比较独立的代码包裹器。其作用就是解压Linux内核,并将PC指针跳到内核(vmlinux)的第一条指令。
Bootloader中传入到Linux中的参数总共有三个,Linux中用到的是第二个和第三个。第二个参数是architecture id,第三个是taglist的地址。Architecture id的arm芯片在Linux中一定要唯一。Taglist是bootload向Linux传入的参数列表(详细的解释请参考《booting arm linux.pdf》)。
//程序的入口点
   .section ".start", #alloc, #execinstr
/*
* sort out different calling conventions
*/
   .align
start:
   .type start,#function
   .rept 8//重复8次下面的指令,也就是空出中断向量表的位置
   mov r0, r0//就是nop指令
   .endr

   b 1f
   .word 0x016f2818   @ Magic numbers to help the loader
   .word start    @ absolute load/run zImage address
   .word _edata    @ zImage end address
1:   mov r7, r1    @ save architecture ID
   mov r8, r2    @ save atags pointer

#ifndef __ARM_ARCH_2__
   /*
   * Booting from Angel - need to enter SVC mode and disable
   * FIQs/IRQs (numeric definitions from angel arm.h source).
   * We only do this if we were in user mode on entry.
   */
   mrs r2, cpsr   @ get current mode
   tst r2, #3    @ not user?
   bne not_angel
   mov r0, #0x17   @ angel_SWIreason_EnterSVC
   swi 0x123456   @ angel_SWI_ARM
not_angel:
   mrs r2, cpsr   @ turn off interrupts to
   orr r2, r2, #0xc0   @ prevent angel from running
   msr cpsr_c, r2
#else
   teqp pc, #0x0c000003   @ turn off interrupts
#endif

一定要保证当前运行在SVC模式下,否则会跳到swi里面去(为什么?我不清楚,而且我没有处理过这个swi)。然后再关闭irq和fiq。

   /*
   * Note that some cache flushing and other stuff may
   * be needed here - is there an Angel SWI call for this?
   */

   /*
   * some architecture specific code can be inserted
   * by the linker here, but it should preserve r7, r8, and r9.
   */

读入地址表。因为我们的代码可以在任何地址执行,也就是位置无关代码(PIC),所以我们需要加上一个偏移量。下面有每一个列表项的具体意义。
GOT表的初值是连接器指定的,当时程序并不知道代码在哪个地址执行。如果当前运行的地址已经和表上的地址不一样,还要修正GOT表。
   .text
   adr r0, LC0
   ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp}
   subs r0, r0, r1   @ calculate the delta offset

       @ if delta is zero, we are
   beq not_relocated   @ running at the address we
       @ were linked at.

   /*
   * We're running at a different address. We need to fix
   * up various pointers:
   *   r5 - zImage base address
   *   r6 - GOT start
   *   ip - GOT end
   */
   add r5, r5, r0
   add r6, r6, r0
   add ip, ip, r0

   /*
   * If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
   * we need to fix up pointers into the BSS region.
   *   r2 - BSS start
   *   r3 - BSS end
   *   sp - stack pointer
   */
   add r2, r2, r0
   add r3, r3, r0
   add sp, sp, r0

修改GOT(全局偏移表)表。根据当前的运行地址,修正该表。
   /*
   * Relocate all entries in the GOT table.
   */
1:   ldr r1, [r6, #0]   @ relocate entries in the GOT
   add r1, r1, r0   @ table. This fixes up the
   str r1, [r6], #4   @ C references.
   cmp r6, ip
   blo 1b

清BSS段,所有的arm程序都需要做这些的。

not_relocated: mov r0, #0
1:   str r0, [r2], #4   @ clear bss
   str r0, [r2], #4
   str r0, [r2], #4
   str r0, [r2], #4
   cmp r2, r3
   blo 1b

正如下面的注释所说,C环境我们已经设置好了。下面我们要打开cache和mmu。为什么要这样做呢?这只是一个解压程序呀?为了速度。那为什么要开mmu呢,而且只是做一个平板式的映射?还是为了速度。如果不开mmu的话,就只能打开icache。因为不开mmu的话就无法实现内存管理,而io区是决不能开dcache的。

   /*
   * The C runtime environment should now be setup
   * sufficiently. Turn the cache on, set up some
   * pointers, and start decompressing.
   */
   bl cache_on
是不是要跟读进去呢?对于只是对流程感兴趣的人只是知道打开cache就行了。不过跟进去是很有乐趣的,这就是为什么虽然Linux如此庞大,但仍有人会孜孜不倦的研究它的每一行代码的原因吧。反过来说,对于Linux内核的整体把握更加重要,要不然就成盲人摸象了。还有,想做ARM高手的人可以读Linux下的每一个汇编文件,因为Linux内核用ARM的东西还是比较全的。

   mov r1, sp    @ malloc space above stack
   add r2, sp, #0x10000 @ 64k max

对下面这些地址的理解其实还是很麻烦,但有篇文档写得很清楚《About TEXTADDR, ZTEXTADDR, PAGE_OFFSET etc...》。下面程序的意义就是保证解压地址和当前程序的地址不重叠。上面分配了64KB的空间来做解压时的数据缓存。
/*
* Check to see if we will overwrite ourselves.
*   r4 = final kernel address//内核执行的最终实地址
*   r5 = start of this image//该程序的首地址
*   r2 = end of malloc space (and therefore this image)
* We basically want:
*   r4 >= r2 -> OK
*   r4 + image length <= r5 -> OK
*/
   cmp r4, r2
   bhs wont_overwrite
   add r0, r4, #4096*1024 @ 4MB largest kernel size
   cmp r0, r5
   bls wont_overwrite

如果空间不够了,只好解压到缓冲区地址后面。调用decompress_kernel进行解压缩,这段代码是用c实现的,和架构无关。

   mov r5, r2    @ decompress after malloc space
   mov r0, r5
   mov r3, r7
   bl decompress_kernel

完成了解压缩之后,由于空间不够,内核也没有解压到正确的地址,必须通过代码搬移来搬到指定的地址。搬运过程中有可能会覆盖掉现在运行的这段代码,所以必须将有可能会执行到的代码搬运到安全的地方,这里用的是解压缩了的代码的后面。

   add r0, r0, #127
   bic r0, r0, #127   @ align the kernel length
/*
* r0     = decompressed kernel length
* r1-r3 = unused
* r4     = kernel execution address
* r5     = decompressed kernel start
* r6     = processor ID
* r7     = architecture ID
* r8     = atags pointer
* r9-r14 = corrupted
*/
   add r1, r5, r0   @ end of decompressed kernel
   adr r2, reloc_start
   ldr r3, LC1
   add r3, r2, r3
1:   ldmia r2!, {r9 - r14}   @ copy relocation code
   stmia r1!, {r9 - r14}
   ldmia r2!, {r9 - r14}
   stmia r1!, {r9 - r14}
   cmp r2, r3
   blo 1b

   bl cache_clean_flush//因为有代码搬移,所以必须先清理(clean)清除(flush)cache。
   add pc, r5, r0   @ call relocation code

decompress_kernel共有4个参数,解压的内核地址、缓存区首地址、缓存区尾地址、和芯片ID,返回解压缩代码的长度。

/*
* We're not in danger of overwriting ourselves. Do this the simple way.
*
* r4     = kernel execution address
* r7     = architecture ID
*/
wont_overwrite: mov r0, r4
   mov r3, r7
   bl decompress_kernel
   b call_kernel

针对于不会出现代码覆盖的情况,就简单了。直接解压缩内核并且跳转到首地址运行。call_kernel这个函数我们会在下面分析它。

   .type LC0, #object
LC0:   .word LC0    @ r1
   .word __bss_start   @ r2
   .word _end    @ r3
   .word zreladdr   @ r4
   .word _start    @ r5
   .word _got_start   @ r6
   .word _got_end   @ ip
   .word user_stack+4096   @ sp
LC1:   .word reloc_end - reloc_start
   .size LC0, . - LC0

上面这个就是刚才我们说过的地址表,里面有几个符号的地址定义。LC0是在这里定义的。Zreladdr是在当前目录下的Makfile里定义的。其他的符号是在lds里定义的。

下面我们来分析一下有关cache和mmu的代码。通过这些代码我们可以看到Linux的高手们是如何通过汇编来实现各个ARM处理器的识别,以达到通用的目的。
/*
* Turn on the cache. We need to setup some page tables so that we
* can have both the I and D caches on.
*
* We place the page tables 16k down from the kernel execution address,
* and we hope that nothing else is using it. If we're using it, we
* will go pop!
*
* On entry,
* r4 = kernel execution address
* r6 = processor ID
* r7 = architecture number
* r8 = atags pointer
* r9 = run-time address of "start" (???)
* On exit,
* r1, r2, r3, r9, r10, r12 corrupted
* This routine must preserve:
* r4, r5, r6, r7, r8
*/
   .align 5
cache_on: mov r3, #8    @ cache_on function
   b call_cache_fn

这里涉及到了很多MMU、cache、writebuffer、TLB的操作和协处理器的编程。具体编程的东西,我就不想多说了,可以对这ARM的手册逐行的理解。至于为什么要这样做,熟悉了他们的工作原理后也就不难理解了(《ARM嵌入式系统开发》这本书就有个比较好的说明)。因为这里包含了太多的代码搬运、解压等费时的操作,所以打开cache是有必要的。由于要用到数据cache所以需要对mmu进行配置。为了简单这里制作了一级映射,而且是物理地址和虚拟地址相同的1:1映射。

__setup_mmu: sub r3, r4, #16384   @ Page directory size
   bic r3, r3, #0xff   @ Align the pointer
   bic r3, r3, #0x3f00
/*
* Initialise the page tables, turning on the cacheable and bufferable
* bits for the RAM area only.
*/
   mov r0, r3
   mov r9, r0, lsr #18
   mov r9, r9, lsl #18   @ start of RAM
   add r10, r9, #0x10000000 @ a reasonable RAM size
   mov r1, #0x12
   orr r1, r1, #3 << 10
   add r2, r3, #16384
1:   cmp r1, r9    @ if virt > start of RAM
   orrhs r1, r1, #0x0c   @ set cacheable, bufferable
   cmp r1, r10    @ if virt > end of RAM
   bichs r1, r1, #0x0c   @ clear cacheable, bufferable
   str r1, [r0], #4   @ 1:1 mapping
   add r1, r1, #1048576
   teq r0, r2
   bne 1b

参考下面的注释,如果当前在flash中运行,我们再映射2MB。就算是当前在RAM中执行其实也没关系,只不过是做了重复工作。

/*
* If ever we are running from Flash, then we surely want the cache
* to be enabled also for our execution instance... We map 2MB of it
* so there is no map overlap problem for up to 1 MB compressed kernel.
* If the execution is in RAM then we would only be duplicating the above.
*/
   mov r1, #0x1e
   orr r1, r1, #3 << 10
   mov r2, pc, lsr #20
   orr r1, r1, r2, lsl #20
   add r0, r3, r2, lsl #2
   str r1, [r0], #4
   add r1, r1, #1048576
   str r1, [r0]
   mov pc, lr

__armv4_cache_on:
   mov r12, lr
   bl __setup_mmu
   mov r0, #0
   mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
   mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
   mrc p15, 0, r0, c1, c0, 0 @ read control reg
   orr r0, r0, #0x5000   @ I-cache enable, RR cache replacement
   orr r0, r0, #0x0030
   bl __common_cache_on
   mov r0, #0
   mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
   mov pc, r12

__common_cache_on:
#ifndef DEBUG
   orr r0, r0, #0x000d   @ Write buffer, mmu
#endif
   mov r1, #-1
   mcr p15, 0, r3, c2, c0, 0 @ load page table pointer
   mcr p15, 0, r1, c3, c0, 0 @ load domain access control
   mcr p15, 0, r0, c1, c0, 0 @ load control register
   mov pc, lr

/*
* All code following this line is relocatable. It is relocated by
* the above code to the end of the decompressed kernel image and
* executed there. During this time, we have no stacks.
*
* r0     = decompressed kernel length
* r1-r3 = unused
* r4     = kernel execution address
* r5     = decompressed kernel start
* r6     = processor ID
* r7     = architecture ID
* r8     = atags pointer
* r9-r14 = corrupted
*/

下面这段代码是在解压空间不够的情况下需要重新定位的,具体原因上面已经说明。

   .align 5
reloc_start: add r9, r5, r0
   debug_reloc_start
   mov r1, r4
1:
   .rept 4
   ldmia r5!, {r0, r2, r3, r10 - r14} @ relocate kernel
   stmia r1!, {r0, r2, r3, r10 - r14}
   .endr

   cmp r5, r9
   blo 1b
   debug_reloc_end

这是最后一个函数了,这个时候一切实质性的工作已经做完。关闭cache,并跳转到真正的内核入口。

call_kernel: bl cache_clean_flush
   bl cache_off
   mov r0, #0    @ must be zero
   mov r1, r7    @ restore architecture number
   mov r2, r8    @ restore atags pointer
   mov pc, r4    @ call kernel

/*
* Here follow the relocatable cache support functions for the
* various processors. This is a generic hook for locating an
* entry and jumping to an instruction at the specified offset
* from the start of the block. Please note this is all position
* independent code.
*
* r1 = corrupted
* r2 = corrupted
* r3 = block offset
* r6 = corrupted
* r12 = corrupted
*/

通过下面函数我们可以通过proc_types结构体数组我们可以顺利的找到现在的处理器型号,并且会根据R3的偏移量跳转到相应的函数中。里面涉及到协处理器CP15中c0的操作,如果有疑问,可以参考ARM相关手册。

call_cache_fn: adr r12, proc_types
   mrc p15, 0, r6, c0, c0 @ get processor ID
1:   ldr r1, [r12, #0]   @ get value
   ldr r2, [r12, #4]   @ get mask
   eor r1, r1, r6   @ (real ^ match)
   tst r1, r2    @       & mask
   addeq pc, r12, r3   @ call cache function
   add r12, r12, #4*5
   b 1b

/*
* Table for cache operations. This is basically:
*   - CPU ID match
*   - CPU ID mask
*   - 'cache on' method instruction
*   - 'cache off' method instruction
*   - 'cache flush' method instruction
*
* We match an entry using: ((real_id ^ match) & mask) == 0
*
* Writethrough caches generally only need 'on' and 'off'
* methods. Writeback caches _must_ have the flush method
* defined.
*/
   .type proc_types,#object
proc_types:
   .word 0x41560600   @ ARM6/610
   .word 0xffffffe0
   b __arm6_cache_off @ works, but slow
   b __arm6_cache_off
   mov pc, lr
@   b __arm6_cache_on   @ untested
@   b __arm6_cache_off
@   b __armv3_cache_flush

   .word 0x00000000   @ old ARM ID
   .word 0x0000f000
   mov pc, lr
   mov pc, lr
   mov pc, lr

   .word 0x41007000   @ ARM7/710
   .word 0xfff8fe00
   b __arm7_cache_off
   b __arm7_cache_off
   mov pc, lr

   .word 0x41807200   @ ARM720T (writethrough)
   .word 0xffffff00
   b __armv4_cache_on
   b __armv4_cache_off
   mov pc, lr

   .word 0x00007000   @ ARM7 IDs
   .word 0x0000f000
   mov pc, lr
   mov pc, lr
   mov pc, lr

   @ Everything from here on will be the new ID system.

   .word 0x4401a100   @ sa110 / sa1100
   .word 0xffffffe0
   b __armv4_cache_on
   b __armv4_cache_off
   b __armv4_cache_flush

   .word 0x6901b110   @ sa1110
   .word 0xfffffff0
   b __armv4_cache_on
   b __armv4_cache_off
   b __armv4_cache_flush

   @ These match on the architecture ID

   .word 0x00020000   @ ARMv4T
   .word 0x000f0000
   b __armv4_cache_on
   b __armv4_cache_off
   b __armv4_cache_flush

   .word 0x00050000   @ ARMv5TE
   .word 0x000f0000
   b __armv4_cache_on
   b __armv4_cache_off
   b __armv4_cache_flush

   .word 0x00060000   @ ARMv5TEJ
   .word 0x000f0000
   b __armv4_cache_on
   b __armv4_cache_off
   b __armv4_cache_flush

   .word 0x00070000   @ ARMv6
   .word 0x000f0000
   b __armv4_cache_on
   b __armv4_cache_off
   b __armv6_cache_flush

   .word 0    @ unrecognised type
   .word 0
   mov pc, lr
   mov pc, lr
   mov pc, lr

   .size proc_types, . - proc_types

/*
* Turn off the Cache and MMU. ARMv3 does not support
* reading the control register, but ARMv4 does.
*
* On entry, r6 = processor ID
* On exit,   r0, r1, r2, r3, r12 corrupted
* This routine must preserve: r4, r6, r7
*/
   .align 5
cache_off: mov r3, #12    @ cache_off function
   b call_cache_fn

//代码略

这里分配了4K的空间用来做堆栈。

reloc_end:

   .align
   .section ".stack", "w"
user_stack: .space 4096


推荐一款基于SpringBoot的开源智能停车项目   大家好,我是小编南风吹,每天推荐一个小工具/源码,装满你的收藏夹,让你轻松节省开发效率,实现不加班不熬夜不掉头发!   今天小编推荐一款基于 SpringBoot + Vue 的智能停车场管理平台!科学计费,多种计费方案灵活切换,商场、小区、停车场等场景均适用!无人值守,云端控制实现无岗亭模式下的车辆自主进出,降低人工成本! 开源协议   使用 MIT 开源许可协议 链接地址   公众号【Github导航站】回复关键词【sma】获取git地址 基础环境   JDK1.8、Maven、Mysql、Inte 阅读详情

相关推荐

head.s源码分析

我们前面分析了setup源码,setup在把模式转为保护模式后立刻调用了一个跳转指令,跳转到内存地址0处开始执行,这个位置对应的就是head.s. head.s经过编译后会与其他程序一起连接成system模块,位于system模块最开始,这也是为什么称它head.s. system放在磁盘上setup之后开始的扇区中,即从磁盘上第6个扇区开始。一般情况下,linux0.11内核的sys

wyc的专栏 948

arm-linux head.S 源代码分析

<br />arm-linux head.S 源代码分析<br />这是ARM-Linux运行的第一个文件,这些代码是一个比较独立的代码包裹器。其作用就是解压Linux内核,并将PC指针跳到内核(vmlinux)的第一条指令。<br />Bootloader中传入到Linux中的参数总共有三个,Linux中用到的是第二个和第三个。第二个参数是architecture id,第三个是taglist的地址。Architecture id的arm芯片在Linux中一定要唯一。Taglist是bootloa

Embeded system Development 2万+

【Linux0.11代码分析】04 之 head.s 启动流程

【Linux0.11代码分析】04 之 head.s 启动流程

|~~~热爱生活、努力学习的小伙汁~~~| 1161

SCF1d.c:(.text+0xee8): relocation truncated to fit: R_X86_64_PC32 against symbol `Fel' defined in CO

SCF1d.c:(.text+0xee8): relocation truncated to fit: R_X86_64_PC32 against symbol `Fel' defined in CO 在linux中编译程序,出现以上内存限制问题,编译不通过。       一些博文中说是内存超过2G会出现问题。需要添加编译选项:-mcmodel 调整编译时的对静态数组要求的大

zhangjingxueq的博客 3万+

CUDA详细安装及环境配置——环境配置指南 – CUDA+cuDNN+PyTorch 安装

本文详细介绍了如何确定显卡支持的CUDA版本、选择对应的cuDNN版本,并逐步安装CUDA、cuDNN和PyTorch。首先,通过命令行输入nvidia-smi.exe查看显卡支持的CUDA版本。接着,根据CUDA版本选择对应的cuDNN版本并下载。然后,从NVIDIA官方网站下载CUDA安装包,按照提示进行安装,并检查是否安装成功。同样地,下载cuDNN安装包,解压后将文件拷贝到CUDA安装目录中,并通过命令行验证安装是否成功。最后,根据PyTorch官网的指引,选择合适的安装命令进行PyTorch的安装

2501_90350274的博客 5098

DSP28335 ADC模块实战:从寄存器配置到精准数据采集(附代码详解)

本文详细解析DSP28335的ADC模块配置与数据采集实战,涵盖寄存器设置、采样窗口优化、中断处理及代码实现。重点解决ADC精度问题,如采样窗口不足导致数据偏差,提供完整代码示例和调试技巧,助力工程师实现精准数据采集。

kkk56的博客 864

Spatial Group Sparsity Regularized Nonnegative Matrix Factorization for Hyperspectral Unmixing

2017-NMF 空间群稀疏正则化非负矩阵分解的高光谱解混

m0_51414342的博客 1万+

保姆级避坑指南:在Ubuntu 22.04上成功复现VMamba模型(附完整环境依赖清单)

本文提供了在Ubuntu 22.04上复现VMamba模型的详细指南,包括环境准备、CUDA与PyTorch的精确匹配、依赖安装的疑难杂症解决以及完整环境清单。特别针对Linux系统下的环境复现问题,提供了实用的避坑技巧和验证方法,帮助开发者高效完成VMamba模型的部署。

weixin_29083373的博客 263

linux内核head.S分析

文章目录1.1内核链接脚本分析出内核第一条指令1.2head.s的分析1.3内核为什么在一开始不用C,而是先用汇编语言再跳转至C程序 1.1内核链接脚本分析出内核第一条指令 链接文件怎么读可以参考下面的文章 https://blog.csdn.net/zhjica/article/details/52995536 路径:arch/arm/kernel/vmlinux.lds.S 部分内容如下 OUTPUT_ARCH(arm) 输出文件的架构 ENTRY(stext) 指的是执行的第一条指令的地址,这个是

qq_14843999的博客 1903

Gitlab+Jenkins+Docker+Harbor+K8s+Rancher集群搭建CICD平台

本文以诺依项目为例详细记录了Kubernetes集群的部署过程以及配套DevOps环境的搭建。主要内容包括:1) 配置8个节点的软硬件环境;2) 基础环境准备(网络、防火墙、Docker等);3) 三节点Kubernetes集群部署;4) GitLab代码仓库安装;5) Harbor私有镜像仓库搭建;6) Jenkins持续集成工具配置;7) 基于若依项目的CI/CD实践;8) Rancher集群管理工具部署。

hickman2023的博客 1201

AD服务器搭建

一、角色安装1)打开服务器管理器,添加 角色和功能;2) 点 下一步;3)点 下一步;4)点 下一步;5)点击安装;6-1)将此服务器提升为域控制器;6-2)点下一步;6)输入密码 点 下一步;7)自动生成LIXF,点击下一步;8)确认目录,点下一步;8)确认安装条件,点安装; 8)安装成功,点关闭;...

潇峰的博客 6446

Linux启动分析(2)— bootsect.S、setup.S、head.S分析

bootsect.S,系统引导程序,一般不超过512字节。在PC系统结构中,线性地址0xA0000以上,即640K以上用于图形接口卡和BIOS自身,640K以下为系统的基本内存。如果配置更多的内存,则0x100000,即1MB处开始称为高内存。当BIOS引导一个系统时,总是把引导扇区读入到基本内存地址为0x7c00的地方,然后跳转到此执行引导扇区的代码。这段代码将自身搬运到0x90000处,并

cxy的Linux技术专栏 7466

结构光三维重建(一)条纹结构光三维重建

在近景三维重建领域,结构光技术可以说是应用最广泛的,尤其在工业领域。该技术目前具有高精度和无视弱纹理等优点,但复杂的室外环境还是会对该技术造成一定程度的干扰。目前用的比较多的结构光分别两大类:线结构光以及条纹结构光。接下来我先来简单介绍一下条纹结构光三维重建,事实上,条纹结构光的原理与双目立体匹配是非常相似的。...

AAAA202012的博客 1万+

Linux源码head.S分析

分析/arch/arm/boot/compress/head.S。 看了很久也看得不是很明白,先转一篇牛人写的, http://blog.csdn.net/lanmanck/article/details/4288048

FF的专栏 1078

Android Input——输入系统介绍(一)

Input 系统对于提供流畅、灵敏和一致的用户交互体验至关重要,它需要在不同的设备、场景和应用中保证输入事件的正确性、及时性和安全性。Android 输入系统是一个复杂但高效的设计,旨在处理来自各种输入设备(如触摸屏、键盘等)的用户交互,并将这些交互转换为应用程序可以理解和响应的形式。EventHub:输入系统的最底层,直接与硬件通信,监听和读取输入设备的原始事件。:从 EventHub 获取原始输入事件,对其进行解析,转化为更高层次的事件,以便上层应用或服务能够理解。

小旭的专栏 1711

Android 64位支持的坑:诡异的文件名问题

最近在尝试发布我的Android应用程序的更新时,遇到了一个令人困惑的64位错误。本文将详细讲解这个问题的产生原因及解决方法,供大家参考。

m0_74337424的博客 122

linux内核源码head.s分析

在boot.s中,内核已经移至0x0000 0000处,并且开始执行,首先执行的就是head.s,这部分代码执行完后,也会被覆盖,严格意义上来讲,不是完全属于内核代码。 这部分代码采用AT&T汇编编写,下面来详细分析下其功能: /* * head.s contains the 32-bit startup code. * * NOTE!!! Startup happens at a...

helloworld 714

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

android内核启动分析之head.S

内核加载到ramhuo

徐行而来--浅唱而归的专栏 1144

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Linux启动分析— bootsect.S、setup.S、head.S分析

bootsect.S,系统引导程序,一般不超过512字节。     在PC系统结构中,线性地址0xA0000以上,即640K以上用于图形接口卡和BIOS自身,640K以下为系统的基本内存。如果配置更多的内存,则0x100000,即1MB处开始称为高内存。当BIOS引导一个系统时

wangsheng8888的专栏 623

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

arm linux 从入口到start_kernel 代码分析——head.S分析——3

arm linux 从入口到start_kernel 代码分析 - 3(2008-07-30 16:03:39)转载标签:it分类:kernel<br />2. 确定 machine type<br />    arch/arm/kernel/head.S中:<br />00079:  bl __lookup_machine_type  @ r5=machinfo             <br />00080:  movs r8, r5    @ invalid machine (r5=0)? <br /

y296144646q的专栏 1399

arm linux head.s,linux2.6.17,arm head.s文件分析.doc

哗傻邦驮歉隶戊敏唇很乃奠依莎钳窜抉扣珠堡涯柄汤络早示涪拣诛洁坟质挫琐礼月憾鞋辣秤音诡渺懒庞虱撩曳蕾痒烧渐呀猖覆陵碗谢蒋站苛倔鸽蒸局添桨咏拼妆紊德丑寇浦痈恃偶诽靴堪奢论磷酉彤堕迄浮峡兰茧释讹荣椽菌胸形油领艇谚臭仲吵搜嫂扬筑沦纸寇洗贮靛唇迂聘征净英镊里间吸孽梆焉舜罪札侣衬丧呢应炔铁贤根愿赴复护维棋瘴觉虐绚腹矾程活呆蚀驻总谓凋迟黄隘喘蓄累杀洼拨崇仗择旅亡尼蹈包召蛛调疆敖盲祈焕茹钙折松赞来森睡揉巩斯园离纶...

weixin_35662417的博客 245

linux内核源码分析-head.s

本人最近在学linux0.11的源码,顺便写成博客可以供自己记忆还有分享给别人学习,以下的内容是基于作者本人的理解写的,如有疑问可以提出,大家一起探讨学习,如写得有错误,也欢迎指正。

weixin_52543485的博客 1478

linux源码分析之cpu初始化 kernel/head.s,linux源码分析之cpu初始化 kernel/head.s

来自:http://blog.csdn.net/BoySKung/archive/2008/12/09/3486026.aspxlinux-2.6.20.6/arch/arm/kernel/head.S这是解压内核后内核入口所在的文件,完成内核解压后将控制权将转移到这里的入口。先看一下 arch/arm/kernel/vmlinux.lds 这个链接脚本,在开头186. OUTPUT_ARCH(a...

weixin_32521765的博客 322

head.s分析(19):跳转到main

//jump.l _start_kernel; jump.l _main; ENDPROC(_real_start) 哈哈,终于要进入main了,原来是要跳转到start_kernel,在这里为了满足vdsp的调试需要,先跳转到main函数。 Head.s分析至此结束!...

xiaoer 106

spark架构代码分析-head.s启动代码分析

基本介绍         这是几年前在做sparc架构开发学习的时候写的技术文档,时间过了很久了,可能很多细节自己已经忘记了,这次把他分享在这里,现在国内估计很少还有人关注sparc架构。这里是第一片,分析的是head.S这段内核执行的第一段汇编代码,是基于2.6.32版本内核的。 正文   &nb...

sungeshilaoda的博客 648

Linux0.11内核源码分析(head.s)

head大小为25KB+184B,随后才是main函数。 head创建了内核分页机制(页目录表,页表,缓冲区,GDT,IDT,并将已经执行过的代码所占内存空间覆盖) 0x0000~0x4FFF,20KB将作为页目录表 先设置寄存器ds,es,fs,gs: .text .globl _idt,_gdt,_pg_dir,_tmp_floppy_area _pg_dir: startup_32: movl $0x10,%eax mov %ax,%ds mov %ax,%es mov %ax,%f

weixin_41418994的博客 739
上一篇: Linux 2.6.11 MTD驱动情景分析
下一篇: zImage内核镜像解压过程详解
hellolwl
博客等级 码龄24年 16粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值