저는 개인적인 즐거움을 위해 커널 내부 수정, 패치 적용, 장치 드라이버 및 모듈 처리에 관심이 있습니다.
숙련 된 프로그래머를위한 커널 해킹에 대한 포괄적 인 자료가 있습니까?
저는 개인적인 즐거움을 위해 커널 내부 수정, 패치 적용, 장치 드라이버 및 모듈 처리에 관심이 있습니다.
숙련 된 프로그래머를위한 커널 해킹에 대한 포괄적 인 자료가 있습니까?
답변:
**TODO** +editPic: Linux Kernel Developer -> (Ring Layer 0)
+addSection: Kernel Virtualization Engine
KERN_WARN_CODING_STYLE: Do not Loop unless you absolutely have to.
초기화되지 않은 권장 도서
void *i
"책을 읽는 사람은 어느 정도의 삶을 살 때까지, 또는 책의 내용 중 적어도 일부를보고 살기 전까지는 아무도 깊은 책을 이해하지 못할 때까지 책을 이해하지 못합니다." – 에즈라 파운드
천 코드 마일 의 여행은 한 단계로 시작해야합니다. 다음 중 어떤 책으로 시작해야할지 혼동되는 경우 걱정하지 마십시오. 선택한 책 중 하나를 선택하십시오. 방황하는 모든 이가 길을 잃은 건 아니다. 모든 도로가 궁극적으로 고속도로에 연결되면 막 다른 길을 거치지 않고 페이지가 진행됨에 따라 커널 여행에서 새로운 것을 탐색하고 궁극적으로에 연결합니다 code-set
. 주의 깊게 읽고 기억하십시오 : 코드는 문학이 아닙니다 .
남은 것은 물건이나 감정이나 이미지 나 정신적 인 그림이나 기억이나 아이디어가 아닙니다. 기능입니다. 일종의 과정. "더 큰"기능으로 설명 될 수있는 삶의 한 측면. 그러므로, 그것은 실제로 다른 것과 "별도"가 아닌 것으로 보입니다. 칼의 기능처럼-무언가를 자르는 것은 실제로 칼 자체와 분리되지 않습니다. 이 기능은 현재 사용 중이거나 사용하지 않을 수 있지만 잠재적으로 분리되지는 않습니다.
소수성 테스트를위한 Solovay Strassen Derandomized Algorithm :
모순되고 혼동하지 않도록 읽으십시오. 믿거 나 당연한 것으로 여기지도 않습니다. 대화 나 담론을 찾지도 않습니다. 그러나 무게와 고려합니다. 어떤 책은 맛보고, 다른 책은 삼켜야하고, 일부는 씹고 소화해야합니다. 그리고 부지런함과주의를 기울입니다.
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();
}
}
핵심 리눅스 (5-> 1-> 3-> 2-> 7-> 4-> 6)
“자연은 커널이나 쉘이 없습니다. 그녀는 한 번에 모든 것입니다.”-Johann Wolfgang von Goethe
독자는 운영 체제 개념에 정통해야합니다 . 장시간 실행되는 프로세스와 실행이 짧은 프로세스와의 차이점에 대한 공정한 이해; 소프트 및 하드 실시간 제약 조건을 충족하는 동안 내결함성. 읽는 동안 n/ack
핵심 하위 시스템의 Linux 커널 소스에서 선택한 디자인 과 이해하는 것이 중요합니다 .
실과 신호는 플랫폼에 따른 불행, 절망, 공포와 광기의 흔적입니다 (~ Anthony Baxte). 커널에 들어가기 전에 자체 평가 C 전문가가되어야한다고 말하고 있습니다. 또한 Linked Lists, Stacks, Queues, Red Blacks Trees, Hash Functions 등에 대한 경험이 풍부해야합니다.
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;
}
Linux Kernel 소스의 아름다움과 예술은 의도적으로 사용 된 코드 난독 화에 있습니다. 이것은 종종 깨끗하고 우아한 방식으로 둘 이상의 연산을 포함하는 계산 의미를 전달하기 위해 필요하다. 멀티 코어 아키텍처 용 코드를 작성할 때 특히 그렇습니다.
실시간 시스템의 비디오 강의 , 작업 예약 , 메모리 압축 , 메모리 장벽 , SMP
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
리눅스 장치 드라이버 (1-> 2-> 4-> 3-> 8-> ...)
"음악은 당신을 가지고 다니지 않습니다. 당신은 그 작은 감정이나 이야기의 작은 부분에 정말로 집중할 수있는 능력에 의해 엄격히 가지고 가야합니다" -데비 해리
기본적으로 하드웨어 장치와 소프트웨어 커널간에 고속 통신 인터페이스를 설정해야합니다. 장치의 동작과 제어 및 데이터 상태 및 제공된 물리적 채널을 이해하려면 하드웨어 참조 데이터 시트 / 매뉴얼을 읽어야합니다. 특정 아키텍처에 대한 어셈블리 지식과 VHDL 또는 Verilog와 같은 VLSI 하드웨어 설명 언어에 대한 공정한 지식은 장기적으로 도움이 될 것입니다.
Q : 그러나 왜 하드웨어 사양을 읽어야합니까?
A : "소프트웨어가 연결할 수없는 탄소와 실리콘의 틈이 있습니다"-Rahul Sonnad
그러나 위의 내용은 범용 튜링 머신 에서 완전히 시뮬레이션 할 수 있기 때문에 계산 알고리즘 ( 드라이버 코드 - 하 반반 처리 ) 에는 문제가되지 않습니다 . 계산 된 결과가 수학적 영역 에서 사실이면 물리 영역 에서도 마찬가지입니다 .
Linux 장치 드라이버에 대한 비디오 강의 (레크레이션 17 및 18), 임베디드 KMS 드라이버 분석 , 핀 제어 및 GPIO 업데이트 , 공통 클럭 프레임 워크 , 실제 Linux 드라이버 작성-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;
}
커널 네트워킹 (1-> 2-> 3-> ...)
"클랜이라고 부르고, 네트워크라고, 부족이라고, 가족이라고 부릅니다. 당신이 무엇이든, 누구든, 필요합니다."-Jane Howard
커널에서 패킷 연습을 이해하는 것이 커널 네트워킹을 이해하는 데 중요합니다. Netfilter 또는 IPSec 내부 등을 이해하려면이를 이해해야합니다. 리눅스 커널 네트워크 계층의 가장 중요한 두 가지 구조는 다음 struct sk_buff
과 같습니다.struct net_device
static inline int sk_hashed(const struct sock *sk)
{
return !sk_unhashed(sk);
}
커널 디버깅 (1-> 4-> 9-> ...)
의사 소통과 의사 소통을하지 않는 한, 어떤 의미인지 정확히 말하지 않으면 문제가 발생합니다. ~ 컴퓨터에 관한 Alan Turing
Brian W. Kernighan은 "Univers for Beginners (1979)"에서 "가장 효과적인 디버깅 도구는 신중하게 생각하고 신중하게 배치 된 인쇄 설명과 함께"라고 말했다. 무엇을 수집해야하는지 알면 빠른 진단을 위해 올바른 데이터를 빠르게 얻는 데 도움이됩니다. 위대한 컴퓨터 과학자 인 Edsger Dijkstra는 테스트 결과 버그의 존재를 보여줄 수는 있지만 버그가없는 것은 아님을 증명했습니다. 좋은 조사 관행은 문제를 신속하게 해결해야 할 필요성, 기술을 키울 필요성, 주제 전문가의 효과적인 사용 간의 균형을 유지해야합니다.
당신이 바닥에 부딪쳤을 때, 아무것도 작동하지 않는 것 같고 모든 옵션이 부족합니다. 그런 다음 실제 디버깅이 시작됩니다. 버그는 비 효과적인 솔루션의 수정에서 분리하는 데 필요한 중단을 제공 할 수 있습니다.
동영상 강의 커널 디버깅 및 프로파일 링에 , 코어 분석 덤프 , GDB와 멀티 코어 디버깅 , 제어 멀티 코어 경쟁 조건 , 디버깅 전자
/* 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
*/
파일 시스템 (1-> 2-> 6-> ...)
"파일 시스템과 결합 된 가상 메모리를 원했습니다." -켄 톰슨
UNIX 시스템에서는 모든 것이 파일입니다. 파일이 아닌 경우 명명 된 파이프 및 소켓을 제외한 프로세스입니다. 파일 시스템에서 파일은 파일을 구성 inode
하는 실제 데이터에 대한 정보를 포함하는 일련 번호의 일종으로 표시됩니다 . Linux 가상 파일 시스템 VFS
은 마운트 및 사용시 각 파일 시스템의 정보를 메모리에 캐시합니다. 파일과 디렉토리가 작성, 기록 및 삭제 될 때 이러한 캐시 내의 데이터가 수정되므로 파일 시스템을 올바르게 업데이트하기 위해 많은주의를 기울여야합니다. 이러한 캐시 중 가장 중요한 것은 개별 파일 시스템이 기본 블록 스토리지 장치에 액세스하는 방식으로 통합 된 버퍼 캐시입니다.
스토리지 시스템 , 플래시 친화적 인 파일 시스템의 비디오 강의
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);
}
보안 (1-> 2-> 8-> 4-> 3-> ...)
"UNIX는 사용자가 어리석은 일을하는 것을 막기 위해 고안된 것이 아닙니다. 그로 인해 사용자가 영리한 일을하는 것도 막을 수 있습니다." — 더그 기윈
사용하지 않으면 기술이 작동하지 않습니다. 윤리는 기술에 따라 변화합니다.
" F × S = k "자유와 안전의 산물은 일정합니다. -니븐의 법칙
암호화는 온라인 신뢰의 기초를 형성합니다. 해킹은 기술적, 물리적 또는 인적 요소로 보안 제어를 이용하고 있습니다. 다른 실행중인 프로그램으로부터 커널을 보호하는 것이 안전하고 안정적인 시스템을 향한 첫 단계이지만, 이것으로는 충분하지 않습니다. 다른 사용자 영역 응용 프로그램 간에도 어느 정도의 보호가 있어야합니다. 익스플로잇은 로컬 또는 원격 서비스를 대상으로 할 수 있습니다.
"당신은 당신의 운명을 해킹 할 수없고, 무차별적인 힘을 가할 수 있습니다 ... 당신은 뒷문, 삶의 측면 통로가 필요합니다." -Clyde Dsouza
컴퓨터는 문제를 해결하지 못하고 솔루션을 실행합니다. 모든 비 결정적 알고리즘 코드 뒤에는 결정적인 마음이 있습니다. -/ var / log / dmesg
암호화 및 네트워크 보안에 대한 비디오 강의 , 보안을위한 네임 스페이스 , 원격 공격으로부터 보호 , 안전한 임베디드 리눅스
env x='() { :;}; echo vulnerable' bash -c "echo this is a test for Shellsock"
커널 소스 (0.11-> 2.4-> 2.6-> 3.18)
"커널 프로그래밍의 숙달 인 와인과 마찬가지로 시간이 지남에 따라 성숙합니다. 그러나 와인과 달리 과정에서 더 달콤합니다." -로렌스 무체 카
프로그래머가 예술가라고 생각하지는 않지만 프로그래밍은 매우 창조적 인 직업입니다. 논리 기반 창의성입니다. 컴퓨터 과학 교육은 브러시와 안료를 공부하는 것이 전문 화가가 될 수있는 것 이상으로 전문 프로그래머가 될 수 없습니다. 이미 알고 있듯이 길을 아는 것과 길을 걷는 것에는 차이가 있습니다. 커널 소스 코드로 소매를 감아 손을 더럽히는 것이 가장 중요합니다. 마지막으로 이렇게 얻은 커널 지식 으로 어디를 가든지 빛을 발할 것 입니다.
미성숙 코더들은 모방한다. 성숙한 코더는 훔칩니다. 나쁜 코더는 자신이 취하는 것을 훼손하고, 좋은 코더는 그것을 더 나은 것으로 만들거나 적어도 다른 것으로 만듭니다. 좋은 코더는 자신의 도난을 독특하고 완전히 찢어진 느낌과 완전히 다른 느낌으로 용접합니다.
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/*
Linux Kernel Newbies 는 훌륭한 리소스입니다.
난 당신이 "읽기 제안 요컨대 리눅스 커널 그렉 크로아 - 하트만에 의해", " 리눅스 커널의 이해 로버트 사랑을". 읽어야합니다 :)
리눅스 장치 드라이버 는 또 다른 좋은 자료입니다. 그것은 당신에게 내면의 일에 들어가는 또 다른 방법을 줄 것입니다. 서문에서 :
이 책은 표면적으로 리눅스 시스템 용 장치 드라이버 작성에 관한 책입니다. 물론 그것은 가치있는 목표입니다. 새로운 하드웨어 제품의 흐름은 곧 느려지지 않을 것이며 누군가는 새로운 가제트를 모두 Linux에서 작동하게해야 할 것입니다. 그러나이 책은 Linux 커널의 작동 방식과 작업을 사용자의 요구 또는 관심사에 맞게 조정하는 방법에 대해서도 설명합니다. 리눅스는 개방형 시스템입니다. 이 책을 통해 더 많은 개발자 커뮤니티가 더 개방적이고 접근하기를 바랍니다.
Linux 문서 프로젝트를 참조하십시오 . 특히 "Linux 커널 모듈 안내서".
Linux Kernel 2.4 Internals 는 또 다른 온라인 리소스입니다. 부팅을 시작으로 꽤 '접지'접근 방식을 취하는 것으로 보입니다. TOC는 다음과 같습니다.
그리고 더 달콤하게하기 위해 Robert Love out의 새로운 Linux Kernel Development Third Edition이 있으며 Slashdot은 검토를 받았습니다.
Claudia Salzberg et al.의 Linux Kernel Primer로 시작하십시오. 초보자부터 시작하는 것이 좋습니다. Robert Love의 책은 초보자가 시작해야 할 책이 아닙니다. 후기 책은 중간 수준 이상입니다.