O que são os códigos como o CC, LD e CC[M] saída quando compilando o kernel do Linux?
-
13-12-2019 - |
Pergunta
Ao compilar o Linux a partir do zero percebo que há de compilação de códigos que aparecem durante a compilação.
Por exemplo CC de nome de arquivo , LD nome de arquivo, CC[M] nome do arquivo.
O que esses códigos significa?
Solução
As marcas diferentes especificam o seguinte
- [CC] - compila o arquivo C em um arquivo de objeto designado.O arquivo de objeto contém o código do montador do Archicture desse arquivo .c.Como também pode referência a peças fora de seu escopo.Por exemplo, chamando outra função em outro arquivo .c.As chamadas de função são deixadas abertas no arquivo de objeto, que é mais tarde incluído pelo vinculador.Portanto
- [LD] é os processos de ligar os objetos compilados juntos e conectar as chamadas de função que foi deixada aberta pelo compilador.No entanto, muitas partes estão ligadas como parte central do kernel, enquanto algumas partes são deixadas de fora.E assim você vê
- [cc (m)] para as partes que são compiladas como pontos a serem carregados no kernel ao tempo de execução.Mas que não estão ligados juntos na parte monolítica do kernel.Mas em vez disso pode ser inserido quando o kernel é inicializado.
Outras dicas
Vamos dar um exemplo específico e descobrir o que ele faz no kernel 4.1, por exemplo, IHEX
.
Encontrar que um código não
Basta executar:
make SHELL='sh -x'
Como funciona: https://stackoverflow.com/a/32010960/895245
Se nós a saída para o grep IHEX
, encontramos as linhas:
+ echo IHEX firmware/e100/d101s_ucode.bin
IHEX firmware/e100/d101s_ucode.bin
+ objcopy -Iihex -Obinary /home/ciro/git/kernel/src/firmware/e100/d101s_ucode.bin.ihex firmware/e100/d101s_ucode.bin
então podemos concluir que IHEX
faz um objcopy -Iihex
.
Onde encontrar um código é definido
Todos os comandos do 'kernel' deve ser definido com algo como:
quiet_cmd_ihex = IHEX $@
cmd_ihex = $(OBJCOPY) -Iihex -Obinary $< $@
$(obj)/%: $(obj)/%.ihex
$(call cmd,ihex)
para as definições de verbosidade (e.g. V=1
e make -s
) para o trabalho.
Por isso, em geral, você só tem que
git grep 'cmd.* = CODE'
para encontrar CODE
.
Eu tenho explicado em detalhes como este sistema funciona em: https://stackoverflow.com/a/32023861/895245
Obter a lista de todos os códigos
make | grep -E '^ ' | sort -uk1,1
CC e CC [M]
Definido no scripts/Makefile.build
:
quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
e o [M]
vem do alvo de variáveis específicas:
$(real-objs-m) : quiet_modtag := [M]
$(real-objs-m:.o=.i) : quiet_modtag := [M]
$(real-objs-m:.o=.s) : quiet_modtag := [M]
$(real-objs-m:.o=.lst): quiet_modtag := [M]
$(obj-m) : quiet_modtag := [M]
Em seguida, ele é chamado através de:
$(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE
[...]
$(call if_changed_rule,cc_o_c)
define rule_cc_o_c
[...]
$(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \
onde if_changed_rule
é definido no scripts/Kbuild.include
como:
if_changed_rule = $(if $(strip $(any-prereq) $(arg-check) ), \
@set -e; \
$(rule_$(1)))
e Kbuild.include
fica incluído no nível superior Makefile.
LD
Existem algumas versões, mas a mais simples parece ser:
quiet_cmd_link_o_target = LD $@
cmd_link_o_target = $(if $(strip $(obj-y)),\
$(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^) \
$(cmd_secanalysis),\
rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) $@)
$(builtin-target): $(obj-y) FORCE
$(call if_changed,link_o_target)
e no scripts/Kbuild.include
:
# Execute command if command has changed or prerequisite(s) are updated.
#
if_changed = $(if $(strip $(any-prereq) $(arg-check)), \
@set -e; \
$(echo-cmd) $(cmd_$(1)); \
printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)
deve mostrar:
-
CC
ao compilar uma parte central do kernel -
CC [M]
ao compilar um módulo -
LD
ao vincular