Estou interessado em modificar as partes internas do kernel, aplicar patches, manipular drivers e módulos de dispositivo, para minha diversão pessoal.
Existe um recurso abrangente para hackers do kernel, destinado a programadores experientes?
**TODO** +editPic: Linux Kernel Developer -> (Ring Layer 0)
+addSection: Kernel Virtualization Engine
KERN_WARN_CODING_STYLE: Do not Loop unless you absolutely have to.
Livros recomendados para o Não inicializado
void *i
"Os homens não entendem livros até que tenham uma certa quantidade de vida, ou de qualquer forma nenhum homem entende um livro profundo, até que tenha visto e vivido pelo menos parte de seu conteúdo". –Ezra Pound
Uma jornada de mil código-milhas deve começar com uma única etapa. Se estiver confuso sobre qual dos seguintes livros começar, não se preocupe, escolha qualquer um de sua escolha. Nem todos os que vagueiam estão perdidos. Como todas as estradas finalmente se conectam à estrada, você explorará coisas novas em sua jornada do kernel à medida que as páginas progridem sem atingir nenhum beco sem saída e, finalmente, se conecta ao code-set
. Leia com atenção e lembre-se: Código não é literatura.
O que resta não é uma coisa ou uma emoção ou uma imagem ou uma imagem mental ou uma memória ou mesmo uma idéia. É uma função. Um processo de algum tipo. Um aspecto da vida que pode ser descrito como uma função de algo "maior". E, portanto, parece que não é realmente "separado" dessa outra coisa. Como a função de uma faca - cortar algo - não é, de fato, separada da própria faca. A função pode ou não estar em uso no momento, mas é potencialmente NUNCA separada.
Algoritmo derandomizado por Solovay Strassen para teste de primazia :
Leia para não contradizer e refutar; nem acreditar e dar como certo; nem encontrar conversa e discurso; mas pesar e considerar. Alguns livros são para serem degustados, outros para serem engolidos e alguns para serem mastigados e digeridos: ou seja, alguns livros devem ser lidos apenas em partes, outros para serem lidos, mas não curiosamente, e alguns para serem lidos inteiramente , e com diligência e atenção.
static void tasklet_hi_action(struct softirq_action *a)
{
struct tasklet_struct *list;
local_irq_disable();
list = __this_cpu_read(tasklet_hi_vec.head);
__this_cpu_write(tasklet_hi_vec.head, NULL);
__this_cpu_write(tasklet_hi_vec.tail, this_cpu_ptr(&tasklet_hi_vec.head));
local_irq_enable();
while (list) {
struct tasklet_struct *t = list;
list = list->next;
if (tasklet_trylock(t)) {
if (!atomic_read(&t->count)) {
if (!test_and_clear_bit(TASKLET_STATE_SCHED,
&t->state))
BUG();
t->func(t->data);
tasklet_unlock(t);
continue;
}
tasklet_unlock(t);
}
local_irq_disable();
t->next = NULL;
*__this_cpu_read(tasklet_hi_vec.tail) = t;
__this_cpu_write(tasklet_hi_vec.tail, &(t->next));
__raise_softirq_irqoff(HI_SOFTIRQ);
local_irq_enable();
}
}
Núcleo Linux (5 -> 1 -> 3 -> 2 -> 7 -> 4 -> 6)
“A natureza não tem núcleo nem casca; ela é tudo de uma vez ”- Johann Wolfgang von Goethe
O leitor deve ser bem versado em conceitos de sistema operacional ; um entendimento justo dos processos de longa execução e suas diferenças com os processos com breves rajadas de execução; tolerância a falhas, atendendo a restrições de tempo real suaves e difíceis. Durante a leitura, é importante entender e n/ack
as escolhas de design feitas pela fonte do kernel linux nos subsistemas principais.
Threads [e] sinais [são] uma trilha dependente de plataforma de miséria, desespero, horror e loucura (~ Anthony Baxte). Dito isto, você deve ser um especialista em auto-avaliação C antes de mergulhar no kernel. Você também deve ter uma boa experiência com listas vinculadas, pilhas, filas, árvores de negros vermelhos, funções de hash, etc.
volatile int i;
int main(void)
{
int c;
for (i=0; i<3; i++) {
c = i&&&i;
printf("%d\n", c); /* find c */
}
return 0;
}
A beleza e a arte da fonte do Kernel Linux estão na ofuscação deliberada do código usada junto. Isso geralmente é necessário para transmitir o significado computacional que envolve duas ou mais operações de maneira limpa e elegante. Isto é especialmente verdade ao escrever código para arquitetura com vários núcleos.
Palestras de vídeo em sistemas em tempo real , Agendamento de tarefas , Compactação de memória , Barreiras de memória , SMP
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
Drivers de dispositivo Linux (1 -> 2 -> 4 -> 3 -> 8 -> ...)
"A música não carrega você. Você precisa carregá-la estritamente pela sua capacidade de realmente se concentrar apenas naquele pequeno núcleo pequeno de emoção ou história". - Debbie Harry
Sua tarefa é basicamente estabelecer uma interface de comunicação de alta velocidade entre o dispositivo de hardware e o kernel do software. Você deve ler a folha de dados/manual de referência de hardware para entender o comportamento do dispositivo e seus estados de controle e dados e canais físicos fornecidos. Conhecimento de montagem para sua arquitetura específica e conhecimento razoável de linguagens de descrição de hardware VLSI, como VHDL ou Verilog, ajudarão você a longo prazo.
[~ # ~] q [~ # ~] : Mas, por que preciso ler as especificações de hardware?
[~ # ~] a [~ # ~] : Porque: "Existe um abismo de carbono e silício que o software não consegue superar" - Rahul Sonnad
No entanto, o acima exposto não apresenta problemas para Algoritmos computacionais ( Código do driver - processamento na metade inferior), pois pode ser totalmente simulado em niversal Turing Machine . Se o resultado calculado é verdadeiro no domínio matemático , é certo que também é verdadeiro no domínio físico .
Palestras de vídeo em drivers de dispositivo Linux (Lec. 17 e 18), Anatomia de um driver KMS incorporado , Pin Control e GPIO Update , Common Clock Framework , Escreva um driver Linux real - Greg KH
static irqreturn_t phy_interrupt(int irq, void *phy_dat)
{
struct phy_device *phydev = phy_dat;
if (PHY_HALTED == phydev->state)
return IRQ_NONE; /* It can't be ours. */
/* The MDIO bus is not allowed to be written in interrupt
* context, so we need to disable the irq here. A work
* queue will write the PHY to disable and clear the
* interrupt, and then reenable the irq line.
*/
disable_irq_nosync(irq);
atomic_inc(&phydev->irq_disable);
queue_work(system_power_efficient_wq, &phydev->phy_queue);
return IRQ_HANDLED;
}
Rede de Kernel (1 -> 2 -> 3 -> ...)
“Chame de clã, de rede, de tribo, de família: seja lá como for, seja quem for, você precisa de um.” - Jane Howard
Compreender um passo a passo de pacote no kernel é a chave para entender a rede do kernel. Entender isso é essencial se queremos entender os aspectos internos do Netfilter ou IPSec e muito mais. As duas estruturas mais importantes da camada de rede do kernel do linux são: struct sk_buff
e struct net_device
static inline int sk_hashed(const struct sock *sk)
{
return !sk_unhashed(sk);
}
Depuração do Kernel (1 -> 4 -> 9 -> ...)
A menos que, ao se comunicar com ele, se diga exatamente o que significa, o problema provavelmente resultará. ~ Alan Turing, sobre computadores
Brian W. Kernighan, no artigo Unix for Beginners (1979), disse: "A ferramenta de depuração mais eficaz ainda é o pensamento cuidadoso, juntamente com declarações impressas criteriosamente". Saber o que coletar ajudará você a obter os dados corretos rapidamente para um diagnóstico rápido. O grande cientista da computação Edsger Dijkstra disse uma vez que os testes podem demonstrar a presença de bugs, mas não a ausência deles. Boas práticas de investigação devem equilibrar a necessidade de resolver problemas rapidamente, a necessidade de desenvolver suas habilidades e o uso eficaz de especialistas no assunto.
Há momentos em que você atinge o fundo do poço, nada parece funcionar e você fica sem todas as suas opções. É então que a depuração real começa. Um bug pode fornecer a interrupção que você precisa para desativar uma fixação na solução ineficaz.
Palestras de vídeo na depuração e criação de perfil do kernel , Análise de despejo de núcleo , Depuração multicore com GDB , Controlando condições de corrida com vários núcleos , Depurando eletrônicos
/* Buggy Code -- Stack frame problem
* If you require information, do not free memory containing the information
*/
char *initialize() {
char string[80];
char* ptr = string;
return ptr;
}
int main() {
char *myval = initialize();
do_something_with(myval);
}
/* “When debugging, novices insert corrective code; experts remove defective code.”
* – Richard Pattis
#if DEBUG
printk("The above can be considered as Development and Review in Industrial Practises");
#endif
*/
Sistemas de arquivos (1 -> 2 -> 6 -> ...)
"Eu queria ter memória virtual, pelo menos quando associada a sistemas de arquivos". - Ken Thompson
Em um sistema UNIX, tudo é um arquivo; se algo não é um arquivo, é um processo, exceto para tubos e soquetes nomeados. Em um sistema de arquivos, um arquivo é representado por um inode
, um tipo de número de série que contém informações sobre os dados reais que compõem o arquivo. O sistema de arquivos virtual do Linux VFS
armazena em cache as informações na memória de cada sistema de arquivos, à medida que é montado e usado. Muito cuidado deve ser tomado para atualizar o sistema de arquivos corretamente, pois os dados nesses caches são modificados à medida que os arquivos e diretórios são criados, gravados e excluídos. O mais importante desses caches é o Buffer Cache, que é integrado à maneira como os sistemas de arquivos individuais acessam seus dispositivos de armazenamento em bloco subjacentes.
Palestras de vídeo em sistemas de armazenamento , Flash Friendly File System
long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
{
struct open_flags op;
int fd = build_open_flags(flags, mode, &op);
struct filename *tmp;
if (fd)
return fd;
tmp = getname(filename);
if (IS_ERR(tmp))
return PTR_ERR(tmp);
fd = get_unused_fd_flags(flags);
if (fd >= 0) {
struct file *f = do_filp_open(dfd, tmp, &op);
if (IS_ERR(f)) {
put_unused_fd(fd);
fd = PTR_ERR(f);
} else {
fsnotify_open(f);
fd_install(fd, f);
}
}
putname(tmp);
return fd;
}
SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
{
if (force_o_largefile())
flags |= O_LARGEFILE;
return do_sys_open(AT_FDCWD, filename, flags, mode);
}
Segurança (1 -> 2 -> 8 -> 4 -> 3 -> ...)
"O UNIX não foi projetado para impedir que seus usuários façam coisas estúpidas, pois isso também os impediria de fazer coisas inteligentes". - Doug Gwyn
Nenhuma técnica funciona se não for usada. A ética muda com a tecnologia.
" F × S = k" o produto da liberdade e da segurança é uma constante. - Leis de Niven
A criptografia forma a base da confiança online. O hacking está explorando os controles de segurança em um elemento técnico, físico ou humano. Proteger o kernel de outros programas em execução é o primeiro passo em direção a um sistema seguro e estável, mas isso obviamente não é suficiente: também deve existir algum grau de proteção entre diferentes aplicativos do usuário. As explorações podem ter como alvo serviços locais ou remotos.
“Você não pode invadir seu destino, força bruta ... você precisa de uma porta dos fundos, um canal lateral para a Vida." ― Clyde Dsouza
Computadores não resolvem problemas, eles executam soluções. Por trás de todo código algorítmico não determinístico , existe uma mente determinada . --/var/log/dmesg
Palestras de vídeo sobre criptografia e segurança de rede , Namespaces for Security , Proteção contra Ataques remotos , Secure Embedded Linux
env x='() { :;}; echo vulnerable' bash -c "echo this is a test for Shellsock"
Origem do Kernel (0.11 -> 2.4 -> 2.6 -> 3.18)
"Como o vinho, o domínio da programação do kernel amadurece com o tempo. Mas, ao contrário do vinho, fica mais doce no processo". --Lawrence Mucheka
Você pode não pensar que os programadores são artistas, mas a programação é uma profissão extremamente criativa. É criatividade baseada em lógica. A educação em ciência da computação não pode tornar ninguém um programador especialista, assim como estudar pincéis e pigmentos pode tornar alguém um pintor especialista. Como você já sabe, há uma diferença entre conhecer o caminho e percorrê-lo; é de extrema importância arregaçar as mangas e sujar as mãos com o código-fonte do kernel. Finalmente, com o seu kernel assim adquirido conhecimento, onde quer que você vá, você brilhar.
Codificadores imaturos imitam; codificadores maduros roubam; codificadores ruins desfiguram o que recebem, e bons codificadores transformam isso em algo melhor, ou pelo menos em algo diferente. O bom programador solda seu roubo em um sentimento único, totalmente diferente daquele em que foi rasgado.
Palestras em vídeo em Receitas do Kernel
linux-0.11
├── boot
│ ├── bootsect.s head.s setup.s
├── fs
│ ├── bitmap.c block_dev.c buffer.c char_dev.c exec.c
│ ├── fcntl.c file_dev.c file_table.c inode.c ioctl.c
│ ├── namei.c open.c pipe.c read_write.c
│ ├── stat.c super.c truncate.c
├── include
│ ├── a.out.h const.h ctype.h errno.h fcntl.h
│ ├── signal.h stdarg.h stddef.h string.h termios.h
│ ├── time.h unistd.h utime.h
│ ├── asm
│ │ ├── io.h memory.h segment.h system.h
│ ├── linux
│ │ ├── config.h fdreg.h fs.h hdreg.h head.h
│ │ ├── kernel.h mm.h sched.h sys.h tty.h
│ ├── sys
│ │ ├── stat.h times.h types.h utsname.h wait.h
├── init
│ └── main.c
├── kernel
│ ├── asm.s exit.c fork.c mktime.c panic.c
│ ├── printk.c sched.c signal.c sys.c system_calls.s
│ ├── traps.c vsprintf.c
│ ├── blk_drv
│ │ ├── blk.h floppy.c hd.c ll_rw_blk.c ramdisk.c
│ ├── chr_drv
│ │ ├── console.c keyboard.S rs_io.s
│ │ ├── serial.c tty_io.c tty_ioctl.c
│ ├── math
│ │ ├── math_emulate.c
├── lib
│ ├── close.c ctype.c dup.c errno.c execve.c _exit.c
│ ├── malloc.c open.c setsid.c string.c wait.c write.c
├── Makefile
├── mm
│ ├── memory.c page.s
└── tools
└── build.c
Linux_source_dir/Documentation/*
Iniciantes no Kernel do Linux é um ótimo recurso.
Eu sugiro que você leia " Linux Kernel in a Nutshell ", de Greg Kroah-Hartman e " Entendendo o Linux Kernel ", de Robert Love. Deve ler :)
Drivers de dispositivo Linux é outro bom recurso. Daria a você outra maneira de entrar no funcionamento interno. Do prefácio:
Este é, na superfície, um livro sobre como escrever drivers de dispositivo para o sistema Linux. Esse é um objetivo digno, é claro; o fluxo de novos produtos de hardware provavelmente não diminuirá tão cedo, e alguém terá que fazer com que todos esses novos gadgets funcionem com o Linux. Mas este livro também é sobre como o kernel do Linux funciona e como adaptar seu funcionamento às suas necessidades ou interesses. Linux é um sistema aberto; com este livro, esperamos que seja mais aberto e acessível a uma comunidade maior de desenvolvedores.
Veja The Projeto de documentação do Linux . Particularmente o "Guia do módulo Linux Kernel".
Internos do Kernel 2.4 do Linux é outro recurso online para se olhar. Parece ter uma abordagem bastante básica, começando com a inicialização. Aqui o sumário:
E, para torná-lo ainda mais doce, existe uma nova terceira edição do Linux Kernel Development de Robert Love e Slashdot tem uma revisão.
Comece com o Linux Kernel Primer de Claudia Salzberg et al. Bom para começar para iniciantes. O livro de Robert Love definitivamente não é o livro que os iniciantes deveriam começar. O último livro está acima do nível intermediário.