← Documents Documentation/core-api/printk-formats.rst GitHub 원문 ↗

Linux 6.18.37 · Core API

printk 형식 지정자

커널 printk의 정수와 포인터 형식, 주소·심볼·네트워크·device tree·시간·bitmap·flags·FourCC 및 Rust 전용 확장 지정자를 정리합니다.

Source pathDocumentation/core-api/printk-formats.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

요약과 해설

printk-formats.rst:1-698

커널의 `printk()` 형식은 C printf와 비슷하지만 `%n`과 부동소수점 변환을 지원하지 않으며, 커널 객체를 안전하고 의미 있게 출력하기 위한 다양한 `%p` 확장을 제공합니다.

일반 `%p`는 메모리 배치 노출을 막기 위해 주소를 hash합니다. 원시 주소가 꼭 필요할 때만 `%px`, 사용자 공간이 읽는 가상 파일에는 `%pK`, symbol에는 `%pS`·`%ps`·`%pB`처럼 목적에 맞는 전용 modifier를 사용해야 합니다.

문서는 resource, 물리·DMA 주소, escaped/hex buffer, MAC·IP·UUID, dentry, device tree, fwnode, 날짜와 시간, bitmap과 flags, FourCC 및 Rust 인자를 위한 형식을 예제와 함께 설명합니다. 참조 전달 여부와 endianness 규칙을 각 항목에서 확인해야 합니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 =========================================
2 How to get printk format specifiers right
3 =========================================
4
5 .. _printk-specifiers:
6
7 :Author: Randy Dunlap <[email protected]>
8 :Author: Andrew Murray <[email protected]>
9
10
11 Integer types
12 =============
13
14 ::
15
16 If variable is of Type, use printk format specifier:
17 ------------------------------------------------------------
18 signed char %d or %hhx
19 unsigned char %u or %x
20 char %u or %x
21 short int %d or %hx
22 unsigned short int %u or %x
23 int %d or %x
24 unsigned int %u or %x
25 long %ld or %lx
26 unsigned long %lu or %lx
27 long long %lld or %llx
28 unsigned long long %llu or %llx
29 size_t %zu or %zx
30 ssize_t %zd or %zx
31 s8 %d or %hhx
32 u8 %u or %x
33 s16 %d or %hx
34 u16 %u or %x
35 s32 %d or %x
36 u32 %u or %x
37 s64 %lld or %llx
38 u64 %llu or %llx
39
40
41 If <type> is architecture-dependent for its size (e.g., cycles_t, tcflag_t) or
42 is dependent on a config option for its size (e.g., blk_status_t), use a format
43 specifier of its largest possible type and explicitly cast to it.
44
45 Example::
46
47 printk("test: latency: %llu cycles\n", (unsigned long long)time);
48
49 Reminder: sizeof() returns type size_t.
50
51 The kernel's printf does not support %n. Floating point formats (%e, %f,
52 %g, %a) are also not recognized, for obvious reasons. Use of any
53 unsupported specifier or length qualifier results in a WARN and early
54 return from vsnprintf().
55
56 Pointer types
57 =============
58
59 A raw pointer value may be printed with %p which will hash the address
60 before printing. The kernel also supports extended specifiers for printing
61 pointers of different types.
62
63 Some of the extended specifiers print the data on the given address instead
64 of printing the address itself. In this case, the following error messages
65 might be printed instead of the unreachable information::
66
67 (null) data on plain NULL address
68 (efault) data on invalid address
69 (einval) invalid data on a valid address
70
71 Plain Pointers
72 --------------
73
74 ::
75
76 %p abcdef12 or 00000000abcdef12
77
78 Pointers printed without a specifier extension (i.e unadorned %p) are
79 hashed to prevent leaking information about the kernel memory layout. This
80 has the added benefit of providing a unique identifier. On 64-bit machines
81 the first 32 bits are zeroed. The kernel will print ``(ptrval)`` until it
82 gathers enough entropy.
83
84 When possible, use specialised modifiers such as %pS or %pB (described below)
85 to avoid the need of providing an unhashed address that has to be interpreted
86 post-hoc. If not possible, and the aim of printing the address is to provide
87 more information for debugging, use %p and boot the kernel with the
88 ``no_hash_pointers`` parameter during debugging, which will print all %p
89 addresses unmodified. If you *really* always want the unmodified address, see
90 %px below.
91
92 If (and only if) you are printing addresses as a content of a virtual file in
93 e.g. procfs or sysfs (using e.g. seq_printf(), not printk()) read by a
94 userspace process, use the %pK modifier described below instead of %p or %px.
95
96 Error Pointers
97 --------------
98
99 ::
100
101 %pe -ENOSPC
102
103 For printing error pointers (i.e. a pointer for which IS_ERR() is true)
104 as a symbolic error name. Error values for which no symbolic name is
105 known are printed in decimal, while a non-ERR_PTR passed as the
106 argument to %pe gets treated as ordinary %p.
107
108 Symbols/Function Pointers
109 -------------------------
110
111 ::
112
113 %pS versatile_init+0x0/0x110
114 %ps versatile_init
115 %pSR versatile_init+0x9/0x110
116 (with __builtin_extract_return_addr() translation)
117 %pB prev_fn_of_versatile_init+0x88/0x88
118
119
120 The ``S`` and ``s`` specifiers are used for printing a pointer in symbolic
121 format. They result in the symbol name with (S) or without (s)
122 offsets. If KALLSYMS are disabled then the symbol address is printed instead.
123
124 The ``B`` specifier results in the symbol name with offsets and should be
125 used when printing stack backtraces. The specifier takes into
126 consideration the effect of compiler optimisations which may occur
127 when tail-calls are used and marked with the noreturn GCC attribute.
128
129 If the pointer is within a module, the module name and optionally build ID is
130 printed after the symbol name with an extra ``b`` appended to the end of the
131 specifier.
132
133 ::
134
135 %pS versatile_init+0x0/0x110 [module_name]
136 %pSb versatile_init+0x0/0x110 [module_name ed5019fdf5e53be37cb1ba7899292d7e143b259e]
137 %pSRb versatile_init+0x9/0x110 [module_name ed5019fdf5e53be37cb1ba7899292d7e143b259e]
138 (with __builtin_extract_return_addr() translation)
139 %pBb prev_fn_of_versatile_init+0x88/0x88 [module_name ed5019fdf5e53be37cb1ba7899292d7e143b259e]
140
141 Probed Pointers from BPF / tracing
142 ----------------------------------
143
144 ::
145
146 %pks kernel string
147 %pus user string
148
149 The ``k`` and ``u`` specifiers are used for printing prior probed memory from
150 either kernel memory (k) or user memory (u). The subsequent ``s`` specifier
151 results in printing a string. For direct use in regular vsnprintf() the (k)
152 and (u) annotation is ignored, however, when used out of BPF's bpf_trace_printk(),
153 for example, it reads the memory it is pointing to without faulting.
154
155 Kernel Pointers
156 ---------------
157
158 ::
159
160 %pK 01234567 or 0123456789abcdef
161
162 For printing kernel pointers which should be hidden from unprivileged
163 users. The behaviour of %pK depends on the kptr_restrict sysctl - see
164 Documentation/admin-guide/sysctl/kernel.rst for more details.
165
166 This modifier is *only* intended when producing content of a file read by
167 userspace from e.g. procfs or sysfs, not for dmesg. Please refer to the
168 section about %p above for discussion about how to manage hashing pointers
169 in printk().
170
171 Unmodified Addresses
172 --------------------
173
174 ::
175
176 %px 01234567 or 0123456789abcdef
177
178 For printing pointers when you *really* want to print the address. Please
179 consider whether or not you are leaking sensitive information about the
180 kernel memory layout before printing pointers with %px. %px is functionally
181 equivalent to %lx (or %lu). %px is preferred because it is more uniquely
182 grep'able. If in the future we need to modify the way the kernel handles
183 printing pointers we will be better equipped to find the call sites.
184
185 Before using %px, consider if using %p is sufficient together with enabling the
186 ``no_hash_pointers`` kernel parameter during debugging sessions (see the %p
187 description above). One valid scenario for %px might be printing information
188 immediately before a panic, which prevents any sensitive information to be
189 exploited anyway, and with %px there would be no need to reproduce the panic
190 with no_hash_pointers.
191
192 Pointer Differences
193 -------------------
194
195 ::
196
197 %td 2560
198 %tx a00
199
200 For printing the pointer differences, use the %t modifier for ptrdiff_t.
201
202 Example::
203
204 printk("test: difference between pointers: %td\n", ptr2 - ptr1);
205
206 Struct Resources
207 ----------------
208
209 ::
210
211 %pr [mem 0x60000000-0x6fffffff flags 0x2200] or
212 [mem 0x60000000 flags 0x2200] or
213 [mem 0x0000000060000000-0x000000006fffffff flags 0x2200]
214 [mem 0x0000000060000000 flags 0x2200]
215 %pR [mem 0x60000000-0x6fffffff pref] or
216 [mem 0x60000000 pref] or
217 [mem 0x0000000060000000-0x000000006fffffff pref]
218 [mem 0x0000000060000000 pref]
219
220 For printing struct resources. The ``R`` and ``r`` specifiers result in a
221 printed resource with (R) or without (r) a decoded flags member. If start is
222 equal to end only print the start value.
223
224 Passed by reference.
225
226 Physical address types phys_addr_t
227 ----------------------------------
228
229 ::
230
231 %pa[p] 0x01234567 or 0x0123456789abcdef
232
233 For printing a phys_addr_t type (and its derivatives, such as
234 resource_size_t) which can vary based on build options, regardless of the
235 width of the CPU data path.
236
237 Passed by reference.
238
239 Struct Range
240 ------------
241
242 ::
243
244 %pra [range 0x0000000060000000-0x000000006fffffff] or
245 [range 0x0000000060000000]
246
247 For printing struct range. struct range holds an arbitrary range of u64
248 values. If start is equal to end only print the start value.
249
250 Passed by reference.
251
252 DMA address types dma_addr_t
253 ----------------------------
254
255 ::
256
257 %pad 0x01234567 or 0x0123456789abcdef
258
259 For printing a dma_addr_t type which can vary based on build options,
260 regardless of the width of the CPU data path.
261
262 Passed by reference.
263
264 Raw buffer as an escaped string
265 -------------------------------
266
267 ::
268
269 %*pE[achnops]
270
271 For printing raw buffer as an escaped string. For the following buffer::
272
273 1b 62 20 5c 43 07 22 90 0d 5d
274
275 A few examples show how the conversion would be done (excluding surrounding
276 quotes)::
277
278 %*pE "\eb \C\a"\220\r]"
279 %*pEhp "\x1bb \C\x07"\x90\x0d]"
280 %*pEa "\e\142\040\\\103\a\042\220\r\135"
281
282 The conversion rules are applied according to an optional combination
283 of flags (see :c:func:`string_escape_mem` kernel documentation for the
284 details):
285
286 - a - ESCAPE_ANY
287 - c - ESCAPE_SPECIAL
288 - h - ESCAPE_HEX
289 - n - ESCAPE_NULL
290 - o - ESCAPE_OCTAL
291 - p - ESCAPE_NP
292 - s - ESCAPE_SPACE
293
294 By default ESCAPE_ANY_NP is used.
295
296 ESCAPE_ANY_NP is the sane choice for many cases, in particularly for
297 printing SSIDs.
298
299 If field width is omitted then 1 byte only will be escaped.
300
301 Raw buffer as a hex string
302 --------------------------
303
304 ::
305
306 %*ph 00 01 02 ... 3f
307 %*phC 00:01:02: ... :3f
308 %*phD 00-01-02- ... -3f
309 %*phN 000102 ... 3f
310
311 For printing small buffers (up to 64 bytes long) as a hex string with a
312 certain separator. For larger buffers consider using
313 :c:func:`print_hex_dump`.
314
315 MAC/FDDI addresses
316 ------------------
317
318 ::
319
320 %pM 00:01:02:03:04:05
321 %pMR 05:04:03:02:01:00
322 %pMF 00-01-02-03-04-05
323 %pm 000102030405
324 %pmR 050403020100
325
326 For printing 6-byte MAC/FDDI addresses in hex notation. The ``M`` and ``m``
327 specifiers result in a printed address with (M) or without (m) byte
328 separators. The default byte separator is the colon (:).
329
330 Where FDDI addresses are concerned the ``F`` specifier can be used after
331 the ``M`` specifier to use dash (-) separators instead of the default
332 separator.
333
334 For Bluetooth addresses the ``R`` specifier shall be used after the ``M``
335 specifier to use reversed byte order suitable for visual interpretation
336 of Bluetooth addresses which are in the little endian order.
337
338 Passed by reference.
339
340 IPv4 addresses
341 --------------
342
343 ::
344
345 %pI4 1.2.3.4
346 %pi4 001.002.003.004
347 %p[Ii]4[hnbl]
348
349 For printing IPv4 dot-separated decimal addresses. The ``I4`` and ``i4``
350 specifiers result in a printed address with (i4) or without (I4) leading
351 zeros.
352
353 The additional ``h``, ``n``, ``b``, and ``l`` specifiers are used to specify
354 host, network, big or little endian order addresses respectively. Where
355 no specifier is provided the default network/big endian order is used.
356
357 Passed by reference.
358
359 IPv6 addresses
360 --------------
361
362 ::
363
364 %pI6 0001:0002:0003:0004:0005:0006:0007:0008
365 %pi6 00010002000300040005000600070008
366 %pI6c 1:2:3:4:5:6:7:8
367
368 For printing IPv6 network-order 16-bit hex addresses. The ``I6`` and ``i6``
369 specifiers result in a printed address with (I6) or without (i6)
370 colon-separators. Leading zeros are always used.
371
372 The additional ``c`` specifier can be used with the ``I`` specifier to
373 print a compressed IPv6 address as described by
374 https://tools.ietf.org/html/rfc5952
375
376 Passed by reference.
377
378 IPv4/IPv6 addresses (generic, with port, flowinfo, scope)
379 ---------------------------------------------------------
380
381 ::
382
383 %pIS 1.2.3.4 or 0001:0002:0003:0004:0005:0006:0007:0008
384 %piS 001.002.003.004 or 00010002000300040005000600070008
385 %pISc 1.2.3.4 or 1:2:3:4:5:6:7:8
386 %pISpc 1.2.3.4:12345 or [1:2:3:4:5:6:7:8]:12345
387 %p[Ii]S[pfschnbl]
388
389 For printing an IP address without the need to distinguish whether it's of
390 type AF_INET or AF_INET6. A pointer to a valid struct sockaddr,
391 specified through ``IS`` or ``iS``, can be passed to this format specifier.
392
393 The additional ``p``, ``f``, and ``s`` specifiers are used to specify port
394 (IPv4, IPv6), flowinfo (IPv6) and scope (IPv6). Ports have a ``:`` prefix,
395 flowinfo a ``/`` and scope a ``%``, each followed by the actual value.
396
397 In case of an IPv6 address the compressed IPv6 address as described by
398 https://tools.ietf.org/html/rfc5952 is being used if the additional
399 specifier ``c`` is given. The IPv6 address is surrounded by ``[``, ``]`` in
400 case of additional specifiers ``p``, ``f`` or ``s`` as suggested by
401 https://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-07
402
403 In case of IPv4 addresses, the additional ``h``, ``n``, ``b``, and ``l``
404 specifiers can be used as well and are ignored in case of an IPv6
405 address.
406
407 Passed by reference.
408
409 Further examples::
410
411 %pISfc 1.2.3.4 or [1:2:3:4:5:6:7:8]/123456789
412 %pISsc 1.2.3.4 or [1:2:3:4:5:6:7:8]%1234567890
413 %pISpfc 1.2.3.4:12345 or [1:2:3:4:5:6:7:8]:12345/123456789
414
415 UUID/GUID addresses
416 -------------------
417
418 ::
419
420 %pUb 00010203-0405-0607-0809-0a0b0c0d0e0f
421 %pUB 00010203-0405-0607-0809-0A0B0C0D0E0F
422 %pUl 03020100-0504-0706-0809-0a0b0c0e0e0f
423 %pUL 03020100-0504-0706-0809-0A0B0C0E0E0F
424
425 For printing 16-byte UUID/GUIDs addresses. The additional ``l``, ``L``,
426 ``b`` and ``B`` specifiers are used to specify a little endian order in
427 lower (l) or upper case (L) hex notation - and big endian order in lower (b)
428 or upper case (B) hex notation.
429
430 Where no additional specifiers are used the default big endian
431 order with lower case hex notation will be printed.
432
433 Passed by reference.
434
435 dentry names
436 ------------
437
438 ::
439
440 %pd{,2,3,4}
441 %pD{,2,3,4}
442
443 For printing dentry name; if we race with :c:func:`d_move`, the name might
444 be a mix of old and new ones, but it won't oops. %pd dentry is a safer
445 equivalent of %s dentry->d_name.name we used to use, %pd<n> prints ``n``
446 last components. %pD does the same thing for struct file.
447
448 Passed by reference.
449
450 block_device names
451 ------------------
452
453 ::
454
455 %pg sda, sda1 or loop0p1
456
457 For printing name of block_device pointers.
458
459 struct va_format
460 ----------------
461
462 ::
463
464 %pV
465
466 For printing struct va_format structures. These contain a format string
467 and va_list as follows::
468
469 struct va_format {
470 const char *fmt;
471 va_list *va;
472 };
473
474 Implements a "recursive vsnprintf".
475
476 Do not use this feature without some mechanism to verify the
477 correctness of the format string and va_list arguments.
478
479 Passed by reference.
480
481 Device tree nodes
482 -----------------
483
484 ::
485
486 %pOF[fnpPcCF]
487
488
489 For printing device tree node structures. Default behaviour is
490 equivalent to %pOFf.
491
492 - f - device node full_name
493 - n - device node name
494 - p - device node phandle
495 - P - device node path spec (name + @unit)
496 - F - device node flags
497 - c - major compatible string
498 - C - full compatible string
499
500 The separator when using multiple arguments is ':'
501
502 Examples::
503
504 %pOF /foo/bar@0 - Node full name
505 %pOFf /foo/bar@0 - Same as above
506 %pOFfp /foo/bar@0:10 - Node full name + phandle
507 %pOFfcF /foo/bar@0:foo,device:--P- - Node full name +
508 major compatible string +
509 node flags
510 D - dynamic
511 d - detached
512 P - Populated
513 B - Populated bus
514
515 Passed by reference.
516
517 Fwnode handles
518 --------------
519
520 ::
521
522 %pfw[fP]
523
524 For printing information on an fwnode_handle. The default is to print the full
525 node name, including the path. The modifiers are functionally equivalent to
526 %pOF above.
527
528 - f - full name of the node, including the path
529 - P - the name of the node including an address (if there is one)
530
531 Examples (ACPI)::
532
533 %pfwf \[email protected]@0 - Full node name
534 %pfwP endpoint@0 - Node name
535
536 Examples (OF)::
537
538 %pfwf /ocp@68000000/i2c@48072000/camera@10/port/endpoint - Full name
539 %pfwP endpoint - Node name
540
541 Time and date
542 -------------
543
544 ::
545
546 %pt[RT] YYYY-mm-ddTHH:MM:SS
547 %pt[RT]s YYYY-mm-dd HH:MM:SS
548 %pt[RT]d YYYY-mm-dd
549 %pt[RT]t HH:MM:SS
550 %pt[RT][dt][r][s]
551
552 For printing date and time as represented by::
553
554 R struct rtc_time structure
555 T time64_t type
556
557 in human readable format.
558
559 By default year will be incremented by 1900 and month by 1.
560 Use %pt[RT]r (raw) to suppress this behaviour.
561
562 The %pt[RT]s (space) will override ISO 8601 separator by using ' ' (space)
563 instead of 'T' (Capital T) between date and time. It won't have any effect
564 when date or time is omitted.
565
566 Passed by reference.
567
568 struct clk
569 ----------
570
571 ::
572
573 %pC pll1
574
575 For printing struct clk structures. %pC prints the name of the clock
576 (Common Clock Framework) or a unique 32-bit ID (legacy clock framework).
577
578 Passed by reference.
579
580 bitmap and its derivatives such as cpumask and nodemask
581 -------------------------------------------------------
582
583 ::
584
585 %*pb 0779
586 %*pbl 0,3-6,8-10
587
588 For printing bitmap and its derivatives such as cpumask and nodemask,
589 %*pb outputs the bitmap with field width as the number of bits and %*pbl
590 output the bitmap as range list with field width as the number of bits.
591
592 The field width is passed by value, the bitmap is passed by reference.
593 Helper macros cpumask_pr_args() and nodemask_pr_args() are available to ease
594 printing cpumask and nodemask.
595
596 Flags bitfields such as page flags and gfp_flags
597 --------------------------------------------------------
598
599 ::
600
601 %pGp 0x17ffffc0002036(referenced|uptodate|lru|active|private|node=0|zone=2|lastcpupid=0x1fffff)
602 %pGg GFP_USER|GFP_DMA32|GFP_NOWARN
603 %pGv read|exec|mayread|maywrite|mayexec|denywrite
604
605 For printing flags bitfields as a collection of symbolic constants that
606 would construct the value. The type of flags is given by the third
607 character. Currently supported are:
608
609 - p - [p]age flags, expects value of type (``unsigned long *``)
610 - v - [v]ma_flags, expects value of type (``unsigned long *``)
611 - g - [g]fp_flags, expects value of type (``gfp_t *``)
612
613 The flag names and print order depends on the particular type.
614
615 Note that this format should not be used directly in the
616 :c:func:`TP_printk()` part of a tracepoint. Instead, use the show_*_flags()
617 functions from <trace/events/mmflags.h>.
618
619 Passed by reference.
620
621 Network device features
622 -----------------------
623
624 ::
625
626 %pNF 0x000000000000c000
627
628 For printing netdev_features_t.
629
630 Passed by reference.
631
632 V4L2 and DRM FourCC code (pixel format)
633 ---------------------------------------
634
635 ::
636
637 %p4cc
638
639 Print a FourCC code used by V4L2 or DRM, including format endianness and
640 its numerical value as hexadecimal.
641
642 Passed by reference.
643
644 Examples::
645
646 %p4cc BG12 little-endian (0x32314742)
647 %p4cc Y10 little-endian (0x20303159)
648 %p4cc NV12 big-endian (0xb231564e)
649
650 Generic FourCC code
651 -------------------
652
653 ::
654 %p4c[h[R]lb] gP00 (0x67503030)
655
656 Print a generic FourCC code, as both ASCII characters and its numerical
657 value as hexadecimal.
658
659 The generic FourCC code is always printed in the big-endian format,
660 the most significant byte first. This is the opposite of V4L/DRM FourCCs.
661
662 The additional ``h``, ``hR``, ``l``, and ``b`` specifiers define what
663 endianness is used to load the stored bytes. The data might be interpreted
664 using the host, reversed host byte order, little-endian, or big-endian.
665
666 Passed by reference.
667
668 Examples for a little-endian machine, given &(u32)0x67503030::
669
670 %p4ch gP00 (0x67503030)
671 %p4chR 00Pg (0x30305067)
672 %p4cl gP00 (0x67503030)
673 %p4cb 00Pg (0x30305067)
674
675 Examples for a big-endian machine, given &(u32)0x67503030::
676
677 %p4ch gP00 (0x67503030)
678 %p4chR 00Pg (0x30305067)
679 %p4cl 00Pg (0x30305067)
680 %p4cb gP00 (0x67503030)
681
682 Rust
683 ----
684
685 ::
686
687 %pA
688
689 Only intended to be used from Rust code to format ``core::fmt::Arguments``.
690 Do *not* use it from C.
691
692 Thanks
693 ======
694
695 If you add other %p extensions, please extend <lib/tests/printf_kunit.c>
696 with one or more test cases, if at all feasible.
697
698 Thank you for your cooperation and attention.
699

3. 한국어 전문 번역

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

printk 형식 지정자를 올바르게 사용하는 방법

1-10

printk 형식 지정자를 올바르게 사용하는 방법

문서 내부 참조 이름은 `printk-specifiers`입니다.

저자: Randy Dunlap <[email protected]>

저자: Andrew Murray <[email protected]>

정수 형식

11-55

정수 형식 (Integer types)

변수 형식printk 형식 지정자
signed char%d 또는 %hhx
unsigned char%u 또는 %x
char%u 또는 %x
short int%d 또는 %hx
unsigned short int%u 또는 %x
int%d 또는 %x
unsigned int%u 또는 %x
long%ld 또는 %lx
unsigned long%lu 또는 %lx
long long%lld 또는 %llx
unsigned long long%llu 또는 %llx
size_t%zu 또는 %zx
ssize_t%zd 또는 %zx
s8%d 또는 %hhx
u8%u 또는 %x
s16%d 또는 %hx
u16%u 또는 %x
s32%d 또는 %x
u32%u 또는 %x
s64%lld 또는 %llx
u64%llu 또는 %llx

크기가 아키텍처에 의존하는 형식, 예를 들어 `cycles_t`와 `tcflag_t`, 또는 `blk_status_t`처럼 구성 옵션에 따라 크기가 달라지는 형식은 가능한 가장 큰 형식의 지정자를 사용하고 그 형식으로 명시적으로 cast해야 합니다.

예:

printk("test: latency: %llu cycles\n", (unsigned long long)time);

`sizeof()`는 `size_t` 형식을 반환한다는 점을 기억하십시오.

커널의 printf는 `%n`을 지원하지 않습니다. 명백한 이유로 부동소수점 형식 `%e`, `%f`, `%g`, `%a`도 인식하지 않습니다. 지원하지 않는 지정자나 길이 한정자를 사용하면 WARN이 발생하고 `vsnprintf()`가 일찍 반환합니다.

포인터 형식과 접근 오류

56-70

포인터 형식 (Pointer types)

원시 포인터 값은 `%p`로 출력할 수 있으며, 주소는 출력 전에 hash됩니다. 커널은 서로 다른 포인터 형식을 출력하기 위한 확장 지정자도 지원합니다.

일부 확장 지정자는 주소 자체가 아니라 해당 주소의 데이터를 출력합니다. 이때 정보에 접근할 수 없으면 다음 오류 메시지가 대신 출력될 수 있습니다.

(null)         data on plain NULL address
(efault) data on invalid address
(einval) invalid data on a valid address

일반 포인터

71-95

일반 포인터 (Plain Pointers)

%p        abcdef12 or 00000000abcdef12

확장 없는 `%p`로 출력하는 포인터는 커널 메모리 배치 정보가 노출되지 않도록 hash됩니다. 동시에 고유 식별자로 쓸 수 있다는 장점도 있습니다. 64비트 시스템에서는 첫 32비트를 0으로 만듭니다. 커널은 충분한 entropy를 모을 때까지 `(ptrval)`을 출력합니다.

가능하면 나중에 해석해야 하는 원시 주소를 노출하지 않도록 아래에 설명한 `%pS` 또는 `%pB` 같은 전용 modifier를 사용하십시오. 불가능하고 디버깅 정보를 늘리는 것이 목적이라면 `%p`를 사용하고 디버깅 중 `no_hash_pointers` 커널 매개변수로 부팅하여 모든 `%p` 주소를 수정 없이 출력할 수 있습니다. 언제나 수정되지 않은 주소가 정말 필요하다면 아래의 `%px`를 참고하십시오.

주소를 procfs 또는 sysfs 같은 가상 파일의 내용으로 출력하여 사용자 공간 프로세스가 읽게 하는 경우에만, 예를 들어 `printk()`가 아니라 `seq_printf()`를 사용할 때는 `%p`나 `%px` 대신 아래의 `%pK` modifier를 사용하십시오.

오류 포인터

96-107

오류 포인터 (Error Pointers)

%pe        -ENOSPC

`IS_ERR()`가 참인 오류 포인터를 기호 오류 이름으로 출력할 때 `%pe`를 사용합니다. 알려진 기호 이름이 없는 오류 값은 10진수로 출력하며, `ERR_PTR`이 아닌 값을 `%pe` 인자로 전달하면 일반 `%p`처럼 처리합니다.

심볼과 함수 포인터

108-140

심볼/함수 포인터 (Symbols/Function Pointers)

%pS        versatile_init+0x0/0x110
%ps        versatile_init
%pSR        versatile_init+0x9/0x110
        (with __builtin_extract_return_addr() translation)
%pB        prev_fn_of_versatile_init+0x88/0x88

`S`와 `s` 지정자는 포인터를 기호 형식으로 출력합니다. `S`는 offset을 포함한 symbol 이름을, `s`는 offset 없는 이름을 출력합니다. `KALLSYMS`가 비활성화되어 있으면 symbol 주소를 대신 출력합니다.

`B` 지정자는 offset을 포함한 symbol 이름을 출력하며 stack backtrace에 사용해야 합니다. Tail call을 사용하고 `noreturn` GCC attribute로 표시했을 때 생길 수 있는 compiler optimization 효과도 고려합니다.

포인터가 모듈 안에 있으면 지정자 끝에 `b`를 추가하여 symbol 이름 뒤에 모듈 이름과 선택적으로 build ID를 출력할 수 있습니다.

%pS        versatile_init+0x0/0x110 [module_name]
%pSb        versatile_init+0x0/0x110 [module_name ed5019fdf5e53be37cb1ba7899292d7e143b259e]
%pSRb        versatile_init+0x9/0x110 [module_name ed5019fdf5e53be37cb1ba7899292d7e143b259e]
        (with __builtin_extract_return_addr() translation)
%pBb        prev_fn_of_versatile_init+0x88/0x88 [module_name ed5019fdf5e53be37cb1ba7899292d7e143b259e]

BPF와 tracing에서 조사한 포인터

141-154

BPF/tracing에서 사전에 조사한 포인터

%pks        kernel string
%pus        user string

`k`와 `u` 지정자는 각각 커널 메모리와 사용자 메모리에서 미리 조사한 메모리를 출력합니다. 뒤따르는 `s`는 문자열 출력을 뜻합니다. 일반 `vsnprintf()`에서 직접 사용할 때 `(k)`와 `(u)` 표시는 무시되지만, 예를 들어 BPF의 `bpf_trace_printk()`에서 사용하면 fault 없이 포인터가 가리키는 메모리를 읽습니다.

커널 포인터

155-170

커널 포인터 (Kernel Pointers)

%pK        01234567 or 0123456789abcdef

비특권 사용자에게 숨겨야 하는 커널 포인터를 출력할 때 `%pK`를 사용합니다. `%pK`의 동작은 `kptr_restrict` sysctl에 따라 달라지며 자세한 내용은 `Documentation/admin-guide/sysctl/kernel.rst`를 참조하십시오.

이 modifier는 procfs나 sysfs처럼 사용자 공간이 읽는 파일의 내용을 만들 때만 사용하며 dmesg용이 아닙니다. `printk()` 포인터 hash 관리 방법은 앞의 `%p` 절을 참고하십시오.

수정되지 않은 주소

171-191

수정되지 않은 주소 (Unmodified Addresses)

%px        01234567 or 0123456789abcdef

주소 자체를 정말 출력해야 할 때 `%px`를 사용합니다. 사용하기 전에 커널 메모리 배치에 관한 민감한 정보가 노출되지 않는지 검토해야 합니다. `%px`는 기능상 `%lx` 또는 `%lu`와 같지만 검색으로 호출 지점을 찾기 쉽기 때문에 선호됩니다.

`%px`를 사용하기 전에 디버깅 세션에서 `no_hash_pointers`를 활성화한 `%p`로 충분한지 고려하십시오. `%px`가 타당한 예는 panic 직전에 정보를 출력하는 경우입니다. 이미 panic이 발생하므로 민감한 정보를 악용하기 어렵고, `no_hash_pointers`를 켜서 panic을 재현할 필요도 없습니다.

포인터 차이

192-205

포인터 차이 (Pointer Differences)

%td        2560
%tx        a00

포인터 차이를 출력할 때는 `ptrdiff_t`용 `%t` modifier를 사용합니다.

예:

printk("test: difference between pointers: %td\n", ptr2 - ptr1);

struct resource

206-225

`struct resource` 출력

%pr        [mem 0x60000000-0x6fffffff flags 0x2200] or
        [mem 0x60000000 flags 0x2200] or
        [mem 0x0000000060000000-0x000000006fffffff flags 0x2200]
        [mem 0x0000000060000000 flags 0x2200]
%pR        [mem 0x60000000-0x6fffffff pref] or
        [mem 0x60000000 pref] or
        [mem 0x0000000060000000-0x000000006fffffff pref]
        [mem 0x0000000060000000 pref]

`R`과 `r` 지정자는 각각 flags 멤버를 해석한 형태와 해석하지 않은 형태로 resource를 출력합니다. `start`와 `end`가 같으면 시작 값만 출력합니다.

인자는 참조로 전달합니다.

물리 주소 형식

226-238

물리 주소 형식 `phys_addr_t`

%pa[p]        0x01234567 or 0x0123456789abcdef

CPU data path 폭과 관계없이 빌드 옵션에 따라 크기가 달라질 수 있는 `phys_addr_t` 및 `resource_size_t` 같은 파생 형식을 출력합니다.

인자는 참조로 전달합니다.

struct range

239-251

`struct range`

%pra    [range 0x0000000060000000-0x000000006fffffff] or
        [range 0x0000000060000000]

`struct range`는 임의의 `u64` 값 범위를 담습니다. `start`와 `end`가 같으면 시작 값만 출력합니다.

인자는 참조로 전달합니다.

DMA 주소 형식

252-263

DMA 주소 형식 `dma_addr_t`

%pad        0x01234567 or 0x0123456789abcdef

CPU data path 폭과 관계없이 빌드 옵션에 따라 크기가 달라질 수 있는 `dma_addr_t` 형식을 출력합니다.

인자는 참조로 전달합니다.

Escape된 문자열로 출력하는 raw buffer

264-300

Raw buffer를 escape된 문자열로 출력

%*pE[achnops]

다음 buffer를 출력한다고 가정합니다.

1b 62 20 5c 43 07 22 90 0d 5d

주변 따옴표를 제외한 변환 예는 다음과 같습니다.

%*pE                "\eb \C\a"\220\r]"
%*pEhp                "\x1bb \C\x07"\x90\x0d]"
%*pEa                "\e\142\040\\\103\a\042\220\r\135"

변환 규칙은 선택적인 플래그 조합에 따라 적용됩니다. 자세한 내용은 `string_escape_mem` 커널 문서를 참조하십시오.

  • `a`: `ESCAPE_ANY`
  • `c`: `ESCAPE_SPECIAL`
  • `h`: `ESCAPE_HEX`
  • `n`: `ESCAPE_NULL`
  • `o`: `ESCAPE_OCTAL`
  • `p`: `ESCAPE_NP`
  • `s`: `ESCAPE_SPACE`

기본값은 `ESCAPE_ANY_NP`입니다. 이는 특히 SSID 출력 등 많은 경우에 합리적인 선택입니다. Field width를 생략하면 1바이트만 escape됩니다.

16진 문자열로 출력하는 raw buffer

301-314

Raw buffer를 16진 문자열로 출력

%*ph        00 01 02  ...  3f
%*phC        00:01:02: ... :3f
%*phD        00-01-02- ... -3f
%*phN        000102 ... 3f

최대 64바이트의 작은 buffer를 지정한 separator가 있는 16진 문자열로 출력합니다. 더 큰 buffer에는 `print_hex_dump`를 사용하는 편을 고려하십시오.

MAC/FDDI 주소

315-339

MAC/FDDI 주소

%pM        00:01:02:03:04:05
%pMR        05:04:03:02:01:00
%pMF        00-01-02-03-04-05
%pm        000102030405
%pmR        050403020100

6바이트 MAC/FDDI 주소를 16진 표기로 출력합니다. `M`은 byte separator를 포함하고 `m`은 포함하지 않습니다. 기본 separator는 colon(`:`)입니다.

FDDI 주소에는 `M` 뒤의 `F` 지정자로 기본 separator 대신 dash(`-`)를 사용할 수 있습니다.

Bluetooth 주소에는 `M` 뒤의 `R` 지정자를 사용하여 little-endian 주소를 사람이 보기 좋은 역순 byte order로 출력합니다.

인자는 참조로 전달합니다.

IPv4 주소

340-358

IPv4 주소

%pI4        1.2.3.4
%pi4        001.002.003.004
%p[Ii]4[hnbl]

IPv4 주소를 점으로 구분한 10진수로 출력합니다. `I4`는 leading zero 없이, `i4`는 leading zero를 포함해 출력합니다.

추가 지정자 `h`, `n`, `b`, `l`은 각각 host, network, big-endian, little-endian 주소 순서를 뜻합니다. 지정자가 없으면 network/big-endian 순서가 기본입니다.

인자는 참조로 전달합니다.

IPv6 주소

359-377

IPv6 주소

%pI6        0001:0002:0003:0004:0005:0006:0007:0008
%pi6        00010002000300040005000600070008
%pI6c        1:2:3:4:5:6:7:8

Network order의 16비트 16진 IPv6 주소를 출력합니다. `I6`은 colon separator를 포함하고 `i6`은 포함하지 않으며 leading zero는 항상 사용합니다.

`I` 뒤에 `c`를 추가하면 RFC 5952에서 설명하는 압축 IPv6 주소를 출력합니다.

인자는 참조로 전달합니다.

일반 IPv4/IPv6 주소

378-414

IPv4/IPv6 주소: 일반 형식과 port, flowinfo, scope

%pIS        1.2.3.4                or 0001:0002:0003:0004:0005:0006:0007:0008
%piS        001.002.003.004        or 00010002000300040005000600070008
%pISc        1.2.3.4                or 1:2:3:4:5:6:7:8
%pISpc        1.2.3.4:12345        or [1:2:3:4:5:6:7:8]:12345
%p[Ii]S[pfschnbl]

주소가 `AF_INET`인지 `AF_INET6`인지 구별하지 않고 IP 주소를 출력합니다. `IS` 또는 `iS`로 유효한 `struct sockaddr` 포인터를 전달할 수 있습니다.

추가 지정자 `p`, `f`, `s`는 각각 port(IPv4와 IPv6), flowinfo(IPv6), scope(IPv6)를 지정합니다. Port에는 `:`, flowinfo에는 `/`, scope에는 `%` 접두사가 붙고 그 뒤에 실제 값이 옵니다.

IPv6 주소에 `c`를 추가하면 RFC 5952 압축 형식을 사용합니다. `p`, `f`, `s` 중 하나가 추가되면 관련 주소 표현 초안의 권고대로 IPv6 주소를 `[`와 `]`로 감쌉니다.

IPv4 주소에는 `h`, `n`, `b`, `l`도 사용할 수 있으며 IPv6 주소에서는 무시됩니다. 인자는 참조로 전달합니다.

추가 예:

%pISfc                1.2.3.4                or [1:2:3:4:5:6:7:8]/123456789
%pISsc                1.2.3.4                or [1:2:3:4:5:6:7:8]%1234567890
%pISpfc                1.2.3.4:12345        or [1:2:3:4:5:6:7:8]:12345/123456789

UUID/GUID 주소

415-434

UUID/GUID 주소

%pUb        00010203-0405-0607-0809-0a0b0c0d0e0f
%pUB        00010203-0405-0607-0809-0A0B0C0D0E0F
%pUl        03020100-0504-0706-0809-0a0b0c0e0e0f
%pUL        03020100-0504-0706-0809-0A0B0C0E0E0F

16바이트 UUID/GUID를 출력합니다. `l`과 `L`은 little-endian 순서의 소문자 및 대문자 16진 표기, `b`와 `B`는 big-endian 순서의 소문자 및 대문자 16진 표기를 뜻합니다.

추가 지정자가 없으면 big-endian 순서와 소문자 16진 표기가 기본입니다. 인자는 참조로 전달합니다.

dentry 이름

435-449

Dentry 이름

%pd{,2,3,4}
%pD{,2,3,4}

Dentry 이름을 출력합니다. `d_move`와 race가 발생하면 이전 이름과 새 이름이 섞일 수 있지만 oops는 발생하지 않습니다. `%pd`는 과거의 `%s dentry->d_name.name`보다 안전하며 `%pd<n>`은 마지막 `n`개 path component를 출력합니다. `%pD`는 `struct file`에 같은 동작을 적용합니다.

인자는 참조로 전달합니다.

block_device 이름

450-458

`block_device` 이름

%pg        sda, sda1 or loop0p1

`block_device` 포인터의 이름을 출력합니다.

struct va_format

459-480

`struct va_format`

%pV

`struct va_format`은 다음과 같이 format string과 `va_list`를 담습니다.

struct va_format {
        const char *fmt;
        va_list *va;
};

이는 재귀적인 `vsnprintf`를 구현합니다. Format string과 `va_list` 인자의 정확성을 검증하는 장치 없이는 이 기능을 사용하지 마십시오. 인자는 참조로 전달합니다.

Device tree node

481-516

Device tree node

%pOF[fnpPcCF]

Device tree node 구조체 정보를 출력합니다. 기본 동작은 `%pOFf`와 같습니다.

  • `f`: device node `full_name`
  • `n`: device node 이름
  • `p`: device node phandle
  • `P`: device node path 사양, 즉 이름과 `@unit`
  • `F`: device node flags
  • `c`: 주요 compatible string
  • `C`: 전체 compatible string

여러 인자를 사용할 때 separator는 colon(`:`)입니다.

예:

%pOF        /foo/bar@0                        - Node full name
%pOFf        /foo/bar@0                        - Same as above
%pOFfp        /foo/bar@0:10                        - Node full name + phandle
%pOFfcF        /foo/bar@0:foo,device:--P-        - Node full name +
                                          major compatible string +
                                          node flags
                                                D - dynamic
                                                d - detached
                                                P - Populated
                                                B - Populated bus

인자는 참조로 전달합니다.

Fwnode handle

517-540

Fwnode handle

%pfw[fP]

`fwnode_handle` 정보를 출력합니다. 기본값은 path를 포함한 전체 node 이름이며 modifier는 앞의 `%pOF`와 기능상 같습니다.

  • `f`: path를 포함한 node 전체 이름
  • `P`: 주소가 있으면 이를 포함한 node 이름

ACPI 예:

%pfwf        \[email protected]@0        - Full node name
%pfwP        endpoint@0                                - Node name

OF 예:

%pfwf        /ocp@68000000/i2c@48072000/camera@10/port/endpoint - Full name
%pfwP        endpoint                                - Node name

시간과 날짜

541-567

시간과 날짜

%pt[RT]                        YYYY-mm-ddTHH:MM:SS
%pt[RT]s                YYYY-mm-dd HH:MM:SS
%pt[RT]d                YYYY-mm-dd
%pt[RT]t                HH:MM:SS
%pt[RT][dt][r][s]

다음 형식으로 표현되는 날짜와 시간을 사람이 읽을 수 있는 형태로 출력합니다.

지정자인자 형식
Rstruct rtc_time 구조체
Ttime64_t 형식

기본적으로 연도에는 1900을, 월에는 1을 더합니다. 이 동작을 억제하려면 raw 형식 `%pt[RT]r`을 사용하십시오.

`%pt[RT]s`의 `s`는 날짜와 시간 사이의 ISO 8601 separator `T` 대신 space를 사용합니다. 날짜 또는 시간이 생략된 경우에는 영향이 없습니다.

인자는 참조로 전달합니다.

struct clk

568-579

`struct clk`

%pC        pll1

`struct clk`를 출력합니다. `%pC`는 Common Clock Framework에서는 clock 이름을, legacy clock framework에서는 고유한 32비트 ID를 출력합니다. 인자는 참조로 전달합니다.

Bitmap과 cpumask/nodemask

580-595

Bitmap 및 `cpumask`, `nodemask` 같은 파생 형식

%*pb        0779
%*pbl        0,3-6,8-10

`%*pb`는 field width를 bit 수로 사용하여 bitmap을 출력하고, `%*pbl`은 같은 field width를 사용해 bitmap을 범위 목록으로 출력합니다.

Field width는 값으로, bitmap은 참조로 전달합니다. `cpumask`와 `nodemask` 출력을 돕는 `cpumask_pr_args()` 및 `nodemask_pr_args()` helper macro도 제공됩니다.

Page flag와 gfp_flags bitfield

596-620

Page flag와 `gfp_flags` 같은 flags bitfield

%pGp        0x17ffffc0002036(referenced|uptodate|lru|active|private|node=0|zone=2|lastcpupid=0x1fffff)
%pGg        GFP_USER|GFP_DMA32|GFP_NOWARN
%pGv        read|exec|mayread|maywrite|mayexec|denywrite

값을 구성하는 기호 상수의 집합으로 flags bitfield를 출력합니다. 세 번째 문자가 flags 형식을 지정합니다.

  • `p`: page flags, `unsigned long *` 형식 값을 기대합니다.
  • `v`: `vma_flags`, `unsigned long *` 형식 값을 기대합니다.
  • `g`: `gfp_flags`, `gfp_t *` 형식 값을 기대합니다.

Flag 이름과 출력 순서는 구체적인 형식에 따라 달라집니다.

이 형식은 tracepoint의 `TP_printk()` 부분에서 직접 사용하면 안 됩니다. 대신 `<trace/events/mmflags.h>`의 `show_*_flags()` 함수를 사용하십시오. 인자는 참조로 전달합니다.

네트워크 장치 기능

621-631

네트워크 장치 기능

%pNF        0x000000000000c000

`netdev_features_t`를 출력합니다. 인자는 참조로 전달합니다.

V4L2와 DRM FourCC

632-649

V4L2 및 DRM FourCC code(pixel format)

%p4cc

V4L2 또는 DRM이 사용하는 FourCC code를 형식의 endianness와 16진 숫자값까지 포함하여 출력합니다. 인자는 참조로 전달합니다.

예:

%p4cc        BG12 little-endian (0x32314742)
%p4cc        Y10  little-endian (0x20303159)
%p4cc        NV12 big-endian (0xb231564e)

일반 FourCC

650-681

일반 FourCC code

%p4c[h[R]lb]        gP00 (0x67503030)

일반 FourCC code를 ASCII 문자와 16진 숫자값으로 함께 출력합니다. 일반 FourCC는 항상 최상위 byte부터 시작하는 big-endian 형식으로 출력되며, 이는 V4L/DRM FourCC와 반대입니다.

추가 지정자 `h`, `hR`, `l`, `b`는 저장된 byte를 읽을 때 사용할 endianness를 정의합니다. 각각 host, reversed host byte order, little-endian, big-endian으로 해석할 수 있습니다. 인자는 참조로 전달합니다.

Little-endian 시스템에서 `&(u32)0x67503030`을 전달한 예:

%p4ch        gP00 (0x67503030)
%p4chR        00Pg (0x30305067)
%p4cl        gP00 (0x67503030)
%p4cb        00Pg (0x30305067)

Big-endian 시스템에서 같은 값을 전달한 예:

%p4ch        gP00 (0x67503030)
%p4chR        00Pg (0x30305067)
%p4cl        00Pg (0x30305067)
%p4cb        gP00 (0x67503030)

Rust 형식

682-691

Rust

%pA

`%pA`는 Rust 코드에서 `core::fmt::Arguments`를 형식화하는 용도로만 사용합니다. C에서는 사용하지 마십시오.

마무리

692-698

감사의 말 (Thanks)

다른 `%p` 확장을 추가한다면 가능한 경우 `<lib/tests/printf_kunit.c>`에도 하나 이상의 test case를 추가하십시오.

협조와 관심에 감사드립니다.