Коротка відповідь полягає в тому, що .ko файл - це ваш об’єктовий файл, пов'язаний з деякими ядрами, автоматично генерованими структурами даних, які потрібні ядру.
Файл .o - це об'єктний файл ваших модулів - результат компіляції ваших файлів c. Потім система збирання ядра автоматично створює ще один файл C з деякими структурами даних, що описують модуль ядра (з назвою your_module_kmod.c), компілює цей файл C в інший об'єктний файл і пов'язує ваш об'єктний файл та файл об'єкта, який він створив разом для створення .ko файл.
Динамічний лінкер в ядрі, який відповідає за завантаження модулів ядра, розраховує знайти структуру даних, яку ядро поставило в об'єкт kmod, у файл .ko і не зможе завантажити ваш модуль ядра без них.