《Linux设备驱动》 -- 也就是我们所说的LDD3了; 适合一定基础的人阅读,深入学习Linux不可或缺的知识; 《UNIX环境高级编程》 这本书并不是面对linux内核的书,但是我是从最基础看这本书逐步入门的...; 《Linux内核完全剖析》 本书对早期Linux内核(v0.12)全部代码文件进行了详细、全面的注释和说明,旨在帮助读者用较短的时间对Linux的工作机理获得全面而深刻的理解,为进一步学习和研究Linux...虽然选择的版本较低,但该内核已能够正常编译运行,并且其中已包括了Linux工作原理的精髓。...《Linux那些事》 由复旦一群大神所写,团队为fudan_adc,主要写了我是xxx系列,本人比较喜欢对USB 部分的描述,不得不说大神就是大神。...《Linux设备驱动开发详解》 由华清远见出身的大神所写,宋宝华大神所写,华清远见出来的技术杠杠的。 《深入理解计算机操作系统》 当然啦,不得不说大学学过的操作系统啊!!!!
而linux就是受其影响。。。。 ? 第五版是2012年出的,也比较新。...写的非常好,建议一定要买!可作入门,但即使是高手,也应看看,学习作者分析问题的方法和思想。其实是无数次印刷了,经典不能错过。...本书称不上非常的通俗,但是在有一定的基础的情况下还是比较容易看懂的。本书是世面上极少见的讲述内部网关路由技术的经典书籍,内容极为丰富。...网络体系结构:linux内核中网络协议的设计与实现》 ?...一本在kernel实现网络功能的基础书籍,最好还是看英文版的,翻译的实在太烂了。有条件的还是看原版吧,没办法啊,中国的此类书籍基本上落后老美3-4年。结合linux源代码分析一书收获更多。
本文将从源码角度分析epoll的实现机制,使用的内核版本为 ➜ bionic git:(ffdd392b8196) git remote -v origin git://git.launchpad.net...-4.15.0-45.48 有关如何找到对应的内核源码,请参考 找到运行的Ubuntu版本对应的内核源码。...我们先看下wait变量的类型 // include/linux/wait.h typedef struct wait_queue_entry wait_queue_entry_t; ......所有监听对象检查完毕后,此时满足条件的对象已经被拷贝到用户提供的events里,到这里方法就可以返回了。 至此,epoll_wait 方法也分析完毕。...有关 epoll_ctl 方法及其他epoll内容,我们会在另起文章再来分析。
Linux内核源码分析方法 一、内核源码之我见 Linux内核代码的庞大令不少人“望而生畏”,也正因为如此,使得人们对Linux的了解仅处于泛泛的层次。...我也是通过一个项目接触了Linux内核源码的分析,从源码的分析工作中,我受益颇多。除了获取相关的内核知识外,也改变了我对内核代码的过往认知: 1.内核源码的分析并非“高不可攀”。...内核源码分析的难度不在于源码本身,而在于如何使用更合适的分析代码的方式和手段。...这里所说的一切资源是指无论是Baidu、Google大型网络搜索引擎,还是操作系统原理教材和专业书籍,亦或是他人提供的经验和资料,甚至是Linux源码提供的文档、注释和源码标识符的名称(不要小看代码中的标识符的命名...目前的Linux源码会把模块相关的文档说明保存在源码目录的documention的文件夹下,如果待分析的模块没有文档说明,这多少会增加定位关键源码文件的难度,但是不会导致我们找不到我们要分析的源码。
网络协议有很多协议族,常见的是AF_Inet、AF_Unix,前者是IPv4,后者用于本地通信。...unix_proto_getname, unix_proto_read, unix_proto_write, unix_proto_select, unix_proto_ioctl }; 二、建立连接源码分析...1 创建socket 调用socket()系统调用时需要指定family,才能找到对应的操作函数集合。...buf = NULL; upd->bp_head = upd->bp_tail = 0; } } --upd->refcnt; } 三、读发送接收源码分析...连接是通过文件系统路径来绑定的,读写数据是通过两个缓冲区来实现的。 Unix Socket与Pipe的不同在于Pipe是单缓冲区,只能用于单向通信,而Unix Socket是双缓冲区,能够双向通信。
上面的文章已经分析了tcp建立的整个过程,下面我们来看下write是如何实现tcp写的。...// include/linux/fs.h static inline ssize_t call_write_iter(struct file *file, struct kiocb *kio,...调用这个方法的第三个参数为方法msg_data_left的返回值,该值为我们最开始调用write时,传入的要写的数据长度。...do_error的逻辑大体上为,如果当前写成功的字节数大于0,则正常返回当前写成功的字节数,如果等于0,则调用sk_stream_error方法,获取当前应该返回给用户的错误码并赋值给err,最后返回err...进入while循环,循环继续的条件为当前剩余要写的字节数大于0。 5. 设置copy变量的值为0,该变量用于表示这次while循环可拷贝的字节数。 6.
调用sock->ops->listen(sock, backlog)继续执行具体的listen逻辑。 由第一篇文章我们可以知道,sock->ops->listen指向的方法为inet_listen。...该方法的逻辑在第二篇文章中有讲。 5. 调用sk->sk_prot->hash(sk)方法将sk放到全局listening的hashtable中。...根据sk的端口等信息,找到其所属的listening_hash中的bucket。...hashinfo->listening_hash为存放listen sock的hashtable,在对sk进行hash后,根据hash值,找到其所属的bucket列表,ilb变量用来指向这个bucket...列表的头。
之前的文章已经分析了tcp的建立过程以及tcp读和写,下面我们继续看下shutdown方法。...->ops->shutdown指向的方法继续执行shutdown逻辑。...由第一篇文章我们可以知道,sock->ops->shutdown指向的方法是inet_shutdown。...调用sk->sk_prot->shutdown指向的方法继续执行shutdown逻辑。 3. 调用sk->sk_state_change方法,唤醒那些在监听sock状态变化的阻塞线程。...由第一篇文章可以知道,sk->sk_prot->shutdown指向的方法为tcp_shutdown。
/* * linux/mm/memory.c * * (C) 1991 Linus Torvalds */ /* * demand-loading started 01.12.91 -...invalidate()"s - I wasn't doing enough of them. */ #include #include #include linux.../sched.h> #include linux/head.h> #include linux/kernel.h> volatile void do_exit(long code); static...释放from开始,连续的n个大小为4MB的页面对应的物理地址。...对应的页目录项的地址。
我的源码分析,是基于Linux Kernel 4.4.19 (https://www.kernel.org/pub/linux/kernel/v4.x/patch-4.4.19.gz)版本的,由于namespace...##copy_process源码分析 linux/linux-4.4.19/kernel/fork.c #1243中,定义了copy_process()函数的实现: static struct task_struct...给了子进程 为新进程分配并设置新的 pid ###dup_task_struct源码分析 dup_task_struct()函数的定义在linux-4.4.19/kernel/fork.c #334 static...###sched_fork源码分析 linux-4.4.19/kernel/sched/core.c #2187 int sched_fork(unsigned long clone_flags, struct...return 0; } 我们可以看到sched_fork大致完成了两项重要工作,一是将子进程状态设置为 TASK_RUNNING,二是为其分配 CPU ###copy_thread_tls源码分析
继上一篇 Linux epoll 源码分析 1,我们来继续看下 epoll_ctl 方法。...调用ep_item_poll方法,将epitem等相关信息组成的实例,放到被监听文件的事件变动通知队列中,这样当被监听文件有事件变化时,就会调用该队列里各个实例的回调方法,看是否有其感兴趣的事件发生。...// include/linux/poll.h static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address...至此,ep_insert方法涉及到的逻辑算是全部讲完了。 结合第一篇文章的内容,现在epoll体系的知识已经形成了一个逻辑闭环。...限于篇幅原因,ep_remove和ep_modify方法我们会在下一篇文章中分析。
Linux下的tcp编程中,第一步就是要创建socket,本文将从源码角度看下socket是如何被创建的。...本文使用的linux内核版本为 ➜ bionic git:(ffdd392b8196) git remote get-url origin git://git.launchpad.net/~ubuntu-kernel...-45.48 有关如何找到当前运行的Ubuntu版本对应的内核源码,请参考 找到运行的Ubuntu版本对应的内核源码。...在看具体的源码分析之前,最好先看下socket的man文档,这样能对socket api有个大概的了解。...有关epoll的源码分析,请参见 Linux epoll 源码分析 1 Linux epoll 源码分析 2 Linux epoll 源码分析 3 5.
所以,当该bind方法调用结束后,用户提供的struct sockaddr参数变量还是可以继续使用的。 3. 调用sock->ops->bind方法,继续执行bind逻辑。...inet->inet_num的值是在sk->sk_prot->get_port(sk, snum)方法中设置的。...对比上一篇文章中的tcp_prot中各字段的值我们可以知道,sk->sk_prot->get_port指向的是inet_csk_get_port方法。...如果不存在,则创建一个新的inet_bind_bucket实例tb,并将其放入head指向的列表中,供后续做冲突检查。 5. 调用inet_bind_hash方法,设置sk为tb的owner。...inet->inet_num的值赋值给inet->inet_sport,所以,inet->inet_sport的最终值就是用户传入的端口。
在linux下,假设我们想打开文件/dev/tty,我们可以使用系统调用open,比如: int fd = open("/dev/tty", O_RDWR, 0); 本文将从源码角度看下,在linux内核中...,open方法是如何打开文件的。...// include/linux/fs.h struct filename { const char *name; /* pointer to actual...path component就是以‘/’字符分割的路径的各个部分。 3. 将该path component的信息赋值给nd->last字段。 4....限于篇幅原因,本文暂且分析到这,下一篇继续分析vfs_open方法。 完。
上一篇文章我们分析了shutdown方法的实现,这里我们再看下close方法。...先将file->f_count字段减1,再判断该字段的值是否为0,如果是,则继续执行if内的逻辑。 2. 调用init_task_work方法,设置file销毁的回调函数为____fput。 3....调用task_work_add方法,将销毁该文件的task放到待执行的任务队列中。 最终____fput方法会被回调,继续执行文件的close逻辑。...,找到对应的file指针,然后再调用__fput方法,传入这个file参数。...本文为了代码上的简便,省略了很多内存释放的逻辑。 与shutdown方法相比,close方法不仅会根据当前状态决定是否要发送fin消息,还会释放该socket涉及到的一系列内存。
在上一篇文章 Linux epoll 源码分析 2 中,我们分析了 epoll_ctl 的 ep_insert 方法,在这里我们继续看下 ep_remove 和 ep_modify 方法。...struct file *file = epi->ffd.file; ... // 将epitem从tcp socket的事件变动通知队列中移除 ep_unregister_pollwait...return 0; } 该方法的逻辑和ep_insert方法里的逻辑比较像,它先覆盖epitem中epoll_event的旧值,然后检查该文件当前已经就绪的事件,如果这些事件中有我们感兴趣的事件,则把epitem...放到eventpoll的rdllist队列中,最后通知因调用epoll_wait堵塞的线程,它们可以继续执行了。...至此,epoll的所有逻辑都已讲完。 有关tcp在何种情况下,会通知给epoll何种事件,我们会在其他文章中详细讲解。
connect方法对应的内核源码为 // net/socket.c SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr...拷贝用户提供的目标地址到address变量。 3. 调用sock->ops->connect方法继续执行connect操作。...由第一篇文章可以知道,sock->ops->connect指向的方法为inet_stream_connect。...当连接建立成功后,sk->sk_state的值会被设置成TCP_ESTABLISHED,同时堵塞的线程会被唤醒,使其从inet_wait_for_connect方法中返回,返回值大于0。...调用tcp_connect方法发送SYN消息,及启动SYN消息的重传定时。
之后又调用call_read_iter方法,传入这些新的参数,继续执行read逻辑 // include/linux/fs.h static inline ssize_t call_read_iter...设置变量seq的值,使其持有tp->copied_seq字段的地址,tp->copied_seq字段用于表示下一个要拷贝给用户的数据的seq是多少。 4....进入while循环,该循环继续的条件为len>0,即剩余要拷贝给用户的数据的字节数大于0。 6....当tcp层收到数据后,会将数据放到sk->sk_receive_queue队列中,等待用户读取,该部分逻辑的详细分析,我们以后会另开文章详细讲解。 7....seq的值,即下一个要拷贝字节的位置,copied的值,即已经拷贝的字节数,len的值,即剩余要拷贝的字节数,最后,根据情况决定是否要将skb从sk->sk_receive_queue队列中移除。
accept方法对应的内核源码为 // net/socket.c SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr...找一个未使用的文件描述符赋值给newfd。 6. 为newsock创建一个新的struct file实例,并赋值给newfile。 7....1. struct socket是给用户使用的,struct sock是内核内部使用的。...4. struct sock存放的是各种sock的通用数据,用面向对象的语言来说,它是一个基类,它的子类很多,比如struct tcp_sock等,当内核要访问子类数据时,先会把struct sock强转成子类类型...将req->sk指向的struct sock实例赋值给newsk,并返回给上层。 4. 当queue指向的队列为空时,则根据flags中是否有O_NONBLOCK标志,设置timeo的值。
前两篇文章中我们讲到,shutdown和close方法会发送fin消息给对方,开始tcp连接的关闭流程,现在我们从源码角度看下tcp连接关闭的具体过程,以及中间发送的消息和涉及到的各种状态。...下面看下服务端如何处理fin消息的。 由之前的文章可知,ip层在收到消息之后,会通过回调tcp_v4_rcv方法将消息转给tcp层。...设置sk的flag为SOCK_DONE。 3....由上可见,谁先发起的tcp连接关闭请求,谁最终就会进入到TIME_WAIT状态,在写服务器端代码时,这个是要注意的。 现在剩下最后一步,即服务端ack消息的处理。...至此,服务端的sk就已经完全关闭。 客户端的sk等TIME_WAIT状态的定时超时之后,也会自动关闭。 这样,tcp连接的关闭流程就完整了。
领取专属 10元无门槛券
手把手带您无忧上云