Como decodificar o cmd = 3222823425 no ioctl no Linux 2.6.29

4

Estou confuso como posso dividir cmd=3222823425 em diferentes partes para descobrir o que esse comando significa realmente no kernel do Linux. Eu sei, algumas funções estão fazendo o comando ioctl com os seguintes parâmetros, mas eu quero saber o que significam esses valores de parâmetro.

fd=21, cmd=3222823425 and arg=3203118816 

Eu tenho procurado em vários fóruns, páginas de manual e outros links para descobrir isso, como o que significa quando uma chamada de sistema cmd em ioctl tem valor de 3222823425 . Descobri que cmd é um número de comando que consiste em type , number e data_type e os primeiros pares são 8-bit inteiros (0-255).

Então, minha pergunta é como decodificar esses valores de parâmetro para descobrir o que esta chamada está tentando fazer?

    
por Junaid 08.01.2013 / 08:36

1 resposta

8

Um ioctl vai para um driver, então a coisa mais importante para descobrir o que um ioctl está fazendo é qual driver está lidando com ele.

O que você leu sobre type , number e data_type é uma convenção que os gravadores de driver devem usar ao escolher números ioctl. Embora drivers diferentes possam usar o mesmo valor para significar coisas completamente diferentes, é melhor evitar isso, de modo que se um ioctl for acidentalmente enviado para o dispositivo errado, há uma boa chance de ele retornar um erro em vez de causar algum evento catastrófico .

Uma boa descrição da convenção está no livro Drivers de dispositivos do Linux (LDD ), capítulo 6 . O data_type é de fato (desde algum tempo no início da série 2.6.x IIRC) feito de duas partes, direction e size .

  • type (8 bits) é uma constante que deve ser consistente nos ioctls implementados em um driver e deve ser diferente de ioctls de dispositivos não relacionados, se possível. Há um repositório desatualizado de valores type em Documentation/ioctl/ioctl-number.txt .
  • number (8 bits) deve ser diferente para todos os ioctls em um driver.
  • direction (2 bits) indica a direção da transferência de dados (0 = nenhum, 1 = gravação, 2 = leitura, 3 = ambos).
  • size é o tamanho do buffer de dados, se o argumento ioctl for um ponteiro para um buffer de dados.

O número de ioctl deve ser

 direction << 30 | size << 16 | type << 8 | number

(Se você estiver escrevendo um driver, use as macros _IOC_* definidas em asm-generic/ioctl.h .)

Para o seu número de ioctl 3222823425 = 0xc0186201, obtemos type = 0x62 (conhecido como “bit3 vme host bridge” em 1999), number = 1, direction = 2 e size = 0x18 = 24, então o ioctl leva um valor de 24- parâmetro de entrada de byte.

Esse valor ioctl deve ser definido como _IOR(0x62, 0x01, struct somestruct) ou algo equivalente como _IOR('b', 1, struct somestruct) , em que struct somestruct é uma estrutura de 24 bytes. Se você não souber qual driver está processando o ioctl, poderá procurar uma chamada como essa na origem do kernel para reunir candidatos. No entanto, observe que uma pesquisa de texto simples geralmente não encontra o driver, pois é comum usar uma macro, por exemplo, #define FOOIO_TYPE 0x62 seguido por #define FOOIO_SOMETHING _IOR(FOOIO_TYPE, 1, struct foobar) .

Uma chamada ioctl tem dois parâmetros além do descritor de arquivo com o qual o ioctl atua: o número do ioctl cmd e um argumento arg . O argumento pode ser um valor imediato ou um ponteiro para um buffer. Aqui, se o gravador de driver estiver seguindo a convenção, arg deverá ser um ponteiro para um buffer de 24 bytes no espaço de memória do aplicativo.

    
por 09.01.2013 / 03:58