深圳市手机网站建设报价/网络推广公司运作
Linux 启动流程之自解压(一)
首先,我们要知道在zImage的生成过程中,是把arch/arm/boot/compressed/head.s 和解压代码misc.c,decompress.c加在压缩内核的最前面最终生成zImage的,那么它的启动过程就是从这个head.s开始的,并且如果代码从RAM运行的话,是与位置无关的,可以加载到内存的任何地方。
下面以linux-4.15.09 版本arch/arm/boot/compressed/head.s为主线进行启动过程解析。
1 head.s DEBUG宏定义部分
/** Debugging stuff** Note that these macros must not contain any code which is not* 100% relocatable. Any attempt to do so will result in a crash.* Please select one of the following when turning on debugging.*/
#ifdef DEBUG
//开启DEBUG,该功能可有两种方式实现。
//第一种方式:CONFIG_DEBUG_ICEDCC使用ARMv6以上架构支持的ICEDCC技术实现,
//DCC(Debug Communication Channel)是ARM的调试通信通道,在串口无法使用的时候可
//使用改通道进行通信。
//第二种方式:使用串口进行调试,通过配置CONFIG_DEBUG_LL_INCLUDE,
//包含相关平台操作串口的方法,其所用的串口配置参数依赖前一级
//BootLoader所配置好的串口。
#if defined(CONFIG_DEBUG_ICEDCC)#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7).macro loadsp, rb, tmp.endm.macro writeb, ch, rbmcr p14, 0, \ch, c0, c5, 0.endm
#elif defined(CONFIG_CPU_XSCALE).macro loadsp, rb, tmp.endm.macro writeb, ch, rbmcr p14, 0, \ch, c8, c0, 0.endm
#else.macro loadsp, rb, tmp.endm.macro writeb, ch, rbmcr p14, 0, \ch, c1, c0, 0.endm
#endif#else#include CONFIG_DEBUG_LL_INCLUDE
//添加平台操作串口的汇编代码,该部分汇编代码主要实现以下几个功能:
//1. 添加UART:addruart
//2. 发送数据:senduart
//3. 忙等待:busyuart
//4. 等待完成:waituart.macro writeb, ch, rbsenduart \ch, \rb.endm#if defined(CONFIG_ARCH_SA1100).macro loadsp, rb, tmpmov \rb, #0x80000000 @ physical base address
#ifdef CONFIG_DEBUG_LL_SER3add \rb, \rb, #0x00050000 @ Ser3
#elseadd \rb, \rb, #0x00010000 @ Ser1
#endif.endm
#else.macro loadsp, rb, tmpaddruart \rb, \tmp.endm
#endif
#endif
#endif
早期调试信息的实现方式://定义宏,输出字符.macro kputc,valmov r0, \valbl putc.endm.macro kphex,val,lenmov r0, \valmov r1, #\lenbl phex.endm//定义宏,用于输出cpu_id,arch_id等信息.macro debug_reloc_start
#ifdef DEBUGkputc #'\n'kphex r6, 8 /* processor id */kputc #':'kphex r7, 8 /* architecture id */
#ifdef CONFIG_CPU_CP15kputc #':'mrc p15, 0, r0, c1, c0kphex r0, 8 /* control reg */
#endifkputc #'\n'kphex r5, 8 /* decompressed kernel start */kputc #'-'kphex r9, 8 /* decompressed kernel end */kputc #'>'kphex r4, 8 /* kernel execution address */kputc #'\n'
#endif.endm.macro debug_reloc_end
#ifdef DEBUGkphex r5, 8 /* end of kernel */kputc #'\n'mov r0, r4bl memdump /* dump 256 bytes at start of kernel */
#endif.endm