KMIDIFF(1) Libabigail KMIDIFF(1)

kmidiff - مقایسه KMIهای درخت‌های هسته لینوکس

دستور kmidiff رابط‌های باینری ماژول‌های هسته (KMI) را میان دو درخت هسته لینوکس مقایسه می‌کند. رابط باینری KMI رابطی است که هسته لینوکس در اختیار ماژول‌های خود قرار می‌دهد. درخت‌های مورد نظر در اینجا، حاصل ساخت (build) درخت منبع هسته لینوکس هستند.

نمونه‌ای از نحوه ساخت هسته در صورتی که بخواهید با استفاده از kmidiff آن را با هسته دیگری مقایسه کنید:

git clone -b v4.5 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git linux/v4.5
cd linux/v4.5
make allyesconfig all

سپس ماژول‌ها را در یک دایرکتوری نصب کنید، برای نمونه، زیردایرکتوری build/modules از درخت منبع هسته خودتان:

mkdir build/modules
make modules_install INSTALL_MOD_DIR=build/modules

سپس فهرستی از رابط‌های صادرشده (exported) توسط هسته را که می‌خواهید مقایسه کنید، بسازید:

cat > kmi-whitelist << EOF
[kernel_4.5_kmi_whitelist]
 init_task
 schedule
 dev_queue_xmit
 __kmalloc
 printk
EOF

فرض کنید کار مشابهی را برای شاخه v4.6 از هسته لینوکس انجام داده‌اید؛ اکنون این دو دایرکتوری را در اختیار دارید: linux/v4.5 و linux/v4.6. ماژول‌های آن‌ها در دایرکتوری‌های linux/v4.5/build/modules و linux/v4.6/build/modules موجود هستند.

برای مقایسه KMI آن‌ها، kmidiff نیاز دارد بداند باینری‌های vmlinux و ماژول‌های مرتبط با آن‌ها را در کجا پیدا کند. خط فرمان به این صورت خواهد بود:

kmidiff                                     \
  --kmi-whitelist  linux/v4.6/kmi-whitelist \
  --vmlinux1       linux/v4.5/vmlinux       \
  --vmlinux2       linux/v4.6/vmlinux       \
                   linux/v4.5/build/modules \
                   linux/v4.6/build/modules

این ابزار از کتابخانه libabigail برای تحلیل باینری و همچنین اطلاعات اشکال‌زدایی (debug) مرتبط با آن استفاده می‌کند. در ادامه نحوه عملکرد کلی آن شرح داده شده است.

هنگامی که دستور اجرا صادر می‌شود، یک باینری و اطلاعات اشکال‌زدایی مرتبط با آن خوانده و تحلیل می‌شود. بدین منظور، libabigail به‌طور پیش‌فرض توصیف نوع‌های داده‌ایِ قابل‌دسترسی از طریق رابط‌هایی (توابع و متغیرها) را که خارج از واحد ترجمه (translation unit) خود قابل مشاهده هستند، تحلیل می‌کند. پس از انجام این تحلیل، یک پیکره رابط باینری برنامه (Application Binary Interface Corpus) تنها با در نظر گرفتن زیرمجموعه‌ای از نوع‌های قابل‌دسترسی از رابط‌های مرتبط با نمادهای ELF http://en.wikipedia.org/wiki/Executable_and_Linkable_Format که توسط باینری تعریف و صادر شده‌اند، ساخته می‌شود. این همان پیکره نهایی ABI است که libabigail آن را به عنوان نمایانگر ABI باینری تحلیل‌شده در نظر می‌گیرد.

سپس Libabigail این توانایی را دارد که نمایش‌های متنی از پیکره‌های ABI تولید کند، آن‌ها را با یکدیگر مقایسه نماید، تغییراتشان را تحلیل کرده و درباره آن‌ها گزارش دهد.

به‌طور کلی‌تر، kmidiff به این صورت فراخوانی می‌شود:

kmidiff [options] <first-modules-dir> <second-modules-dir>

به‌طور پیش‌فرض، kmidiff تمام رابط‌ها (توابع و متغیرهای صادرشده) را میان هسته و ماژول‌های آن مقایسه می‌کند. با این حال، در عمل ممکن است برخی کاربران بخواهند زیرمجموعه‌ای از این رابط‌ها را مقایسه نمایند.

به‌طور پیش‌فرض، kmidiff در صورت وجود، از اطلاعات اشکال‌زدایی در قالب اطلاعات اشکال‌زدایی DWARF http://www.dwarfstd.org استفاده می‌کند؛ در غیر این صورت، رابط‌ها را با استفاده از قالب‌های اطلاعات اشکال‌زدایی CTF https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/ctf-spec.pdf یا BTF https://docs.kernel.org/bpf/btf.html (در صورت وجود) مقایسه می‌نماید. در نهایت، اگر هیچ اطلاعات اشکال‌زدایی در این قالب‌ها یافت نشود، تنها نمادهای ELF http://en.wikipedia.org/wiki/Executable_and_Linkable_Format را مد نظر قرار داده و افزوده شدن یا حذف آن‌ها را گزارش می‌کند.

سپس کاربران می‌توانند یک "لیست سفید" (whitelist) از رابط‌ها برای مقایسه تعریف کنند. چنین لیست سفیدی صرفاً یک فایل با قالب "INI" است که به این شکل است:

[kernel_version_x86_64_whitelist]
  function1_name
  function2_name
  global_variable1_name
  ....

توجه داشته باشید که نام بخش (نامی که میان دو قلاب قرار دارد) در آن فایل INI صرفاً باید با رشته "whitelist" خاتمه یابد. بنابراین می‌توانید هر نامی را که می‌خواهید تعریف کنید، برای نمونه [kernel_46_x86_64_whitelist].

سپس هر خط از آن فایل لیست سفید، نام یک تابع یا متغیر صادرشده است. تنها آن رابط‌ها به همراه نوع‌های قابل‌دسترسی از امضاهایشان، به‌طور بازگشتی توسط kmidiff مقایسه خواهند شد.

توجه داشته باشید که kmidiff به‌طور پیش‌فرض، نوع‌های قابل‌دسترسی از رابط‌های مرتبط با نمادهای ELF http://en.wikipedia.org/wiki/Executable_and_Linkable_Format را که توسط هسته لینوکس https://kernel.org تعریف و صادر شده‌اند، به عنوان اجتماع باینری vmlinux و تمام ماژول‌های کامپایل‌شده آن تحلیل می‌کند. سپس آن رابط‌ها را (به همراه نوع‌هایشان) مقایسه می‌نماید.

  • --help | -h

    نمایش یک راهنمای کوتاه درباره دستور و خروج.

  • --version | -v

    نمایش نسخه برنامه و خروج.

  • --verbose

    نمایش پیام‌های پرگو (verbose) در حین اجرا.

  • --debug-info-dir1 | --d1 <di-path1>

    برای مواردی که اطلاعات اشکال‌زدایی باینری‌های هسته اول لینوکس در فایل‌های جداگانه‌ای تفکیک شده است، به kmidiff اعلام می‌کند که آن فایل‌های جداگانه اطلاعات اشکال‌زدایی را از کجا پیدا کند.

    توجه داشته باشید که di-path باید به دایرکتوری ریشه‌ای اشاره کند که اطلاعات اشکال‌زدایی به صورت درختی در زیر آن سازماندهی شده‌اند. در سیستم‌های مبتنی بر Red Hat، این دایرکتوری معمولاً <root>/usr/lib/debug است.

  • --debug-info-dir2 | --d2 <di-path2>

    همانند --debug-info-dir1، این گزینه به kmidiff اعلام می‌کند که اطلاعات اشکال‌زدایی تفکیک‌شده برای باینری‌های هسته دوم لینوکس را از کجا بیابد.

  • --vmlinux1 | --l1 <path-to-first-vmlinux>

    مسیر اولین باینری vmlinux را برای بررسی تعیین می‌کند. این فایل باید باینری فشرده‌نشده vmlinux باشد که با اطلاعات اشکال‌زدایی کامپایل شده است.

  • --vmlinux2 | --l2 <path-to-first-vmlinux>

    مسیر دومین باینری vmlinux را برای بررسی تعیین می‌کند. این فایل باید باینری فشرده‌نشده vmlinux باشد که با اطلاعات اشکال‌زدایی کامپایل شده است.

  • --kmi-whitelist | -w <path-to-interface-whitelist>

    تعیین مسیر فایل لیست سفید رابط‌ها برای بررسی هنگام مقایسه رابط ماژول هسته (KMI) هسته اول با هسته دوم.

    اگر این گزینه مشخص نشود، تمام رابط‌های صادرشده دو هسته مقایسه خواهند شد. این کار زمان زیادی می‌برد و لزوماً معنی‌دار نیست، چرا که احتمالاً نوع‌های داده‌ایِ قابل‌دسترسیِ بسیاری از رابط‌ها قرار است تغییر کنند.

    بنابراین لطفاً اطمینان حاصل کنید که همیشه از این گزینه استفاده می‌کنید، مگر اینکه واقعاً بدانید چه کاری انجام می‌دهید.

  • --suppressions | --suppr <path-to-suppressions>

    استفاده از یک فایل مشخصات نادیده‌گیری (suppression specification) <#suppr-spec-label> واقع در path-to-suppressions. توجه داشته باشید که این گزینه می‌تواند چندین بار در خط فرمان تکرار شود. در این صورت، تمام فایل‌های مشخصات نادیده‌گیری ارائه‌شده مد نظر قرار می‌گیرند.

    لطفاً توجه داشته باشید که به‌طور پیش‌فرض، در صورت مشخص نشدن این گزینه، فایل‌های پیش‌فرض مشخصات نادیده‌گیری <#abidiff-default-supprs-label> بارگذاری می‌شوند.

  • --no-change-categorization | -x

    این گزینه دسته‌بندی تغییرات به بی‌ضرر (harmless) و آسیب‌رسان (harmful) را غیرفعال می‌کند. توجه داشته باشید که این دسته‌بندی پیش‌نیازی برای پالایش تغییرات است، بنابراین این گزینه پالایش تغییرات را نیز غیرفعال می‌سازد. هدف این گزینه افزایش سرعت اجرای برنامه در مواردی است که گراف تغییرات بسیار بزرگ است و کاربر صرفاً علاقه‌مند است، برای مثال، بدون اهمیت دادن به تأثیر احتمالی بر رابط‌ها، به تغییرات گره‌های برگ (leaf node) نگاه کند.

  • --ctf

    استخراج اطلاعات ABI از اطلاعات اشکال‌زدایی CTF https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/ctf-spec.pdf، در صورت وجود در هسته و ماژول‌ها.

  • --btf

    استخراج اطلاعات ABI از اطلاعات اشکال‌زدایی BTF https://docs.kernel.org/bpf/btf.html، در صورت وجود در هسته و ماژول‌ها.

  • --impacted-interfaces | -i

    مشخص کردن اینکه چه رابط‌هایی تحت تأثیر هر تغییر مجزای ABI قرار گرفته‌اند.

  • --full-impact | -f

    صدور گزارش تغییری که تأثیر کامل هر تغییر بر رابط‌های صادرشده را نشان می‌دهد. این همان گزارش پیش‌فرضی است که توسط ابزارهایی مانند abidiff یا abipkgdiff ارائه می‌شود.

  • --exported-interfaces-only

    هنگام استفاده از این گزینه، این ابزار توصیف نوع‌های قابل‌دسترسی توسط رابط‌هایی (توابع و متغیرها) را تحلیل می‌کند که مرتبط با نمادهای ELF http://en.wikipedia.org/wiki/Executable_and_Linkable_Format هستند که توسط هسته لینوکس https://kernel.org تعریف و صادر شده‌اند.

    در غیر این صورت، ابزار همچنین توانایی تحلیل توصیف نوع‌های قابل‌دسترسی توسط رابط‌های مرتبط با نمادهای ELF http://en.wikipedia.org/wiki/Executable_and_Linkable_Format را که خارج از واحد ترجمه خود قابل مشاهده هستند، دارد. با این حال، امکان اخیر به منابع بسیار بیشتری نیاز دارد و منجر به عملیات بسیار کندتری می‌شود.

    به همین دلیل این گزینه به‌طور پیش‌فرض فعال است.

  • --allow-non-exported-interfaces

    هنگام استفاده از این گزینه، این ابزار توصیف نوع‌های قابل‌دسترسی توسط رابط‌هایی (توابع و متغیرها) را که خارج از واحد ترجمه خود قابل مشاهده هستند، تحلیل می‌کند. پس از انجام این تحلیل، یک پیکره ABI تنها با در نظر گرفتن زیرمجموعه‌ای از نوع‌های قابل‌دسترسی از رابط‌های مرتبط با نمادهای ELF http://en.wikipedia.org/wiki/Executable_and_Linkable_Format که توسط باینری تعریف و صادر شده‌اند، ساخته می‌شود. این همان پیکره نهایی ABI است که در برابر پیکره دیگری مقایسه می‌شود.

    اما مشکل این رویکرد آن است که تحلیل تمام رابط‌های قابل مشاهده از خارج از واحد ترجمه‌شان، می‌تواند حجم بسیار زیادی از داده‌ها را در بر داشته باشد و منجر به عملیات بسیار کند شود.

    توجه داشته باشید که این گزینه به‌طور پیش‌فرض غیرفعال است.

  • --show-bytes

    نمایش اندازه‌ها و آفست‌ها به بایت، نه بیت. این گزینه به‌طور پیش‌فرض فعال است.

  • --show-bits

    نمایش اندازه‌ها و آفست‌ها به بیت، نه بایت. به‌طور پیش‌فرض، اندازه‌ها و آفست‌ها به بایت نمایش داده می‌شوند.

  • --show-hex

    نمایش اندازه‌ها و آفست‌ها در مبنای شانزده‌شانزدهی (هگزادسیمال). این گزینه به‌طور پیش‌فرض فعال است.

  • --show-dec

    نمایش اندازه‌ها و آفست‌ها در مبنای ده‌دهی (دسیمال).

Dodji Seketeli

2014-2025, Red Hat, Inc.

May 1, 2026