← Documents Documentation/kbuild/modules.rst GitHub 원문 ↗

Linux 6.18.37 · Kbuild

Building External Modules

외부 kernel module의 build, Kbuild file 구성, header 경로, 설치, symbol versioning과 MODPOST 연동을 설명합니다.

Source pathDocumentation/kbuild/modules.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

modules.rst:1-512

External module은 대상 kernel의 configuration·header·build artifact를 사용해야 하며 `M=`으로 module source 위치를 kbuild에 전달합니다. Linux 6.13부터 `-f`와 kernel Makefile 직접 include 방식도 사용할 수 있습니다.

Build file은 `obj-m`과 `<module>-y`로 module과 구성 object를 선언합니다. Wrapper Makefile은 편의 target을 제공하고, 큰 project에서는 kbuild 선언을 별도 `Kbuild` file로 분리하는 편이 명확합니다.

설치 path는 `INSTALL_MOD_PATH`와 `INSTALL_MOD_DIR`로 조정합니다. ABI versioning과 external module 간 symbol 의존성은 `Module.symvers`, MODPOST, 공통 top-level Kbuild 또는 `KBUILD_EXTRA_SYMBOLS`가 담당합니다.

External module 생명주기
대상 kernel tree 준비Kbuild goal과 header path 선언`M=`·선택적 `MO=`로 buildMODPOST symbol·CRC 검증`.ko`와 external `Module.symvers` 생성`modules_install`로 release별 directory에 설치

Source 준비부터 설치와 symbol 연동까지의 핵심 단계입니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 =========================
2 Building External Modules
3 =========================
4
5 This document describes how to build an out-of-tree kernel module.
6
7 Introduction
8 ============
9
10 "kbuild" is the build system used by the Linux kernel. Modules must use
11 kbuild to stay compatible with changes in the build infrastructure and
12 to pick up the right flags to the compiler. Functionality for building modules
13 both in-tree and out-of-tree is provided. The method for building
14 either is similar, and all modules are initially developed and built
15 out-of-tree.
16
17 Covered in this document is information aimed at developers interested
18 in building out-of-tree (or "external") modules. The author of an
19 external module should supply a makefile that hides most of the
20 complexity, so one only has to type "make" to build the module. This is
21 easily accomplished, and a complete example will be presented in
22 section `Creating a Kbuild File for an External Module`_.
23
24
25 How to Build External Modules
26 =============================
27
28 To build external modules, you must have a prebuilt kernel available
29 that contains the configuration and header files used in the build.
30 Also, the kernel must have been built with modules enabled. If you are
31 using a distribution kernel, there will be a package for the kernel you
32 are running provided by your distribution.
33
34 An alternative is to use the "make" target "modules_prepare." This will
35 make sure the kernel contains the information required. The target
36 exists solely as a simple way to prepare a kernel source tree for
37 building external modules.
38
39 NOTE: "modules_prepare" will not build Module.symvers even if
40 CONFIG_MODVERSIONS is set; therefore, a full kernel build needs to be
41 executed to make module versioning work.
42
43 Command Syntax
44 --------------
45
46 The command to build an external module is::
47
48 $ make -C <path_to_kernel_dir> M=$PWD
49
50 The kbuild system knows that an external module is being built
51 due to the "M=<dir>" option given in the command.
52
53 To build against the running kernel use::
54
55 $ make -C /lib/modules/`uname -r`/build M=$PWD
56
57 Then to install the module(s) just built, add the target
58 "modules_install" to the command::
59
60 $ make -C /lib/modules/`uname -r`/build M=$PWD modules_install
61
62 Starting from Linux 6.13, you can use the -f option instead of -C. This
63 will avoid unnecessary change of the working directory. The external
64 module will be output to the directory where you invoke make.
65
66 $ make -f /lib/modules/`uname -r`/build/Makefile M=$PWD
67
68 Options
69 -------
70
71 ($KDIR refers to the path of the kernel source directory, or the path
72 of the kernel output directory if the kernel was built in a separate
73 build directory.)
74
75 You can optionally pass MO= option if you want to build the modules in
76 a separate directory.
77
78 make -C $KDIR M=$PWD [MO=$BUILD_DIR]
79
80 -C $KDIR
81 The directory that contains the kernel and relevant build
82 artifacts used for building an external module.
83 "make" will actually change to the specified directory
84 when executing and will change back when finished.
85
86 M=$PWD
87 Informs kbuild that an external module is being built.
88 The value given to "M" is the absolute path of the
89 directory where the external module (kbuild file) is
90 located.
91
92 MO=$BUILD_DIR
93 Specifies a separate output directory for the external module.
94
95 Targets
96 -------
97
98 When building an external module, only a subset of the "make"
99 targets are available.
100
101 make -C $KDIR M=$PWD [target]
102
103 The default will build the module(s) located in the current
104 directory, so a target does not need to be specified. All
105 output files will also be generated in this directory. No
106 attempts are made to update the kernel source, and it is a
107 precondition that a successful "make" has been executed for the
108 kernel.
109
110 modules
111 The default target for external modules. It has the
112 same functionality as if no target was specified. See
113 description above.
114
115 modules_install
116 Install the external module(s). The default location is
117 /lib/modules/<kernel_release>/updates/, but a prefix may
118 be added with INSTALL_MOD_PATH (discussed in section
119 `Module Installation`_).
120
121 clean
122 Remove all generated files in the module directory only.
123
124 help
125 List the available targets for external modules.
126
127 Building Separate Files
128 -----------------------
129
130 It is possible to build single files that are part of a module.
131 This works equally well for the kernel, a module, and even for
132 external modules.
133
134 Example (The module foo.ko, consist of bar.o and baz.o)::
135
136 make -C $KDIR M=$PWD bar.lst
137 make -C $KDIR M=$PWD baz.o
138 make -C $KDIR M=$PWD foo.ko
139 make -C $KDIR M=$PWD ./
140
141
142 Creating a Kbuild File for an External Module
143 =============================================
144
145 In the last section we saw the command to build a module for the
146 running kernel. The module is not actually built, however, because a
147 build file is required. Contained in this file will be the name of
148 the module(s) being built, along with the list of requisite source
149 files. The file may be as simple as a single line::
150
151 obj-m := <module_name>.o
152
153 The kbuild system will build <module_name>.o from <module_name>.c,
154 and, after linking, will result in the kernel module <module_name>.ko.
155 The above line can be put in either a "Kbuild" file or a "Makefile."
156 When the module is built from multiple sources, an additional line is
157 needed listing the files::
158
159 <module_name>-y := <src1>.o <src2>.o ...
160
161 NOTE: Further documentation describing the syntax used by kbuild is
162 located in Documentation/kbuild/makefiles.rst.
163
164 The examples below demonstrate how to create a build file for the
165 module 8123.ko, which is built from the following files::
166
167 8123_if.c
168 8123_if.h
169 8123_pci.c
170
171 Shared Makefile
172 ---------------
173
174 An external module always includes a wrapper makefile that
175 supports building the module using "make" with no arguments.
176 This target is not used by kbuild; it is only for convenience.
177 Additional functionality, such as test targets, can be included
178 but should be filtered out from kbuild due to possible name
179 clashes.
180
181 Example 1::
182
183 --> filename: Makefile
184 ifneq ($(KERNELRELEASE),)
185 # kbuild part of makefile
186 obj-m := 8123.o
187 8123-y := 8123_if.o 8123_pci.o
188
189 else
190 # normal makefile
191 KDIR ?= /lib/modules/`uname -r`/build
192
193 default:
194 $(MAKE) -C $(KDIR) M=$$PWD
195
196 endif
197
198 The check for KERNELRELEASE is used to separate the two parts
199 of the makefile. In the example, kbuild will only see the two
200 assignments, whereas "make" will see everything except these
201 two assignments. This is due to two passes made on the file:
202 the first pass is by the "make" instance run on the command
203 line; the second pass is by the kbuild system, which is
204 initiated by the parameterized "make" in the default target.
205
206 Separate Kbuild File and Makefile
207 ---------------------------------
208
209 Kbuild will first look for a file named "Kbuild", and if it is not
210 found, it will then look for "Makefile". Utilizing a "Kbuild" file
211 allows us to split up the "Makefile" from example 1 into two files:
212
213 Example 2::
214
215 --> filename: Kbuild
216 obj-m := 8123.o
217 8123-y := 8123_if.o 8123_pci.o
218
219 --> filename: Makefile
220 KDIR ?= /lib/modules/`uname -r`/build
221
222 default:
223 $(MAKE) -C $(KDIR) M=$$PWD
224
225 The split in example 2 is questionable due to the simplicity of
226 each file; however, some external modules use makefiles
227 consisting of several hundred lines, and here it really pays
228 off to separate the kbuild part from the rest.
229
230 Linux 6.13 and later support another way. The external module Makefile
231 can include the kernel Makefile directly, rather than invoking sub Make.
232
233 Example 3::
234
235 --> filename: Kbuild
236 obj-m := 8123.o
237 8123-y := 8123_if.o 8123_pci.o
238
239 --> filename: Makefile
240 KDIR ?= /lib/modules/$(shell uname -r)/build
241 export KBUILD_EXTMOD := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
242 include $(KDIR)/Makefile
243
244
245 Building Multiple Modules
246 -------------------------
247
248 kbuild supports building multiple modules with a single build
249 file. For example, if you wanted to build two modules, foo.ko
250 and bar.ko, the kbuild lines would be::
251
252 obj-m := foo.o bar.o
253 foo-y := <foo_srcs>
254 bar-y := <bar_srcs>
255
256 It is that simple!
257
258
259 Include Files
260 =============
261
262 Within the kernel, header files are kept in standard locations
263 according to the following rule:
264
265 * If the header file only describes the internal interface of a
266 module, then the file is placed in the same directory as the
267 source files.
268 * If the header file describes an interface used by other parts
269 of the kernel that are located in different directories, then
270 the file is placed in include/linux/.
271
272 NOTE:
273 There are two notable exceptions to this rule: larger
274 subsystems have their own directory under include/, such as
275 include/scsi; and architecture specific headers are located
276 under arch/$(SRCARCH)/include/.
277
278 Kernel Includes
279 ---------------
280
281 To include a header file located under include/linux/, simply
282 use::
283
284 #include <linux/module.h>
285
286 kbuild will add options to the compiler so the relevant directories
287 are searched.
288
289 Single Subdirectory
290 -------------------
291
292 External modules tend to place header files in a separate
293 include/ directory where their source is located, although this
294 is not the usual kernel style. To inform kbuild of the
295 directory, use either ccflags-y or CFLAGS_<filename>.o.
296
297 Using the example from section 3, if we moved 8123_if.h to a
298 subdirectory named include, the resulting kbuild file would
299 look like::
300
301 --> filename: Kbuild
302 obj-m := 8123.o
303
304 ccflags-y := -I $(src)/include
305 8123-y := 8123_if.o 8123_pci.o
306
307 Several Subdirectories
308 ----------------------
309
310 kbuild can handle files that are spread over several directories.
311 Consider the following example::
312
313 .
314 |__ src
315 | |__ complex_main.c
316 | |__ hal
317 | |__ hardwareif.c
318 | |__ include
319 | |__ hardwareif.h
320 |__ include
321 |__ complex.h
322
323 To build the module complex.ko, we then need the following
324 kbuild file::
325
326 --> filename: Kbuild
327 obj-m := complex.o
328 complex-y := src/complex_main.o
329 complex-y += src/hal/hardwareif.o
330
331 ccflags-y := -I$(src)/include
332 ccflags-y += -I$(src)/src/hal/include
333
334 As you can see, kbuild knows how to handle object files located
335 in other directories. The trick is to specify the directory
336 relative to the kbuild file's location. That being said, this
337 is NOT recommended practice.
338
339 For the header files, kbuild must be explicitly told where to
340 look. When kbuild executes, the current directory is always the
341 root of the kernel tree (the argument to "-C") and therefore an
342 absolute path is needed. $(src) provides the absolute path by
343 pointing to the directory where the currently executing kbuild
344 file is located.
345
346
347 Module Installation
348 ===================
349
350 Modules which are included in the kernel are installed in the
351 directory:
352
353 /lib/modules/$(KERNELRELEASE)/kernel/
354
355 And external modules are installed in:
356
357 /lib/modules/$(KERNELRELEASE)/updates/
358
359 INSTALL_MOD_PATH
360 ----------------
361
362 Above are the default directories but as always some level of
363 customization is possible. A prefix can be added to the
364 installation path using the variable INSTALL_MOD_PATH::
365
366 $ make INSTALL_MOD_PATH=/frodo modules_install
367 => Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel/
368
369 INSTALL_MOD_PATH may be set as an ordinary shell variable or,
370 as shown above, can be specified on the command line when
371 calling "make." This has effect when installing both in-tree
372 and out-of-tree modules.
373
374 INSTALL_MOD_DIR
375 ---------------
376
377 External modules are by default installed to a directory under
378 /lib/modules/$(KERNELRELEASE)/updates/, but you may wish to
379 locate modules for a specific functionality in a separate
380 directory. For this purpose, use INSTALL_MOD_DIR to specify an
381 alternative name to "updates."::
382
383 $ make INSTALL_MOD_DIR=gandalf -C $KDIR \
384 M=$PWD modules_install
385 => Install dir: /lib/modules/$(KERNELRELEASE)/gandalf/
386
387
388 Module Versioning
389 =================
390
391 Module versioning is enabled by the CONFIG_MODVERSIONS tag, and is used
392 as a simple ABI consistency check. A CRC value of the full prototype
393 for an exported symbol is created. When a module is loaded/used, the
394 CRC values contained in the kernel are compared with similar values in
395 the module; if they are not equal, the kernel refuses to load the
396 module.
397
398 Module.symvers contains a list of all exported symbols from a kernel
399 build.
400
401 Symbols From the Kernel (vmlinux + modules)
402 -------------------------------------------
403
404 During a kernel build, a file named Module.symvers will be
405 generated. Module.symvers contains all exported symbols from
406 the kernel and compiled modules. For each symbol, the
407 corresponding CRC value is also stored.
408
409 The syntax of the Module.symvers file is::
410
411 <CRC> <Symbol> <Module> <Export Type> <Namespace>
412
413 0xe1cc2a05 usb_stor_suspend drivers/usb/storage/usb-storage EXPORT_SYMBOL_GPL USB_STORAGE
414
415 The fields are separated by tabs and values may be empty (e.g.
416 if no namespace is defined for an exported symbol).
417
418 For a kernel build without CONFIG_MODVERSIONS enabled, the CRC
419 would read 0x00000000.
420
421 Module.symvers serves two purposes:
422
423 1) It lists all exported symbols from vmlinux and all modules.
424 2) It lists the CRC if CONFIG_MODVERSIONS is enabled.
425
426 Version Information Formats
427 ---------------------------
428
429 Exported symbols have information stored in __ksymtab or __ksymtab_gpl
430 sections. Symbol names and namespaces are stored in __ksymtab_strings,
431 using a format similar to the string table used for ELF. If
432 CONFIG_MODVERSIONS is enabled, the CRCs corresponding to exported
433 symbols will be added to the __kcrctab or __kcrctab_gpl.
434
435 If CONFIG_BASIC_MODVERSIONS is enabled (default with
436 CONFIG_MODVERSIONS), imported symbols will have their symbol name and
437 CRC stored in the __versions section of the importing module. This
438 mode only supports symbols of length up to 64 bytes.
439
440 If CONFIG_EXTENDED_MODVERSIONS is enabled (required to enable both
441 CONFIG_MODVERSIONS and CONFIG_RUST at the same time), imported symbols
442 will have their symbol name recorded in the __version_ext_names
443 section as a series of concatenated, null-terminated strings. CRCs for
444 these symbols will be recorded in the __version_ext_crcs section.
445
446 Symbols and External Modules
447 ----------------------------
448
449 When building an external module, the build system needs access
450 to the symbols from the kernel to check if all external symbols
451 are defined. This is done in the MODPOST step. modpost obtains
452 the symbols by reading Module.symvers from the kernel source
453 tree. During the MODPOST step, a new Module.symvers file will be
454 written containing all exported symbols from that external module.
455
456 Symbols From Another External Module
457 ------------------------------------
458
459 Sometimes, an external module uses exported symbols from
460 another external module. Kbuild needs to have full knowledge of
461 all symbols to avoid spitting out warnings about undefined
462 symbols. Two solutions exist for this situation.
463
464 NOTE: The method with a top-level kbuild file is recommended
465 but may be impractical in certain situations.
466
467 Use a top-level kbuild file
468 If you have two modules, foo.ko and bar.ko, where
469 foo.ko needs symbols from bar.ko, you can use a
470 common top-level kbuild file so both modules are
471 compiled in the same build. Consider the following
472 directory layout::
473
474 ./foo/ <= contains foo.ko
475 ./bar/ <= contains bar.ko
476
477 The top-level kbuild file would then look like::
478
479 #./Kbuild (or ./Makefile):
480 obj-m := foo/ bar/
481
482 And executing::
483
484 $ make -C $KDIR M=$PWD
485
486 will then do the expected and compile both modules with
487 full knowledge of symbols from either module.
488
489 Use "make" variable KBUILD_EXTRA_SYMBOLS
490 If it is impractical to add a top-level kbuild file,
491 you can assign a space separated list
492 of files to KBUILD_EXTRA_SYMBOLS in your build file.
493 These files will be loaded by modpost during the
494 initialization of its symbol tables.
495
496
497 Tips & Tricks
498 =============
499
500 Testing for CONFIG_FOO_BAR
501 --------------------------
502
503 Modules often need to check for certain `CONFIG_` options to
504 decide if a specific feature is included in the module. In
505 kbuild this is done by referencing the `CONFIG_` variable
506 directly::
507
508 #fs/ext2/Makefile
509 obj-$(CONFIG_EXT2_FS) += ext2.o
510
511 ext2-y := balloc.o bitmap.o dir.o
512 ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o
513

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

소개와 외부 모듈 빌드

1-76

이 문서는 source tree 밖에서 개발하는 out-of-tree kernel module, 즉 external module을 build하는 방법을 설명합니다. Linux kernel의 build system인 kbuild를 사용해야 build infrastructure의 변경과 compiler flag를 올바르게 따라갈 수 있습니다. In-tree와 out-of-tree module의 build 방식은 비슷하며, module은 처음에는 대개 source tree 밖에서 개발됩니다.

External module 작성자는 사용자가 인자 없이 `make`만 실행해도 module을 build할 수 있도록 복잡성을 감싼 Makefile을 제공해야 합니다. 이 문서의 `Creating a Kbuild File for an External Module` 절에서 완전한 예제를 제시합니다.

External module을 build하려면 build에 사용된 configuration과 header를 포함하는 미리 build된 kernel이 필요하고, kernel에서 module 기능이 활성화되어 있어야 합니다. Distribution kernel을 사용한다면 실행 중인 kernel에 대응하는 개발 package를 distribution에서 설치할 수 있습니다.

대안으로 kernel source tree에서 `make modules_prepare`를 실행할 수 있습니다. 이 target은 external module build에 필요한 정보를 준비하지만, `CONFIG_MODVERSIONS`가 설정되어 있어도 `Module.symvers`는 생성하지 않습니다. 따라서 module versioning이 필요하면 full kernel build를 수행해야 합니다.

External module build 흐름
Kernel configuration·header와 module 지원 확인필요하면 `modules_prepare`, versioning이면 full kernel buildExternal module directory에 Kbuild 또는 Makefile 작성`make -C $KDIR M=$PWD`로 kbuild 호출Compile·link·MODPOST를 거쳐 `.ko` 생성`modules_install`로 release별 module directory에 설치

준비된 kernel tree와 module directory를 kbuild에 연결하는 순서입니다.

기본 command는 `$ make -C <path_to_kernel_dir> M=$PWD`입니다. `M=<dir>`가 external module build임을 kbuild에 알립니다. 실행 중인 kernel을 대상으로 할 때는 `$ make -C /lib/modules/\`uname -r\`/build M=$PWD`를 사용하고, 설치하려면 끝에 `modules_install` target을 붙입니다.

Linux 6.13부터는 `-C` 대신 `-f /lib/modules/\`uname -r\`/build/Makefile`을 사용할 수 있습니다. 이 방식은 working directory를 불필요하게 바꾸지 않으며, make를 호출한 directory에 external module output을 생성합니다.

External module build option
Option의미
`-C $KDIR`Kernel과 external module build artifact가 있는 directory로 이동해 make 실행
`-f $KDIR/Makefile`Linux 6.13 이상에서 directory 변경 없이 kernel Makefile 실행
`M=$PWD`External module의 Kbuild file이 있는 absolute path 지정
`MO=$BUILD_DIR`External module output을 별도 directory에 생성

`$KDIR`은 kernel source directory 또는 분리 build를 사용한 경우 kernel output directory입니다.

Module output을 별도 directory에 두려면 `make -C $KDIR M=$PWD MO=$BUILD_DIR`처럼 `MO=`를 선택적으로 전달합니다.

=========================
Building External Modules
=========================

This document describes how to build an out-of-tree kernel module.

Introduction
============

"kbuild" is the build system used by the Linux kernel. Modules must use
kbuild to stay compatible with changes in the build infrastructure and
to pick up the right flags to the compiler. Functionality for building modules
both in-tree and out-of-tree is provided. The method for building
either is similar, and all modules are initially developed and built
out-of-tree.

Covered in this document is information aimed at developers interested
in building out-of-tree (or "external") modules. The author of an
external module should supply a makefile that hides most of the
complexity, so one only has to type "make" to build the module. This is
easily accomplished, and a complete example will be presented in
section `Creating a Kbuild File for an External Module`_.


How to Build External Modules
=============================

To build external modules, you must have a prebuilt kernel available
that contains the configuration and header files used in the build.
Also, the kernel must have been built with modules enabled. If you are
using a distribution kernel, there will be a package for the kernel you
are running provided by your distribution.

An alternative is to use the "make" target "modules_prepare." This will
make sure the kernel contains the information required. The target
exists solely as a simple way to prepare a kernel source tree for
building external modules.

NOTE: "modules_prepare" will not build Module.symvers even if
CONFIG_MODVERSIONS is set; therefore, a full kernel build needs to be
executed to make module versioning work.

Command Syntax
--------------

        The command to build an external module is::

                $ make -C <path_to_kernel_dir> M=$PWD

        The kbuild system knows that an external module is being built
        due to the "M=<dir>" option given in the command.

        To build against the running kernel use::

                $ make -C /lib/modules/`uname -r`/build M=$PWD

        Then to install the module(s) just built, add the target
        "modules_install" to the command::

                $ make -C /lib/modules/`uname -r`/build M=$PWD modules_install

        Starting from Linux 6.13, you can use the -f option instead of -C. This
        will avoid unnecessary change of the working directory. The external
        module will be output to the directory where you invoke make.

                $ make -f /lib/modules/`uname -r`/build/Makefile M=$PWD

Options
-------

        ($KDIR refers to the path of the kernel source directory, or the path
        of the kernel output directory if the kernel was built in a separate
        build directory.)

        You can optionally pass MO= option if you want to build the modules in
        a separate directory.

Target과 개별 file 빌드

77-140

External module build에서는 kernel 전체 target 중 일부만 사용할 수 있습니다. 기본 command 형식은 `make -C $KDIR M=$PWD [target]`입니다. Target을 생략하면 현재 directory의 module을 build하고 모든 output도 그 directory에 만듭니다.

External module build는 kernel source를 갱신하지 않습니다. 대상 kernel에서 성공적인 `make`가 이미 수행되었다는 전제가 있습니다.

External module target
Target동작
`modules` 또는 target 생략현재 directory의 external module build
`modules_install`기본적으로 `/lib/modules/<kernel_release>/updates/`에 설치
`clean`Module directory에서 생성된 file만 제거
`help`사용할 수 있는 external module target 표시

External module에 공개되는 주요 make target입니다.

Module에 포함되는 file 하나만 선택해 build할 수도 있습니다. Kernel, in-tree module, external module 모두 같은 방식으로 동작합니다.

예를 들어 `foo.ko`가 `bar.o`와 `baz.o`로 구성되면 `bar.lst`, `baz.o`, `foo.ko`를 각각 target으로 지정할 수 있습니다. `./` target은 현재 external module directory를 build합니다. 정확한 command는 아래 원문 code block에 보존되어 있습니다.


        make -C $KDIR M=$PWD [MO=$BUILD_DIR]

        -C $KDIR
                The directory that contains the kernel and relevant build
                artifacts used for building an external module.
                "make" will actually change to the specified directory
                when executing and will change back when finished.

        M=$PWD
                Informs kbuild that an external module is being built.
                The value given to "M" is the absolute path of the
                directory where the external module (kbuild file) is
                located.

        MO=$BUILD_DIR
                Specifies a separate output directory for the external module.

Targets
-------

        When building an external module, only a subset of the "make"
        targets are available.

        make -C $KDIR M=$PWD [target]

        The default will build the module(s) located in the current
        directory, so a target does not need to be specified. All
        output files will also be generated in this directory. No
        attempts are made to update the kernel source, and it is a
        precondition that a successful "make" has been executed for the
        kernel.

        modules
                The default target for external modules. It has the
                same functionality as if no target was specified. See
                description above.

        modules_install
                Install the external module(s). The default location is
                /lib/modules/<kernel_release>/updates/, but a prefix may
                be added with INSTALL_MOD_PATH (discussed in section
                `Module Installation`_).

        clean
                Remove all generated files in the module directory only.

        help
                List the available targets for external modules.

Building Separate Files
-----------------------

        It is possible to build single files that are part of a module.
        This works equally well for the kernel, a module, and even for
        external modules.

        Example (The module foo.ko, consist of bar.o and baz.o)::

                make -C $KDIR M=$PWD bar.lst
                make -C $KDIR M=$PWD baz.o
                make -C $KDIR M=$PWD foo.ko
                make -C $KDIR M=$PWD ./

External module용 Kbuild file 작성

141-258

실제 module build에는 module 이름과 필요한 source file 목록을 담은 build file이 필요합니다. Source 하나로 구성된 module은 `obj-m := <module_name>.o` 한 줄이면 됩니다. Kbuild는 `<module_name>.c`에서 object를 build하고 link하여 `<module_name>.ko`를 만듭니다.

이 선언은 `Kbuild` 또는 `Makefile`에 둘 수 있습니다. Source가 여러 개라면 `<module_name>-y := <src1>.o <src2>.o ...`로 구성 object를 나열합니다. 자세한 kbuild syntax는 `Documentation/kbuild/makefiles.rst`를 참조합니다.

문서의 예제 module `8123.ko`는 `8123_if.c`, `8123_if.h`, `8123_pci.c`로 구성됩니다. Shared Makefile 방식은 kbuild 영역과 일반 make 영역을 한 file에 함께 둡니다. 사용자가 인자 없이 `make`를 실행할 수 있게 하는 wrapper target은 kbuild가 직접 사용하지 않는 편의 기능이며, test 같은 추가 target은 이름 충돌을 피하도록 kbuild에서 걸러야 합니다.

예제 1은 `ifneq ($(KERNELRELEASE),)`로 두 영역을 구분합니다. Command line에서 실행한 첫 번째 make는 wrapper 영역을 보고, default target의 `$(MAKE) -C $(KDIR) M=$$PWD`가 시작한 두 번째 kbuild pass는 `obj-m`과 `8123-y` 선언을 봅니다.

Shared Makefile의 두 번 실행
사용자가 external module directory에서 `make` 실행첫 pass는 `KERNELRELEASE`가 없어 일반 Makefile 영역 선택Default target이 kernel directory의 make를 재귀 호출둘째 pass에서 kbuild가 `KERNELRELEASE`를 설정Kbuild 영역의 `obj-m`·`8123-y`만 module goal로 처리

`KERNELRELEASE` 유무가 wrapper make와 kbuild 영역을 나눕니다.

Kbuild는 먼저 `Kbuild`라는 file을 찾고 없으면 `Makefile`을 찾습니다. 따라서 예제 2처럼 module 선언은 `Kbuild`에, 편의 target과 `KDIR` 설정은 `Makefile`에 분리할 수 있습니다. 작은 예제에서는 이득이 적지만 수백 줄짜리 external module Makefile에서는 관심사를 분리하는 효과가 큽니다.

Linux 6.13 이상에서는 sub-make를 호출하는 대신 external module Makefile에서 kernel Makefile을 직접 include할 수도 있습니다. `KBUILD_EXTMOD`를 현재 Makefile directory의 real path로 export한 다음 `include $(KDIR)/Makefile`을 사용합니다.

External module build file 구성
구성핵심적합한 경우
Shared `Makefile``KERNELRELEASE`로 두 영역 분기작고 단순한 module
`Kbuild` + `Makefile`Kbuild 선언과 일반 target 분리복잡한 build·test target
Kernel Makefile 직접 include`KBUILD_EXTMOD` export 후 includeLinux 6.13 이상

세 가지 wrapper 구성과 용도를 비교합니다.

한 build file에서 module 여러 개도 만들 수 있습니다. `obj-m := foo.o bar.o`로 module을 나열하고 `foo-y`, `bar-y`에 각각 source object를 지정하면 `foo.ko`와 `bar.ko`를 함께 build합니다.


Creating a Kbuild File for an External Module
=============================================

In the last section we saw the command to build a module for the
running kernel. The module is not actually built, however, because a
build file is required. Contained in this file will be the name of
the module(s) being built, along with the list of requisite source
files. The file may be as simple as a single line::

        obj-m := <module_name>.o

The kbuild system will build <module_name>.o from <module_name>.c,
and, after linking, will result in the kernel module <module_name>.ko.
The above line can be put in either a "Kbuild" file or a "Makefile."
When the module is built from multiple sources, an additional line is
needed listing the files::

        <module_name>-y := <src1>.o <src2>.o ...

NOTE: Further documentation describing the syntax used by kbuild is
located in Documentation/kbuild/makefiles.rst.

The examples below demonstrate how to create a build file for the
module 8123.ko, which is built from the following files::

        8123_if.c
        8123_if.h
        8123_pci.c

Shared Makefile
---------------

        An external module always includes a wrapper makefile that
        supports building the module using "make" with no arguments.
        This target is not used by kbuild; it is only for convenience.
        Additional functionality, such as test targets, can be included
        but should be filtered out from kbuild due to possible name
        clashes.

        Example 1::

                --> filename: Makefile
                ifneq ($(KERNELRELEASE),)
                # kbuild part of makefile
                obj-m  := 8123.o
                8123-y := 8123_if.o 8123_pci.o

                else
                # normal makefile
                KDIR ?= /lib/modules/`uname -r`/build

                default:
                        $(MAKE) -C $(KDIR) M=$$PWD

                endif

        The check for KERNELRELEASE is used to separate the two parts
        of the makefile. In the example, kbuild will only see the two
        assignments, whereas "make" will see everything except these
        two assignments. This is due to two passes made on the file:
        the first pass is by the "make" instance run on the command
        line; the second pass is by the kbuild system, which is
        initiated by the parameterized "make" in the default target.

Separate Kbuild File and Makefile
---------------------------------

        Kbuild will first look for a file named "Kbuild", and if it is not
        found, it will then look for "Makefile". Utilizing a "Kbuild" file
        allows us to split up the "Makefile" from example 1 into two files:

        Example 2::

                --> filename: Kbuild
                obj-m  := 8123.o
                8123-y := 8123_if.o 8123_pci.o

                --> filename: Makefile
                KDIR ?= /lib/modules/`uname -r`/build

                default:
                        $(MAKE) -C $(KDIR) M=$$PWD

        The split in example 2 is questionable due to the simplicity of
        each file; however, some external modules use makefiles
        consisting of several hundred lines, and here it really pays
        off to separate the kbuild part from the rest.

        Linux 6.13 and later support another way. The external module Makefile
        can include the kernel Makefile directly, rather than invoking sub Make.

        Example 3::

                --> filename: Kbuild
                obj-m  := 8123.o
                8123-y := 8123_if.o 8123_pci.o

                --> filename: Makefile
                KDIR ?= /lib/modules/$(shell uname -r)/build
                export KBUILD_EXTMOD := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
                include $(KDIR)/Makefile


Building Multiple Modules
-------------------------

        kbuild supports building multiple modules with a single build
        file. For example, if you wanted to build two modules, foo.ko
        and bar.ko, the kbuild lines would be::

                obj-m := foo.o bar.o
                foo-y := <foo_srcs>
                bar-y := <bar_srcs>

        It is that simple!

Header와 여러 subdirectory

259-346

Kernel 내부 header 배치는 interface 범위에 따릅니다. Module 내부에서만 쓰는 header는 source와 같은 directory에 두고, 다른 directory의 kernel 코드도 사용하는 interface header는 `include/linux/`에 둡니다.

큰 subsystem은 `include/scsi`처럼 `include/` 아래에 자체 directory를 둘 수 있고, architecture-specific header는 `arch/$(SRCARCH)/include/`에 둡니다.

`include/linux/` 아래 header는 `#include <linux/module.h>`처럼 include합니다. Kbuild가 compiler search path를 자동으로 추가합니다.

External module은 kernel의 일반 style과 달리 source 옆 `include/` directory에 header를 두는 경우가 많습니다. 이 path는 `ccflags-y` 또는 `CFLAGS_<filename>.o`로 kbuild에 알려야 합니다. `8123_if.h`를 `include/`로 옮겼다면 `ccflags-y := -I $(src)/include`를 사용합니다.

여러 directory에 source가 퍼진 module도 build할 수 있습니다. 예제의 `complex.ko`는 `src/complex_main.o`와 `src/hal/hardwareif.o`를 `complex-y`에 나열하고, 두 header directory를 `ccflags-y`의 `-I` option으로 추가합니다.

Header 검색 경로
위치용도지정 방식
Source와 같은 directoryModule 내부 interface상대 include
`include/linux/`Kernel 전역 interface`#include <linux/...>`
`arch/$(SRCARCH)/include/`Architecture-specific interfaceKbuild 기본 search path
External module의 `include/`Out-of-tree local header`ccflags-y := -I$(src)/include`

Header의 공개 범위와 Kbuild 설정을 연결합니다.

Object path는 Kbuild file 위치를 기준으로 상대 지정합니다. 다만 source를 여러 directory에 흩어 두는 방식은 권장되지 않습니다.

Kbuild 실행 시 current directory는 항상 `-C`로 전달한 kernel tree root입니다. 따라서 external header path에는 absolute path가 필요하고, `$(src)`가 현재 실행 중인 Kbuild file directory의 absolute path를 제공합니다.

Include Files
=============

Within the kernel, header files are kept in standard locations
according to the following rule:

        * If the header file only describes the internal interface of a
          module, then the file is placed in the same directory as the
          source files.
        * If the header file describes an interface used by other parts
          of the kernel that are located in different directories, then
          the file is placed in include/linux/.

          NOTE:
              There are two notable exceptions to this rule: larger
              subsystems have their own directory under include/, such as
              include/scsi; and architecture specific headers are located
              under arch/$(SRCARCH)/include/.

Kernel Includes
---------------

        To include a header file located under include/linux/, simply
        use::

                #include <linux/module.h>

        kbuild will add options to the compiler so the relevant directories
        are searched.

Single Subdirectory
-------------------

        External modules tend to place header files in a separate
        include/ directory where their source is located, although this
        is not the usual kernel style. To inform kbuild of the
        directory, use either ccflags-y or CFLAGS_<filename>.o.

        Using the example from section 3, if we moved 8123_if.h to a
        subdirectory named include, the resulting kbuild file would
        look like::

                --> filename: Kbuild
                obj-m := 8123.o

                ccflags-y := -I $(src)/include
                8123-y := 8123_if.o 8123_pci.o

Several Subdirectories
----------------------

        kbuild can handle files that are spread over several directories.
        Consider the following example::

                .
                |__ src
                |   |__ complex_main.c
                |   |__ hal
                |        |__ hardwareif.c
                |        |__ include
                |            |__ hardwareif.h
                |__ include
                        |__ complex.h

        To build the module complex.ko, we then need the following
        kbuild file::

                --> filename: Kbuild
                obj-m := complex.o
                complex-y := src/complex_main.o
                complex-y += src/hal/hardwareif.o

                ccflags-y := -I$(src)/include
                ccflags-y += -I$(src)/src/hal/include

        As you can see, kbuild knows how to handle object files located
        in other directories. The trick is to specify the directory
        relative to the kbuild file's location. That being said, this
        is NOT recommended practice.

        For the header files, kbuild must be explicitly told where to
        look. When kbuild executes, the current directory is always the
        root of the kernel tree (the argument to "-C") and therefore an
        absolute path is needed. $(src) provides the absolute path by
        pointing to the directory where the currently executing kbuild
        file is located.

Module 설치 위치

347-387

Kernel source에 포함된 module은 `/lib/modules/$(KERNELRELEASE)/kernel/`에 설치되고, external module은 기본적으로 `/lib/modules/$(KERNELRELEASE)/updates/`에 설치됩니다.

`INSTALL_MOD_PATH`는 전체 설치 path 앞에 prefix를 붙입니다. 예를 들어 `$ make INSTALL_MOD_PATH=/frodo modules_install`은 in-tree module을 `/frodo/lib/modules/$(KERNELRELEASE)/kernel/` 아래에 설치합니다. 이 값은 shell variable이나 make command line에서 설정할 수 있고 in-tree와 out-of-tree module 모두에 적용됩니다.

External module의 기본 subdirectory 이름 `updates`를 기능별 이름으로 바꾸려면 `INSTALL_MOD_DIR`을 사용합니다. `$ make INSTALL_MOD_DIR=gandalf -C $KDIR M=$PWD modules_install`은 `/lib/modules/$(KERNELRELEASE)/gandalf/`에 설치합니다.

Module 설치 변수
변수기본값 또는 효과
`INSTALL_MOD_PATH``/lib/modules/...` 앞에 staging prefix 추가
`INSTALL_MOD_DIR`External module의 `updates` directory 이름 대체
`KERNELRELEASE`설치할 kernel release directory 선택

설치 root와 external module subdirectory를 독립적으로 조정합니다.

Module Installation
===================

Modules which are included in the kernel are installed in the
directory:

        /lib/modules/$(KERNELRELEASE)/kernel/

And external modules are installed in:

        /lib/modules/$(KERNELRELEASE)/updates/

INSTALL_MOD_PATH
----------------

        Above are the default directories but as always some level of
        customization is possible. A prefix can be added to the
        installation path using the variable INSTALL_MOD_PATH::

                $ make INSTALL_MOD_PATH=/frodo modules_install
                => Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel/

        INSTALL_MOD_PATH may be set as an ordinary shell variable or,
        as shown above, can be specified on the command line when
        calling "make." This has effect when installing both in-tree
        and out-of-tree modules.

INSTALL_MOD_DIR
---------------

        External modules are by default installed to a directory under
        /lib/modules/$(KERNELRELEASE)/updates/, but you may wish to
        locate modules for a specific functionality in a separate
        directory. For this purpose, use INSTALL_MOD_DIR to specify an
        alternative name to "updates."::

                $ make INSTALL_MOD_DIR=gandalf -C $KDIR \
                       M=$PWD modules_install
                => Install dir: /lib/modules/$(KERNELRELEASE)/gandalf/

Module versioning과 형식

388-445

`CONFIG_MODVERSIONS`는 간단한 ABI 일관성 검사를 위한 module versioning을 활성화합니다. Exported symbol의 전체 prototype으로 CRC를 만들고, module load 시 kernel과 module의 CRC를 비교합니다. 값이 다르면 kernel은 module load를 거부합니다.

Kernel build가 생성하는 `Module.symvers`에는 vmlinux와 compile된 module의 모든 exported symbol과 해당 CRC가 기록됩니다. 한 행의 형식은 `<CRC> <Symbol> <Module> <Export Type> <Namespace>`이며 field는 tab으로 구분되고 namespace처럼 값이 비어 있을 수도 있습니다.

`CONFIG_MODVERSIONS`가 비활성화된 build에서는 CRC가 `0x00000000`입니다. `Module.symvers`는 exported symbol 전체 목록과 versioning이 활성화된 경우 각 CRC라는 두 정보를 제공합니다.

Module.symvers field
Field내용
`CRC`Symbol prototype에서 계산한 ABI checksum
`Symbol`Export된 symbol 이름
`Module`Symbol을 제공하는 vmlinux 또는 module
`Export Type``EXPORT_SYMBOL` 또는 `EXPORT_SYMBOL_GPL` 계열
`Namespace`선택적인 symbol namespace

Exported symbol 한 행에 기록되는 정보입니다.

Exported symbol 정보는 `__ksymtab` 또는 `__ksymtab_gpl` section에 저장되고, symbol 이름과 namespace는 ELF string table과 비슷한 `__ksymtab_strings` 형식에 저장됩니다. `CONFIG_MODVERSIONS`가 켜지면 CRC는 `__kcrctab` 또는 `__kcrctab_gpl`에 추가됩니다.

기본인 `CONFIG_BASIC_MODVERSIONS` 방식에서는 import symbol의 이름과 CRC를 importing module의 `__versions` section에 저장합니다. 이 방식은 최대 64-byte symbol만 지원합니다.

`CONFIG_MODVERSIONS`와 `CONFIG_RUST`를 동시에 활성화하려면 `CONFIG_EXTENDED_MODVERSIONS`가 필요합니다. 이 방식은 null-terminated symbol 이름들을 `__version_ext_names`에 이어 붙이고, 대응 CRC를 `__version_ext_crcs`에 기록합니다.

Module Versioning
=================

Module versioning is enabled by the CONFIG_MODVERSIONS tag, and is used
as a simple ABI consistency check. A CRC value of the full prototype
for an exported symbol is created. When a module is loaded/used, the
CRC values contained in the kernel are compared with similar values in
the module; if they are not equal, the kernel refuses to load the
module.

Module.symvers contains a list of all exported symbols from a kernel
build.

Symbols From the Kernel (vmlinux + modules)
-------------------------------------------

        During a kernel build, a file named Module.symvers will be
        generated. Module.symvers contains all exported symbols from
        the kernel and compiled modules. For each symbol, the
        corresponding CRC value is also stored.

        The syntax of the Module.symvers file is::

                <CRC>       <Symbol>         <Module>                         <Export Type>     <Namespace>

                0xe1cc2a05  usb_stor_suspend drivers/usb/storage/usb-storage  EXPORT_SYMBOL_GPL USB_STORAGE

        The fields are separated by tabs and values may be empty (e.g.
        if no namespace is defined for an exported symbol).

        For a kernel build without CONFIG_MODVERSIONS enabled, the CRC
        would read 0x00000000.

        Module.symvers serves two purposes:

        1) It lists all exported symbols from vmlinux and all modules.
        2) It lists the CRC if CONFIG_MODVERSIONS is enabled.

Version Information Formats
---------------------------

        Exported symbols have information stored in __ksymtab or __ksymtab_gpl
        sections. Symbol names and namespaces are stored in __ksymtab_strings,
        using a format similar to the string table used for ELF. If
        CONFIG_MODVERSIONS is enabled, the CRCs corresponding to exported
        symbols will be added to the __kcrctab or __kcrctab_gpl.

        If CONFIG_BASIC_MODVERSIONS is enabled (default with
        CONFIG_MODVERSIONS), imported symbols will have their symbol name and
        CRC stored in the __versions section of the importing module. This
        mode only supports symbols of length up to 64 bytes.

        If CONFIG_EXTENDED_MODVERSIONS is enabled (required to enable both
        CONFIG_MODVERSIONS and CONFIG_RUST at the same time), imported symbols
        will have their symbol name recorded in the __version_ext_names
        section as a series of concatenated, null-terminated strings. CRCs for
        these symbols will be recorded in the __version_ext_crcs section.

External module 사이의 symbol

446-495

External module build의 MODPOST 단계는 모든 외부 symbol이 정의되었는지 검사해야 하므로 kernel source tree의 `Module.symvers`를 읽습니다. MODPOST가 끝나면 해당 external module이 export하는 symbol을 담은 새 `Module.symvers`를 작성합니다.

MODPOST symbol 검증
Kernel build가 vmlinux·in-tree module의 `Module.symvers` 생성External module compile 후 MODPOST 시작MODPOST가 kernel `Module.symvers`를 symbol table에 적재External reference의 정의와 version CRC 검사External module이 export한 symbol로 새 `Module.symvers` 작성

Kernel과 external module의 symbol 정보를 합쳐 undefined symbol과 CRC를 확인합니다.

External module 하나가 다른 external module의 exported symbol을 사용할 때는 kbuild가 두 module의 symbol을 모두 알아야 undefined symbol warning을 피할 수 있습니다. 권장 방식은 공통 top-level Kbuild file을 사용하는 것입니다.

예를 들어 `foo.ko`가 `bar.ko`의 symbol을 사용하고 두 module이 `./foo/`, `./bar/`에 있다면 top-level file에 `obj-m := foo/ bar/`를 선언합니다. Top-level에서 `$ make -C $KDIR M=$PWD`를 실행하면 두 module을 한 build에서 처리하므로 서로의 symbol을 완전히 알 수 있습니다.

공통 top-level Kbuild를 만들기 어렵다면 build file의 `KBUILD_EXTRA_SYMBOLS`에 공백으로 구분한 추가 `Module.symvers` file 목록을 지정합니다. MODPOST가 초기 symbol table을 만들 때 이 file들을 읽습니다.

다른 external module의 symbol 사용
방법동작평가
Top-level `obj-m := foo/ bar/`두 module을 같은 MODPOST context에서 build권장
`KBUILD_EXTRA_SYMBOLS`다른 build의 symbol file을 MODPOST에 추가분리 build가 불가피할 때

두 해결책 중 공통 top-level build가 권장됩니다.

Symbols and External Modules
----------------------------

        When building an external module, the build system needs access
        to the symbols from the kernel to check if all external symbols
        are defined. This is done in the MODPOST step. modpost obtains
        the symbols by reading Module.symvers from the kernel source
        tree. During the MODPOST step, a new Module.symvers file will be
        written containing all exported symbols from that external module.

Symbols From Another External Module
------------------------------------

        Sometimes, an external module uses exported symbols from
        another external module. Kbuild needs to have full knowledge of
        all symbols to avoid spitting out warnings about undefined
        symbols. Two solutions exist for this situation.

        NOTE: The method with a top-level kbuild file is recommended
        but may be impractical in certain situations.

        Use a top-level kbuild file
                If you have two modules, foo.ko and bar.ko, where
                foo.ko needs symbols from bar.ko, you can use a
                common top-level kbuild file so both modules are
                compiled in the same build. Consider the following
                directory layout::

                        ./foo/ <= contains foo.ko
                        ./bar/ <= contains bar.ko

                The top-level kbuild file would then look like::

                        #./Kbuild (or ./Makefile):
                                obj-m := foo/ bar/

                And executing::

                        $ make -C $KDIR M=$PWD

                will then do the expected and compile both modules with
                full knowledge of symbols from either module.

        Use "make" variable KBUILD_EXTRA_SYMBOLS
                If it is impractical to add a top-level kbuild file,
                you can assign a space separated list
                of files to KBUILD_EXTRA_SYMBOLS in your build file.
                These files will be loaded by modpost during the
                initialization of its symbol tables.

CONFIG option 활용

496-512

Module은 특정 기능을 포함할지 결정하려고 `CONFIG_` option을 확인하는 경우가 많습니다. Kbuild에서는 `CONFIG_` variable을 직접 참조합니다.

Ext2 예제는 `obj-$(CONFIG_EXT2_FS) += ext2.o`로 filesystem module 또는 built-in object를 선택하고, 기본 object를 `ext2-y`에 나열합니다.

`ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o`는 XATTR option이 활성화된 경우에만 `xattr.o`를 composite `ext2.o`에 추가합니다. 이 패턴은 configuration 결과 `y`, `m`, 빈 값이 Kbuild goal에 직접 반영되는 전형적인 조건부 구성입니다.

CONFIG 기반 object 선택
`CONFIG_EXT2_FS` 값 평가`y`이면 built-in, `m`이면 module, 빈 값이면 제외`ext2-y`의 기본 object를 composite object에 결합`CONFIG_EXT2_FS_XATTR=y`이면 `xattr.o` 추가

Configuration 값이 module과 구성 object의 포함 여부를 결정합니다.


Tips & Tricks
=============

Testing for CONFIG_FOO_BAR
--------------------------

        Modules often need to check for certain `CONFIG_` options to
        decide if a specific feature is included in the module. In
        kbuild this is done by referencing the `CONFIG_` variable
        directly::

                #fs/ext2/Makefile
                obj-$(CONFIG_EXT2_FS) += ext2.o

                ext2-y := balloc.o bitmap.o dir.o
                ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o