Encontrei a seguinte resposta aqui :
A resposta curta é que o arquivo .ko é seu arquivo de objeto vinculado a algumas estruturas de dados geradas automaticamente pelo kernel que são necessárias pelo kernel.
O arquivo .o é o arquivo de objeto dos seus módulos - o resultado da compilação dos arquivos c. O sistema de compilação do kernel cria automaticamente outro arquivo C com algumas estruturas de dados que descrevem o módulo do kernel (chamado your_module_kmod.c), compila esse arquivo C em outro arquivo de objeto e vincula seu arquivo de objeto e o arquivo de objeto que ele criou juntos para criar o .ko Arquivo.
O vinculador dinâmico no kernel encarregado de carregar os módulos do kernel, espera encontrar a estrutura de dados que o kernel colocou no objeto kmod no arquivo .ko e não poderá carregar o módulo do kernel sem eles.
Também a partir dessa fonte , citando tldp : Até versões do kernel 2.4, era ".o" e, desde 2.6, é ".ko".