[LINUX] Lire un peu plus arch / arm / boot / compressé / Makefile

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/compressed/Makefile?h=master

Lisez le contenu du Makefile. Omettez la partie fdt qui ne vous intéresse pas.

Paramètres de la zone TEXTE, etc.

arch/arm/boot/compressed/Makefile


# SPDX-License-Identifier: GPL-2.0
#
# linux/arch/arm/boot/compressed/Makefile
#
# create a compressed vmlinuz image from the original vmlinux
#

OBJS		=
AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET)

Cela signifie ajouter l'option TEXT_OFFSET lors de la création de head.o.

TEXT_OFFSET $ (TEXT_OFFSET) est défini dans arch / arm / Makefile.

arch/arm/Makefile


# Text offset. This list is sorted numerically by address in order to
# provide a means to avoid/resolve conflicts in multi-arch kernels.
textofs-y	:= 0x00008000
# We don't want the htc bootloader to corrupt kernel during resume
textofs-$(CONFIG_PM_H1940)      := 0x00108000
# SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory
ifeq ($(CONFIG_ARCH_SA1100),y)
textofs-$(CONFIG_SA1111) := 0x00208000
endif
textofs-$(CONFIG_ARCH_IPQ40XX) := 0x00208000
textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
textofs-$(CONFIG_ARCH_MESON) := 0x00208000
textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000

(Omis)

TEXT_OFFSET := $(textofs-y)

Code qui traite réellement comme un noyau (head. * / Misc. * / Decompress. *)

arch/arm/boot/compressed/Makefile


HEAD	= head.o
OBJS	+= misc.o decompress.o

head.S C'est la logique de la section d'extension du noyau Linux compressé elle-même.

Faites différentes choses, mais appelez decompress_kernel.

arch/arm/boot/compressed/head.S


/*
 * The C runtime environment should now be setup sufficiently.
 * Set up some pointers, and start decompressing.
 *   r4  = kernel execution address
 *   r7  = architecture ID
 *   r8  = atags pointer
 */
		mov	r0, r4
		mov	r1, sp			@ malloc space above stack
		add	r2, sp, #0x10000	@ 64k max
		mov	r3, r7
		bl	decompress_kernel

misc.S Le corps principal de decompress_kernel () est décrit.

En fait, do_decompress () est appelé à partir de cela.

arch/arm/boot/compressed/misc.c


void
decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
		unsigned long free_mem_ptr_end_p,
		int arch_id)
{
	int ret;

	output_data		= (unsigned char *)output_start;
	free_mem_ptr		= free_mem_ptr_p;
	free_mem_end_ptr	= free_mem_ptr_end_p;
	__machine_arch_type	= arch_id;

	arch_decomp_setup();

	putstr("Uncompressing Linux...");
	ret = do_decompress(input_data, input_data_end - input_data,
			    output_data, error);
	if (ret)
		error("decompressor returned an error");
	else
		putstr(" done, booting the kernel.\n");
}

decompress.S

La partie à décompresser en appelant __decompress () de chaque module de compression.

arch/arm/boot/compressed/decompress.c


#ifdef CONFIG_KERNEL_GZIP
#include "../../../../lib/decompress_inflate.c"
#endif

#ifdef CONFIG_KERNEL_LZO
#include "../../../../lib/decompress_unlzo.c"
#endif

#ifdef CONFIG_KERNEL_LZMA
#include "../../../../lib/decompress_unlzma.c"
#endif

#ifdef CONFIG_KERNEL_XZ
#define memmove memmove
#define memcpy memcpy
#include "../../../../lib/decompress_unxz.c"
#endif

#ifdef CONFIG_KERNEL_LZ4
#include "../../../../lib/decompress_unlz4.c"
#endif

int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
{
	return __decompress(input, len, NULL, NULL, output, 0, NULL, error);
}

Par exemple, pour lz4:

lib/decompress_unlz4.c


#ifdef PREBOOT
STATIC int INIT __decompress(unsigned char *buf, long in_len,
                  long (*fill)(void*, unsigned long),
                  long (*flush)(void*, unsigned long),
                  unsigned char *output, long out_len,
                  long *posp,
                  void (*error)(char *x)
    )
{
    return unlz4(buf, in_len - 4, fill, flush, output, posp, error);
}
#endif

Sortie de caractères pour le débogage

arch/arm/boot/compressed/Makefile


ifeq ($(CONFIG_DEBUG_UNCOMPRESS),y)
OBJS	+= debug.o
endif
FONTC	= $(srctree)/lib/fonts/font_acorn_8x8.c

Je pense que font_acorn_8x8.c n'est pas utilisé sauf pour le gland ...

DEBUG_UNCOMPRESS

DEBUG_UNCOMPRESS est défini dans KConfig.debug.

Cette option concerne la sortie du décompresseur sur le noyau multiplateforme. Habituellement, le décompresseur n'est pas bon pour les noyaux multiplateformes. Parce que je ne sais pas où envoyer la sortie du décompresseur.

Si cette option est définie, elle sera réutilisée par les moyens de sortie DEBUG_LL.

Vous pouvez donc le déboguer.

arch/arm/Kconfig.debug


config DEBUG_UNCOMPRESS
	bool "Enable decompressor debugging via DEBUG_LL output"
	depends on ARCH_MULTIPLATFORM || PLAT_SAMSUNG || ARM_SINGLE_ARMV7M
	depends on DEBUG_LL && !DEBUG_OMAP2PLUS_UART && \
		     (!DEBUG_TEGRA_UART || !ZBOOT_ROM) && \
		     !DEBUG_BRCMSTB_UART
	help
	  This option influences the normal decompressor output for
	  multiplatform kernels.  Normally, multiplatform kernels disable
	  decompressor output because it is not possible to know where to
	  send the decompressor output.

	  When this option is set, the selected DEBUG_LL output method
	  will be re-used for normal decompressor output on multiplatform
	  kernels.

debug.S

debug.s est utilisé pour l'implémentation de putc (). Si CONFIG_DEBUG_SEMIHOSTING est désactivé, adduart / waituart / senduart / busyuart imprime des caractères sur la console.

arm/boot/compressed/debug.S


/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/linkage.h>
#include <asm/assembler.h>

#ifndef CONFIG_DEBUG_SEMIHOSTING

#include CONFIG_DEBUG_LL_INCLUDE

ENTRY(putc)
	addruart r1, r2, r3
	waituart r3, r1
	senduart r0, r1
	busyuart r3, r1
	mov	 pc, lr
ENDPROC(putc)

#else
(Omis)

string library

string.c est un sous-ensemble tel que memcpu / memmove / strlen / strnlen. On estime qu'il est intégré pour que le décompresseur puisse se déplacer indépendamment lorsqu'il se déplace.

arch/arm/boot/compressed/Makefile


# string library code (-Os is enforced to keep it much smaller)
OBJS		+= string.o
CFLAGS_string.o	:= -Os

string.c

Le contenu est une implémentation d'une version simplifiée de la fonction définie dans string.h.

arch/arm/boot/compressed/string.c


void *memcpy(void *__dest, __const void *__src, size_t __n)
{
	int i = 0;
	unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;

	for (i = __n >> 3; i > 0; i--) {
		*d++ = *s++;
		*d++ = *s++;
		*d++ = *s++;
		*d++ = *s++;
		*d++ = *s++;
		*d++ = *s++;
		*d++ = *s++;
		*d++ = *s++;
	}

	if (__n & 1 << 2) {
		*d++ = *s++;
		*d++ = *s++;
		*d++ = *s++;
		*d++ = *s++;
	}

	if (__n & 1 << 1) {
		*d++ = *s++;
		*d++ = *s++;
	}

	if (__n & 1)
		*d++ = *s++;

	return __dest;
}

VIRT_EXT

arch/arm/boot/compressed/Makefile


ifeq ($(CONFIG_ARM_VIRT_EXT),y)
OBJS		+= hyp-stub.o
endif

ARM_VIRT_EXT

arch/arm/mm/Kconfig


config ARM_VIRT_EXT
    bool
    default y if CPU_V7
    help
      Enable the kernel to make use of the ARM Virtualization
      Extensions to install hypervisors without run-time firmware
      assistance.

      A compliant bootloader is required in order to make maximum
      use of this feature.  Refer to Documentation/arm/booting.rst for
      details.

GCOV/KCOV

La fonction de débogage a été désactivée.

arch/arm/boot/compressed/Makefile


GCOV_PROFILE		:= n

# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
KCOV_INSTRUMENT		:= n

Pièce dépendante du modèle

Cette zone dépend du modèle, elle est donc omise.

arch/arm/boot/compressed/Makefile


#
# Architecture dependencies
#
ifeq ($(CONFIG_ARCH_ACORN),y)
OBJS		+= ll_char_wr.o font.o
endif

<Omis>

Spécification d'adresse (ZTEXTADDR / ZBSSADDR)

arch/arm/boot/compressed/Makefile


#
# We now have a PIC decompressor implementation.  Decompressors running
# from RAM should not define ZTEXTADDR.  Decompressors running directly
# from ROM or Flash must define ZTEXTADDR (preferably via the config)
# FIXME: Previous assignment to ztextaddr-y is lost here. See SHARK
ifeq ($(CONFIG_ZBOOT_ROM),y)
ZTEXTADDR	:= $(CONFIG_ZBOOT_ROM_TEXT)
ZBSSADDR	:= $(CONFIG_ZBOOT_ROM_BSS)
else
ZTEXTADDR	:= 0
ZBSSADDR	:= ALIGN(8)
endif

CPPFLAGS_vmlinux.lds := -DTEXT_START="$(ZTEXTADDR)" -DBSS_START="$(ZBSSADDR)"

Confirmation de la méthode de compression

Spécifiez le format de compression spécifié dans KConfig.

arch/arm/boot/compressed/Makefile



compress-$(CONFIG_KERNEL_GZIP) = gzip
compress-$(CONFIG_KERNEL_LZO)  = lzo
compress-$(CONFIG_KERNEL_LZMA) = lzma
compress-$(CONFIG_KERNEL_XZ)   = xzkern
compress-$(CONFIG_KERNEL_LZ4)  = lz4

partie fdt (omis)

arch/arm/boot/compressed/Makefile



# Borrowed libfdt files for the ATAG compatibility mode
<Omis>

Paramètres des fichiers cibles / nettoyés pour Make

arch/arm/boot/compressed/Makefile


targets       := vmlinux vmlinux.lds piggy_data piggy.o \
		 lib1funcs.o ashldi3.o bswapsdi2.o \
		 head.o $(OBJS)

clean-files += piggy_data lib1funcs.S ashldi3.S bswapsdi2.S \
		$(libfdt) $(libfdt_hdrs) hyp-stub.S

KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING

ifeq ($(CONFIG_FUNCTION_TRACER),y)
ORIG_CFLAGS := $(KBUILD_CFLAGS)
KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
endif

fdt partie 2 (omis)

Il semble qu'il soit encore trop tôt pour utiliser stack-protector-strong.

arch/arm/boot/compressed/Makefile


# -fstack-protector-strong triggers protection checks in this code,
# but it is being used too early to link to meaningful stack_chk logic.
nossp-flags-$(CONFIG_CC_HAS_STACKPROTECTOR_NONE) := -fno-stack-protector
CFLAGS_atags_to_fdt.o := $(nossp-flags-y)
<Omis>

Spécification de taille BSS.

Il semble qu'il soit calculé en utilisant entre \ _ \ _ bss_start et \ _ \ _ bss_stop. Il est communiqué en option à Linker.

arch/arm/boot/compressed/Makefile


# Supply kernel BSS size to the decompressor via a linker symbol.
KBSS_SZ = $(shell echo $$(($$($(NM) $(obj)/../../../../vmlinux | \
		sed -n -e 's/^\([^ ]*\) [AB] __bss_start$$/-0x\1/p' \
		       -e 's/^\([^ ]*\) [AB] __bss_stop$$/+0x\1/p') )) )
LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
# Supply ZRELADDR to the decompressor via a linker symbol.
ifneq ($(CONFIG_AUTO_ZRELADDR),y)
LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR)
endif

Autres paramètres lors de la liaison de vmlinux

arch/arm/boot/compressed/Makefile


ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
LDFLAGS_vmlinux += --be8
endif
# Report unresolved symbol references
LDFLAGS_vmlinux += --no-undefined
# Delete all temporary local symbols
LDFLAGS_vmlinux += -X
# Next argument is a linker script
LDFLAGS_vmlinux += -T

Correspondance pour des instructions inexistantes.

Déploiement de code prêt à jouer avec des fonctions inexistantes.

arch/arm/boot/compressed/Makefile


# For __aeabi_uidivmod
lib1funcs = $(obj)/lib1funcs.o

$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
	$(call cmd,shipped)

# For __aeabi_llsl
ashldi3 = $(obj)/ashldi3.o

$(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S
	$(call cmd,shipped)

# For __bswapsi2, __bswapdi2
bswapsdi2 = $(obj)/bswapsdi2.o

$(obj)/bswapsdi2.S: $(srctree)/arch/$(SRCARCH)/lib/bswapsdi2.S
	$(call cmd,shipped)

lib1funcs.S Cela semble être une routine d'optimisation de division.

https://gcc.gnu.org/onlinedocs/gccint/Integer-library-routines.html

Les fonctions suivantes, etc. sont incluses.

Runtime Function: int __divsi3 (int a, int b) Runtime Function: long __divdi3 (long a, long b) Runtime Function: long long __divti3 (long long a, long long b)   These functions return the quotient of the signed division of a and b.

arch/arm/lib/lib1funcs.S


/*
 * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines
 *
 * Author: Nicolas Pitre <[email protected]>
 *   - contributed to gcc-3.4 on Sep 30, 2003
 *   - adapted for the Linux kernel on Oct 2, 2003
 */

ashldi3.S/bswapsdi2.S https://gcc.gnu.org/onlinedocs/gccint/Integer-library-routines.html

Il y a une description de la fonction ici.

Runtime Function: int __ashlsi3 (int a, int b) Runtime Function: long __ashldi3 (long a, int b) Runtime Function: long long __ashlti3 (long long a, int b)   These functions return the result of shifting a left by b bits.

Runtime Function: int32_t __bswapsi2 (int32_t a) Runtime Function: int64_t __bswapdi2 (int64_t a)   These functions return the a byteswapped.

Vérifiez le symbole.

"Les symboles suivants ne doivent pas être de portée locale / privée", a-t-il déclaré.

arch/arm/boot/compressed/Makefile



# We need to prevent any GOTOFF relocs being used with references
# to symbols in the .bss section since we cannot relocate them
# independently from the rest at run time.  This can be achieved by
# ensuring that no private .bss symbols exist, as global symbols
# always have a GOT entry which is what we need.
# The .data section is already discarded by the linker script so no need
# to bother about it here.
check_for_bad_syms = \
bad_syms=$$($(NM) $@ | sed -n 's/^.\{8\} [bc] \(.*\)/\1/p') && \
[ -z "$$bad_syms" ] || \
  ( echo "following symbols must have non local/private scope:" >&2; \
    echo "$$bad_syms" >&2; false )

Vérification liée à ZRELADDR

Si ZRELADDR n'est pas défini et AUTO_ZRELADDR n'est pas défini, vais-je me mettre en colère?

arch/arm/boot/compressed/Makefile


check_for_multiple_zreladdr = \
if [ $(words $(ZRELADDR)) -gt 1 -a "$(CONFIG_AUTO_ZRELADDR)" = "" ]; then \
	echo 'multiple zreladdrs: $(ZRELADDR)'; \
	echo 'This needs CONFIG_AUTO_ZRELADDR to be set'; \
	false; \
fi

Compatible EFI

(Omis sans intérêt)

arch/arm/boot/compressed/Makefile


efi-obj-$(CONFIG_EFI_STUB) := $(objtree)/drivers/firmware/efi/libstub/lib.a

Comment faire vmlinux! !! (Ceci est la dernière ligne)

arch/arm/boot/compressed/Makefile


$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \
		$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) \
		$(bswapsdi2) $(efi-obj-y) FORCE
	@$(check_for_multiple_zreladdr)
	$(call if_changed,ld)
	@$(check_for_bad_syms)

Compresser l'image

compress-y contient le compresseur spécifié sous la forme compress- $ (CONFIG_KERNEL_XXXX) = CMD. Utilisez ceci pour convertir l'image en piggy_data

arch/arm/boot/compressed/Makefile



$(obj)/piggy_data: $(obj)/../Image FORCE
	$(call if_changed,$(compress-y))

$(obj)/piggy.o: $(obj)/piggy_data

piggy.S

J'ai importé piggy_data en tant que données binaires.

arch/arm/boot/compressed/piggy.S


/* SPDX-License-Identifier: GPL-2.0 */
	.section .piggydata, "a"
	.globl	input_data
input_data:
	.incbin	"arch/arm/boot/compressed/piggy_data"
	.globl	input_data_end
input_data_end:

Après cela, spécifiez diverses options

arch/arm/boot/compressed/Makefile



CFLAGS_font.o := -Dstatic=

$(obj)/font.c: $(FONTC)
	$(call cmd,shipped)

AFLAGS_hyp-stub.o := -Wa,-march=armv7-a

$(obj)/hyp-stub.S: $(srctree)/arch/$(SRCARCH)/kernel/hyp-stub.S
	$(call cmd,shipped)

Recommended Posts

Lire un peu plus arch / arm / boot / compressé / Makefile
Lire arc / bras / oprofile / common.c
Un peu plus sur le FIFO
Un peu plus de détails sur la notation d'inclusion de python
Gestion des exceptions Python un peu plus pratique