Какие коды, такие как CC, LD и CC[M], выводятся при компиляции ядра Linux?
-
13-12-2019 - |
Вопрос
При компиляции Linux с нуля я понимаю, что во время компиляции появляются компилируемые коды.
Например, имя файла CC, имя файла LD, имя файла CC[M].
Что означают эти коды?
Решение
Различные маркировки указывают следующее
- .
- [cc] - компилирует файл C в назначенный объектный файл.Файл объекта содержит код ассемблера архитектуры этого файла .c.Поскольку это может также относиться к частям за пределами его объема.Например, вызывая другую функцию в другом файле .C.Вызывы функций остаются открыты в файле объекта, который позже включен линкером.Поэтому
- [ld] - это процессы связывания скомпилированных объектов вместе и проводят вызовы функций, которые остались открытыми компилятором.Однако многие детали связаны как основной частью ядра, в то время как некоторые части остаются.И, таким образом, вы видите
- [CC (M)] для тех частей, которые скомпилированы в виде точек, которые будут загружены в ядро во время выполнения.Но которые не связаны вместе в монолитной части ядра.Но вместо этого можно вставить, когда ядро загружается.
Другие советы
Давайте возьмем конкретный пример и разберемся, что он делает в ядре 4.1, например. IHEX
.
Узнайте, что делает код
Просто беги:
make SHELL='sh -x'
Как это работает: https://stackoverflow.com/a/32010960/895245
Если мы получим вывод для IHEX
, находим строки:
+ 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
поэтому мы приходим к выводу, что IHEX
делает objcopy -Iihex
.
Найдите, где определен код
Каждая команда ядра должна быть определена примерно так:
quiet_cmd_ihex = IHEX $@
cmd_ihex = $(OBJCOPY) -Iihex -Obinary $< $@
$(obj)/%: $(obj)/%.ihex
$(call cmd,ihex)
для настроек детализации (например, V=1
и make -s
) работать.
В общем, вам просто нужно
git grep 'cmd.* = CODE'
найти CODE
.
Я подробно объяснил, как работает эта система: https://stackoverflow.com/a/32023861/895245
Получить список всех кодов
make | grep -E '^ ' | sort -uk1,1
СС и СС [М]
Определено в scripts/Makefile.build
:
quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
и [M]
происходит из целевые конкретные переменные:
$(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]
Затем он вызывается через:
$(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); \
где if_changed_rule
определяется в scripts/Kbuild.include
как:
if_changed_rule = $(if $(strip $(any-prereq) $(arg-check) ), \
@set -e; \
$(rule_$(1)))
и Kbuild.include
включается в Makefile верхнего уровня.
ЛД
Есть несколько версий, но самая простая выглядит так:
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)
И в 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)
Он должен показать:
CC
при компиляции основной части ядраCC [M]
при компиляции модуляLD
при связывании