Estou interessado em modificar os componentes internos 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?
Estou interessado em modificar os componentes internos 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?
Respostas:
**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 os não inicializados
void *i
"Os homens não entendem os 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 milhas-código deve começar com um único passo. Se você 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 conectam ao code-set
. Leia com atenção e lembre-se: o 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();
}
}
Core 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 nos 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 opções de design feitas pela fonte do kernel do linux nos subsistemas principais.
Threads [e] sinais [são] uma trilha de miséria, desespero, horror e loucura dependente de plataforma (~ Anthony Baxte). Dito isto, você deve ser um especialista em autoavaliaçã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. Isso é especialmente verdade ao escrever código para arquitetura de vários núcleos.
Vídeo Palestras em Tempo Real Sistemas , agendamento de tarefas , memória de compressão , 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 leva você junto. Você tem que levá-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 Assembly para sua arquitetura específica e conhecimento razoável de VLSI Hardware Description Languages como VHDL ou Verilog o ajudarão a longo prazo.
P : Mas, por que tenho que ler as especificações de hardware?
R : Porque, "existe um abismo de carbono e silício que o software não consegue superar" - Rahul Sonnad
No entanto, o exposto acima não representa um problema para os algoritmos computacionais ( código do driver - processamento na metade inferior ), pois ele pode ser totalmente simulado em uma máquina universal de Turing . Se o resultado calculado é verdadeiro no domínio matemático , é certo que também é verdadeiro no domínio físico .
Palestras em vídeo sobre drivers de dispositivo Linux (Lec. 17 e 18), anatomia de um driver KMS incorporado , controle de pinos e atualização GPIO , 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 você chamar, 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
estruct 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 se quer dizer, é provável que ocorra problemas. ~ 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 liberar uma fixação na solução ineficaz.
Palestras em vídeo sobre depuração e criação de perfil do kernel , análise de despejo de núcleo , depuração de vários núcleos com GDB , controle de condições de corrida de vários núcleos , eletrônica de depuração
/* 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 assim como os 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 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 cache de buffer, 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 , sistema de arquivos compatível com flash
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 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 obviamente isso não é suficiente: também deve existir algum grau de proteção entre os 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 em vídeo sobre criptografia e segurança de rede , namespaces para segurança , proteção contra ataques remotos , Linux embarcado seguro
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 seu conhecimento do kernel assim adquirido , aonde 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 sobre receitas de 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 Linux é um ótimo recurso.
Eu sugiro que você leia " Linux Kernel in a Nutshell ", de Greg Kroah-Hartman e " Understanding the 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; é provável que o fluxo de novos produtos de hardware não diminua tão cedo e alguém precisará 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 O projeto de documentação do Linux . Particularmente o "Guia do módulo Linux Kernel".
O Linux Kernel 2.4 Internals é 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, há 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.