
Pode ser uma pergunta incoerente sobre os cabeçalhos do kernel, pois não tenho um entendimento claro sobre isso e onde e como ele é usado. Acho que pode ser sinalizado. Minha pergunta tem 3 partes:
Acho que os cabeçalhos do kernel fornecem uma interface para que outras partes do kernel, como os módulos, possam usá-los. Esse é o meu conhecimento livresco. Não vi ou encontrei nenhum código que usasse cabeçalhos de kernel (agradeceria se alguém pudesse me indicar). Também pode ser usado no espaço do usuário? Qualquer exemplo de código seria apreciado.
Descobri que o uso de
make headers_install
cabeçalhos de kernel é exposto pelo espaço do usuário, mas ao mesmo tempo é desencorajado o uso de cabeçalhos do kernel no espaço do usuário. Se for desencorajado, então qual é a utilidade de expô-lo ao espaço do usuário?Conformeesseeesse, os arquivos de cabeçalho do kernel (arquivos .h) devem estar em 3 locais: a.
/usr/include/linux/kernel.h
que é destinado ao espaço do usuário b./lib/modules/$(uname -r)/build/include/linux/sched.h
que são módulos externos c./usr/src/...
que é usado para módulos do kernel Isso significa que arquivos de cabeçalho em diretórios diferentes têm finalidades diferentes ou interfaces ou assinaturas diferentes? Em outras palavras,#include <linux/xyz.h>
o código do espaço do usuário tem um significado diferente#include <linux/xyz.h>
do módulo do kernel? O módulo externo também é igual ao módulo do kernel?
Obrigado.
Responder1
Bem-vindo ao Unix e Linux StackExchange!
Sim, os cabeçalhos do kernel fornecem uma interface para outras partes do kernel - nisso você está totalmente correto. Eles também incluem definições para a interface entre o kernel e o espaço do usuário - mas geralmente a interface "bruta" do kernel não é usada diretamente, mas por meio da biblioteca C (geralmente glibc
).
A interface userspace-kernel pode incluir múltiplas versões de uma chamada de sistema específica, por motivos de compatibilidade com versões anteriores. Ao fazer a chamada do sistema através da biblioteca C, todos os aplicativos obtêm a mesma versão da chamada do sistema real e, portanto, uma garantia de comportamento consistente. Além disso, quando a parte relevante da interface do kernel for atualizada, você só precisará atualizar a biblioteca C para aproveitar as vantagens dos novos recursos.
(Por exemplo, quando time_t é estendido para 64 bits em arquiteturas de 32 bits para evitar o problema Y2K38, a biblioteca C pode passar a usar sempre a versão de 64 bits da interface do kernel, mas ter um mapeamento configurável no espaço do usuário para aplicativos que ainda usam a versão de 32 bits. Nesse ponto, as funções que usam time_t de 32 bits podem se tornar obsoletas e removidas do kernel, e a biblioteca C pode fornecer soluções alternativas melhores para aplicativos legados que ainda usam o tipo de 32 bits.)
Portanto, a menos que você também esteja compilando suas próprias versões da biblioteca C, geralmente você deve preferir os cabeçalhos de desenvolvimento da biblioteca C em vez de usar os cabeçalhos do kernel diretamente.
Os cabeçalhos /usr/include/linux/
geralmente vêm com o pacote de cabeçalho de desenvolvimento da biblioteca C e descrevem a versão do kernel para a qual o arquivo C foi compilado. Isso é o que um desenvolvedor de aplicativos de espaço de usuário normalmente precisa.
/lib/modules/$(uname -r)/build
geralmente é um link simbólico para /usr/src/...
onde os cabeçalhos ou o código-fonte completo da versão real do kernel em execução estão armazenados. É usado ao compilar módulos de kernel externos (também conhecidos como de terceiros), ou seja, módulos de kernel de fontes que não estão integradas ao código-fonte do kernel principal. Esses cabeçalhos incluem as assinaturas de versão da API do kernel necessárias para que os módulos possam usar APIs internas do kernel específicas da versão.