导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页
    1. 主页
    2. miumiu
    • 资料
    • 关注 0
    • 粉丝 1
    • 我的积分 1035
    • 主题 20
    • 帖子 20
    • 最佳 4
    • 群组 0

    WOWLV 5

    @miumiu

    1035
    积分
    4
    声望
    29
    资料浏览
    20
    帖子
    1
    粉丝
    0
    关注
    注册时间 最后登录

    miumiu 取消关注 关注

    miumiu 发布的最佳帖子

    • 安利一本书:《RISC-V 手册》

      作者:Hello小崔
      链接:https://zhuanlan.zhihu.com/p/148284839
      来源:知乎

      在A国封杀中国相关科技公司的大环境下,操作系统和芯片成为大家讨论很火的事情了。ARM公司受限A国法律限制,开始对HW明令禁止提供ARM架构芯片(当然也包括最近比较火的台积电不再接受HW芯片订单),国人又开始讨论如何打破芯片壁垒,是夹缝生存还是寻求突破?(额...其实没那么复杂,就是听说RISC-V能替代ARM和X86架构,并且社区比较火,觉得要与时俱进学习下)。

      学习新的架构(比如ARM或X86)有多种学习方法,比如通过阅读相关书籍著作了解学习,或是报名课程学习,或者查看官网资料。无论是哪种方式,最终都将回归到查看官网提供的芯片手册这条路,因为手册最准确,也最权威。

      RISC-V英文手册其实还好,相比ARMv8的6666页来说...如果有点吃力,就看下《RISC-V 手册》吧,下载地址:
      RISC-V-Reader-Chinese-v2p1.pdf

      为什么安利这本书,因为这本书对于想要了解RISC-V或者学习RISC-V指令,都比较适用。全书无论是介绍RISC-V还是相关指令,都说明为什么这样设计,有什么优点等等(现在X86为什么不好),让人容易理解和记住,总比上来就说架构寄存器多少个,都有什么功能等等,然后开始死记硬背好得多(恩,x86和arm都是这种感觉)。以下节选《RISC-V 手册》,算是对RISC-V和这本书有个印象。

      RISC-V是什么RISC-V(“RISC five”)的目标是成为一个通用的指令集架构(ISA):

      • 它要能适应包括从最袖珍的嵌入式控制器,到最快的高性能计算机等各种规模的处理器。

      • 它应该能兼容各种流行的软件栈和编程语言。

      • 它应该适应所有实现技术,包括现场可编程门阵列(FPGA)、 专用集成电路(ASIC)、 全定制芯片, 甚至未来的设备技术。

      • 它应该对所有微体系结构样式都有效:例如微编码或硬连线控制;顺序或乱序执行流水线; 单发射或超标量等等。

      • 它应该支持广泛的专业化,成为定制加速器的基础,因为随着摩尔定律的消退,加速器的重要性日益提高。

      • 它应该是稳定的,基础的指令集架构不应该改变。

        更重要的是,它不能像以前的专有指令集架构一样被弃用,例如AMD Am29000、 Digital Alpha、 Digital VAX、Hewlett Packard PA-RISC、 Intel i860、 Intel i960、 Motorola 88000、以及ZilogZ8000。

      RISC-V的不同寻常不仅在于它是一个最近诞生的指令集架构(它诞生于最近十年,而大多数其他指令集都诞生于20世纪70到80年代),而且在于它是一个开源的指令集架构。

      与几乎所有的旧架构不同,它的未来不受任何单一公司的浮沉或一时兴起的决定的影响(这一点让许多过去的指令集架构都遭了殃)。

      它属于一个开放的,非营利性质的基金会。 RISC-V基金会的目标是保持RISC-V的稳定性,仅仅出于技术原因缓慢而谨慎地发展它,并力图让它之于硬件如同Linux之于操作系统一样受欢迎。

      计算机体系结构的传统方法是增量ISA,新处理器不仅必须实现新的ISA扩展,还必须实现过去的所有扩展。

      目的是为了保持向后的二进制兼容性,这样几十年前程序的二进制版本仍然可以在最新的处理器上正确运行。

      这一要求与来自于同时发布新指令和新处理器的营销上的诱惑共同导致了ISA的体量随时间大幅增长。例如,图1.2显示了当今主导ISA80x86的指令数量增长过程。这个指令集架构的历史可以追溯到1978年,在它的漫长生涯中,它平均每个月增加了大约三条指令。

      这个传统意味着x86-32(我们用它表示32位地址版本的x86)的每个实现必须实现过去的扩展中的错误设计,即便它们不再有意义。例如, 图1.3描述了x86的ASCII Adjust afterAddition(aaa)指令,该指令早已失效。

      作为一个类比,假设一家餐馆只提供固定价格的餐点,最初只是一顿包含汉堡和奶昔的小餐。 随着时间的推移,它会加入薯条,然后是冰淇淋圣代,然后是沙拉,馅饼,葡萄酒,素食意大利面,牛排,啤酒,无穷无尽,直到它成为一顿大餐。食客可以在那家餐厅找到他们过去吃过的东西,尽管总的来说这样做可能没什么意义。这样做的坏处是,用餐者为每次晚餐支付的宴会费用不断增加。

      RISC-V的不同寻常之处,除了在于它是最近诞生的和开源的以外,还在于:和几乎所有以往的ISA不同,它是模块化的。它的核心是一个名为RV32I的基础ISA,运行一个完整的软件栈。

      RV32I是固定的,永远不会改变。这为编译器编写者,操作系统开发人员和汇编语言程序员提供了稳定的目标。模块化来源于可选的标准扩展,根据应用程序的需要,硬件可以包含或不包含这些扩展。

      这种模块化特性使得RISC-V具有了袖珍化、低能耗的特点,而这对于嵌入式应用可能至关重要。 RISC-V编译器得知当前硬件包含哪些扩展后,便可以生成当前硬件条件下的最佳代码。

      惯例是把代表扩展的字母附加到指令集名称之后作为指示。例如, RV32IMFD将乘法(RV32M),单精度浮点(RV32F)和双精度浮点(RV32D)的扩展添加到了基础指令集(RV32I)中。继续用我们刚才的类比来说, RISC-V提供的是菜单,而不是一顿应有尽有的自助餐。

      主厨只需要烹饪顾客需要的东西(而不是每次都做出一顿盛宴),顾客只需要按他们的订单付费。 RISC-V无需仅仅为了市场吸引力而添加指令。

      RISC-V基金会会决定什么时候在菜单里添加新的选项,而他们只会出于技术原因这样做,而且要在由软硬件专家组成的委员会进行专门的公开讨论以后才会添加。即使那些新选择出现在了菜单上,它们仍是可选的,不会像在增量ISA中那样成为未来所有实现的必要组成部分。

      很通俗易懂,为什么设计RISC-V,因为x86的又老又复杂,并且臃肿(很多用不到的指令)。RISC-V希望吸取前人经验和结合现在的实际情况,开发一种通用的指令集架构。

      发布在 灌水区
      miumiu
      WOW
    • Linux Poll 使用方法和实现

      转载自:https://blog.csdn.net/zhuxiaoping54532/article/details/51701549

      Linux socket之四:使用POLL机制处理多连接

      使用select函数可以处理socket多连接的问题(select的用法参见:http://blog.csdn.net/zhandoushi1982/article/details/5070107),使用POLL也可以实现同样的功能,且调用方式更加简单。原型是:

      [cpp] view plain copy
      struct pollfd {
      int fd; //文件描述符
      short events; //要求查询的事件掩码
      short revents; //返回的事件掩码
      };
      int poll(struct pollfd *ufds, unsigned int nfds, int timeout);

      poll函数使用pollfd类型的结构来监控一组文件句柄,ufds是要监控的文件句柄集合,nfds是监控的文件句柄数量,timeout是等待的毫秒数,这段时间内无论I/O是否准备好,poll都会返回。

      timeout为负数表示无线等待,timeout为0表示调用后立即返回。

      执行结果:为0表示超时前没有任何事件发生;-1表示失败;

      成功则返回结构体中revents不为0的文件描述符个数。pollfd结构监控的事件类型如下:

      [cpp] view plain copy
      #define POLLIN 0x0001
      #define POLLPRI 0x0002
      #define POLLOUT 0x0004
      #define POLLERR 0x0008
      #define POLLHUP 0x0010
      #define POLLNVAL 0x0020

      #define POLLRDNORM 0x0040
      #define POLLRDBAND 0x0080
      #define POLLWRNORM 0x0100
      #define POLLWRBAND 0x0200
      #define POLLMSG 0x0400
      #define POLLREMOVE 0x1000
      #define POLLRDHUP 0x2000

      如上是events事件掩码的值域,POLLIN|POLLPRI类似于select的读事件,POLLOUT|POLLWRBAND类似于select的写事件。当events属性为POLLIN|POLLOUT,表示监控是否可读或可写。

      在poll返回时,即可通过检查revents变量对应的标志位与events是否相同,比如revents中POLLIN事件标志位被设置,则表示文件描述符可以被读取。代码段示例:

      [cpp] view plain copy
      int sockfd; //套接字句柄
      struct pollfd pollfds;
      int timeout;

      timeout = 5000;
      pollfds.fd = sockfd; //设置监控sockfd
      pollfds.events = POLLIN|POLLPRI; //设置监控的事件

      for(;;){
      switch(poll(&pollfds,1,timeout)){ //开始监控
      case -1: //函数调用出错
      printf("poll error \r\n");
      break;
      case 0:
      printf("time out \r\n");
      break;
      default: //得到数据返回
      printf("sockfd have some event \r\n");
      printf("event value is 0x%x",pollfds.revents);
      break;
      }
      }
      原文:http://blog.csdn.net/zhandoushi1982/article/details/7738424

      Linux poll()解析
      poll()函数:这个函数是某些Unix系统提供的用于执行与select()函数同等功能的函数,下面是这个函数的声明:
      #include <poll.h>

      int poll(struct pollfd fds[], nfds_t nfds, int timeout);

      参数说明:

      fds:是一个struct pollfd结构类型的数组,用于存放需要检测其状态的Socket描述符;

      每当调用这个函数之后,系统不会清空这个数组,操作起来比较方便;

      特别是对于 socket连接比较多的情况下,在一定程度上可以提高处理的效率;

      这一点与select()函数不同,调用select()函数之后,select() 函数会清空它所检测的socket描述符集合,导致每次调用select()之前都必须把socket描述符重新加入到待检测的集合中;

      因 此,select()函数适合于只检测一个socket描述符的情况,而poll()函数适合于大量socket描述符的情况;

      nfds:nfds_t类型的参数,用于标记数组fds中的结构体元素的总数量;

      timeout:是poll函数调用阻塞的时间,单位:毫秒;

      返回值:

      0:数组fds中准备好读、写或出错状态的那些socket描述符的总数量;

      ==0:数组fds中没有任何socket描述符准备好读、写,或出错;此时poll超时,超时时间是timeout毫秒;换句话说,如果所检测的 socket描述符上没有任何事件发生的话,那么poll()函数会阻塞timeout所指定的毫秒时间长度之后返回,如果timeout==0,那么 poll() 函数立即返回而不阻塞,如果timeout==INFTIM,那么poll() 函数会一直阻塞下去,直到所检测的socket描述符上的感兴趣的事件发 生是才返回,如果感兴趣的事件永远不发生,那么poll()就会永远阻塞下去;

      -1: poll函数调用失败,同时会自动设置全局变量errno;

      如果待检测的socket描述符为负值,则对这个描述符的检测就会被忽略,也就是不会对成员变量events进行检测,在events上注册的事件也会被忽略,poll()函数返回的时候,会把成员变量revents设置为0,表示没有事件发生;

      另外,poll() 函数不会受到socket描述符上的O_NDELAY标记和O_NONBLOCK标记的影响和制约,也就是说,不管socket是阻塞的还是非阻塞 的,poll()函数都不会收到影响;而select()函数则不同,select()函数会受到O_NDELAY标记和O_NONBLOCK标记的影 响,如果socket是阻塞的socket,则调用select()跟不调用select()时的效果是一样的,socket仍然是阻塞式TCP通讯,相 反,如果socket是非阻塞的socket,那么调用select()时就可以实现非阻塞式TCP通讯;

      所以poll() 函数的功能和返回值的含义与 select() 函数的功能和返回值的含义是完全一样的,两者之间的差别就是内部实现方式不一样,select()函数基本上可以在所有支持文件描述符操作的系统平台上运 行(如:Linux 、Unix 、Windows、MacOS等),可移植性好,而poll()函数则只有个别的的操作系统提供支持(如:SunOS、Solaris、AIX、HP提供 支持,但是Linux不提供支持),可移植性差;

      strust pollfd结构说明:

      typedef struct pollfd {
      int fd; /* 需要被检测或选择的文件描述符*/
      short events; /* 对文件描述符fd上感兴趣的事件 /
      short revents; /
      文件描述符fd上当前实际发生的事件*/
      } pollfd_t;

      typedef unsigned long nfds_t;

      经常检测的事件标记: POLLIN/POLLRDNORM(可读)、POLLOUT/POLLWRNORM(可写)、POLLERR(出错)

      如果是对一个描述符上的多个事件感兴趣的话,可以把这些常量标记之间进行按位或运算就可以了;

      比如:对socket描述符fd上的读、写、异常事件感兴趣,就可以这样做:struct pollfd fds;

      fds[nIndex].events=POLLIN | POLLOUT | POLLERR;

      当 poll()函数返回时,要判断所检测的socket描述符上发生的事件,可以这样做: struct pollfd fds;

      检测可读TCP连接请求:

      if((fds[nIndex].revents & POLLIN) == POLLIN){//接收数据/调用accept()接收连接请求}

      检测可写:

      if((fds[nIndex].revents & POLLOUT) == POLLOUT){//发送数据}

      检测异常:

      if((fds[nIndex].revents & POLLERR) == POLLERR){//异常处理}

      每一个pollfd结构体指定了一个被监视的文件描述符,可以传递多个结构体,指示poll()监视多个文件描述符。每个结构体的events域是监视该文件描述符的事件掩码,由用户来设置这个域。

      revents域是文件描述符的操作结果事件掩码。内核在调用返回时设置这个域。events域中请求的任何事件都可能在revents域中返回。合法的事件

      如下:
      POLLIN
      有数据可读。

      POLLRDNORM
      有普通数据可读。

      POLLRDBAND
      有优先数据可读。

      POLLPRI
      有紧迫数据可读。

      POLLOUT
      写数据不会导致阻塞。

      POLLWRNORM
      写普通数据不会导致阻塞。

      POLLWRBAND
      写优先数据不会导致阻塞。

      POLLMSG
      SIGPOLL 消息可用。
      此外,revents域中还可能返回下列事件:

      POLLER
      指定的文件描述符发生错误。

      POLLHUP
      指定的文件描述符挂起事件。

      POLLNVAL
      指定的文件描述符非法。

      这些事件在events域中无意义,因为它们在合适的时候总是会从revents中返回。使用poll()和select()不一样,你不需要显式地请求异常情况报告。

      POLLIN | POLLPRI等价于select()的读事件,POLLOUT |POLLWRBAND等价于select()的写事件。POLLIN等价于POLLRDNORM |POLLRDBAND,而POLLOUT则等价于POLLWRNORM。

      例如,要同时监视一个文件描述符是否可读和可写,我们可以设置 events为POLLIN |POLLOUT。在poll返回时,我们可以检查revents中的标志,对应于文件描述符请求的events结构体。

      如果POLLIN事件被设置,则文件描述符可以被读取而不阻塞。

      如果POLLOUT被设置,则文件描述符可以写入而不导致阻塞。

      这些标志并不是互斥的:它们可能被同时设置,表示这个文件描述符的读取和写入操作都会正常返回而不阻塞。

      timeout参数指定等待的毫秒数,无论I/O是否准备好,poll都会返回。

      timeout指定为负数值表示无限超时;timeout为0指示poll调用立即返回并列出准备好I/O的文件描述符,但并不等待其它的事件。这种情况下,poll()就像它的名字那样,一旦选举出来,立即返回。

      返回值和错误代码
      成功时,poll()返回结构体中revents域不为0的文件描述符个数;如果在超时前没有任何事件发生,poll()返回0;失败时,poll()返回-1,并设置errno为下列值之一:

      EBADF
      一个或多个结构体中指定的文件描述符无效。

      EFAULT
      fds指针指向的地址超出进程的地址空间。

      EINTR
      请求的事件之前产生一个信号,调用可以重新发起。

      EINVAL
      nfds参数超出PLIMIT_NOFILE值。

      ENOMEM
      可用内存不足,无法完成请求。


      linux的poll机制
      Poll就是监控文件是否可读的一种机制,作用与select一样。
      应用程序的调用函数如下:

      int poll(struct pollfd *fds,nfds_t nfds, int timeout);

      Poll机制会判断fds中的文件是否可读,如果可读则会立即返回,返回的值就是可读fd的数量,如果不可读,那么就进程就会休眠timeout这么长的时间,然后再来判断是否有文件可读,如果有,返回fd的数量,如果没有,则返回0.

      内核实现流程:

      当应用程序调用poll函数的时候,会调用到系统调用sys_poll函数,该函数最终调用do_poll函数,do_poll函数中有一个死循 环,

      在里面又会利用do_pollfd函数去调用驱动中的poll函数(fds中每个成员的字符驱动程序都会被扫描到),驱动程序中的Poll函数的工作 有两个,

      一个就是调用poll_wait 函数,把进程挂到等待队列中去(这个是必须的,你要睡眠,必须要在一个等待队列上面,否则到哪里去唤醒你呢??),

      另一个是确定相关的fd是否有内容可 读,如果可读,就返回1,否则返回0,如果返回1 ,do_poll函数中的count++,

      然后 do_poll函数然后判断三个条件(if (count ||!timeout || signal_pending(current)))如果成立就直接跳出,如果不成立,

      就睡眠timeout个jiffes这么长的时间(调用schedule_timeout实现睡眠),如果在这段时间内没有其他进程去唤醒它,

      那么第二次执行判断的时候就会跳出死循环。如果在这段时间内有其他进程唤醒它,那么也可以跳出死循环返回

      (例如我们可以利用中断处理函数去唤醒它,这样的话一有数据可读,就可以让它立即返回)。

      1.  sys_poll函数位于fs/select.c文件中,代码如下:
        

      asmlinkagelong sys_poll(struct pollfd __user *ufds, unsigned int nfds, long timeout_msecs)

      {

      s64 timeout_jiffies;

           if (timeout_msecs > 0) {
      

      #ifHZ > 1000

               /* We can only overflow if HZ >1000 */
      
               if (timeout_msecs / 1000 >(s64)0x7fffffffffffffffULL / (s64)HZ)
      
                   timeout_jiffies = -1;
      
               else
      

      #endif

                   timeout_jiffies =msecs_to_jiffies(timeout_msecs);
      
           } 
      

      else

      {
      /* Infinite (< 0) or no (0)timeout */

               timeout_jiffies = timeout_msecs;
      
           } 
      
           return do_sys_poll(ufds,nfds, &timeout_jiffies);
      

      }

      它对超时参数稍作处理后,直接调用do_sys_poll。

      1.  do_sys_poll函数也位于位于fs/select.c文件中,我们忽略其他代码:
        

      intdo_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)

      {
      ……

      poll_initwait(&table);

      ……

           fdcount = do_poll(nfds, head,&table, timeout);
      

      ……

      }

      poll_initwait函数非常简单,它初始化一个poll_wqueues变量table:

      poll_initwait> init_poll_funcptr(&pwq->pt, __pollwait); > pt->qproc = qproc;

      即table->pt->qproc= __pollwait,__pollwait将在驱动的poll函数里用到。

      1.  do_sys_poll函数位于fs/select.c文件中,代码如下:
        

      static int do_poll(unsigned int nfds, struct poll_list *list, struct poll_wqueues *wait, s64 *timeout)

      {
      01 ……

      02 for (;;){
      03 ……

      04 if(do_pollfd(pfd, pt)) {
      05 count++;

      06 pt = NULL;

      07 }

      08 ……

      09 if(count || !*timeout || signal_pending(current))

      10 break;

      11 count= wait->error;

      12 if(count)

      13 break;14

      15 if(*timeout < 0) {
      16 /*Wait indefinitely */

      17 __timeout= MAX_SCHEDULE_TIMEOUT;

      18 }else if (unlikely(timeout >= (s64)MAX_SCHEDULE_TIMEOUT-1)) {
      19 /

      20 * Wait for longer than MAX_SCHEDULE_TIMEOUT. Do it in

      21 * a loop

      22 */

      23 __timeout= MAX_SCHEDULE_TIMEOUT - 1;

      24 *timeout-= __timeout;

      25 }else {
      26 __timeout= *timeout;

      27 *timeout= 0;

      28 }29

      30 __timeout= schedule_timeout(__timeout); // 休眠时间由应用提供

      31 if(*timeout >= 0)

      32 *timeout+= __timeout;

      33 }

      34 __set_current_state(TASK_RUNNING);

      35 returncount;

      36 }

      分析其中的代码,可以发现,它的作用如下:

      ① 从02行可以知道,这是个循环,它退出的条件为:

      a. 09行的3个条件之一(count非0,超时、有信号等待处理)

      count顺0表示04行的do_pollfd至少有一个成功。

      b. 11、12行:发生错误

      ② 重点在do_pollfd函数,后面再分析

      ③ 第30行,让本进程休眠一段时间,注意:应用程序执行poll调用后,如果①②的条件不满足,进程就会进入休眠。那么,谁唤醒呢?除了休眠到指定时间被系统唤醒外,还可以被驱动程序唤醒──记住这点,这就是为什么驱动的poll里要调用poll_wait的原因,后面分析。

      1.  do_pollfd函数位于fs/select.c文件中,代码如下:
        

      static inline unsigned int do_pollfd(struct pollfd*pollfd, poll_table *pwait)

      {
      ……

               if(file->f_op && file->f_op->poll)
      
                       mask= file->f_op->poll(file, pwait);
      

      ……

      }

      可见,它就是调用我们的驱动程序里注册的poll函数。

      二、驱动程序:

      驱动程序里与poll相关的地方有两处:一是构造file_operation结构时,要定义自己的poll函数。二是通过poll_wait来调用上面说到的__pollwait函数,pollwait的代码如下:

      staticinline void poll_wait(struct file * filp, wait_queue_head_t * wait_address,poll_table *p)

      {
      if (p && wait_address)

               p->qproc(filp, wait_address, p);
      

      }

      p->qproc就是__pollwait函数,从它的代码可知,它只是把当前进程挂入我们驱动程序里定义的一个队列里而已。它的代码如下:

      staticvoid __pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)

      {
      struct poll_table_entry *entry =poll_get_entry(p);

           if (!entry)
      
               return;
      
           get_file(filp);
      
           entry->filp = filp;
      
           entry->wait_address = wait_address;
      
           init_waitqueue_entry(&entry->wait,current);
      
           add_wait_queue(wait_address,&entry->wait);
      

      }

      执行到驱动程序的poll_wait函数时,进程并没有休眠,我们的驱动程序里实现的poll函数是不会引起休眠的。让进程进入休眠,是前面分析的do_sys_poll函数的30行“__timeout = schedule_timeout(__timeout)”。

      poll_wait只是把本进程挂入某个队列,应用程序调用poll > sys_poll> do_sys_poll > poll_initwait,do_poll > do_pollfd > 我们自己写的poll函数后,再调用schedule_timeout进入休眠。

      如果我们的驱动程序发现情况就绪,可以把这个队列上挂着的进程唤醒。可见,poll_wait的作用,只是为了让驱动程序能找到要唤醒的进程。即使不用poll_wait,我们的程序也有机会被唤醒:

      chedule_timeout(__timeout),只是休眠__time_out这段时间。

      现在来总结一下poll机制:

      1. poll > sys_poll > do_sys_poll >poll_initwait,poll_initwait函数注册一下回调函数__pollwait,它就是我们的驱动程序执行poll_wait时,真正被调用的函数。

      2. 接下来执行file->f_op->poll,即我们驱动程序里自己实现的poll函数

        它会调用poll_wait把自己挂入某个队列,这个队列也是我们的驱动自己定义的;

        它还判断一下设备是否就绪。

      3. 如果设备未就绪,do_sys_poll里会让进程休眠一定时间,这个时间是应用提供的“超时时间”

      4. 进程被唤醒的条件有2:一是上面说的“一定时间”到了,二是被驱动程序唤醒。驱动程序发现条件就绪时,就把“某个队列”上挂着的进程唤醒,这个队列,就是前面通过poll_wait把本进程挂过去的队列。

      5. 如果驱动程序没有去唤醒进程,那么chedule_timeout(__timeou)超时后,会重复2、3动作1次,直到应用程序给定的时间, 然后返回。

      驱动的poll函数编写模板如下:

      static DECLARE_WAIT_QUEUE_HEAD(my_waitq); //休眠要挂的等待队列
      static unsigned drv_poll(struct file *file, poll_table *wait)
      {
      unsigned int mask = 0;
      poll_wait(file, &my_waitq, wait); // 不会立即休眠
      if (有数据)
      mask |= POLLIN | POLLRDNORM;
      return mask;
      }

      发布在 Linux
      miumiu
      WOW
    • Linux 工具快速教程

      转载自:http://whycan.com/t_4494.html (出处:哇酷开发者社区)

      致谢
      README
      Linux基础

      1. 学会使用命令帮助
      2. 文件及目录管理
      3. 文本处理
      4. 磁盘管理
      5. 进程管理工具
      6. 性能监控
      7. 网络工具
      8. 用户管理工具
      9. 系统管理及IPC资源管理
        Linux工具进阶
      10. 程序构建
      11. 程序调试
      12. 性能优化
        工具参考篇
      13. gdb 调试利器
      14. ldd 查看程序依赖库
      15. lsof 一切皆文件
      16. ps 进程查看器
      17. pstack 跟踪进程栈
      18. strace 跟踪进程中的系统调用
      19. ipcs 查询进程间通信状态
      20. top linux下的任务管理器
      21. free 查询可用内存
      22. vmstat 监视内存使用情况
      23. iostat 监视I/O子系统
      24. sar 找出系统瓶颈的利器
      25. readelf elf文件格式分析
      26. objdump 二进制文件分析
      27. nm 目标文件格式分析
      28. size 查看程序内存映像大小
      29. wget 文件下载
      30. scp 跨机远程拷贝
      31. crontab 定时任务

      Linux工具快速教程.pdf

      发布在 Linux
      miumiu
      WOW
    • 精通 Git

      转载自:http://whycan.com/t_4495.html

      目录
      许可证 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
      Scott Chacon 序 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
      Ben Straub 序 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
      献辞 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
      贡献者 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
      引言 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
      起步 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
      关于版本控制 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
      Git 简史 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
      Git 是什么? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
      命令行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
      安装 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
      初次运行 Git 前的配置. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
      获取帮助 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
      Git 基础 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
      获取 Git 仓库. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
      记录每次更新到仓库 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
      查看提交历史 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
      撤消操作 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
      远程仓库的使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
      打标签 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
      Git 别名 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
      Git 分支 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
      分支简介 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
      分支的新建与合并 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
      分支管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
      分支开发工作流 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
      远程分支 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
      变基 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
      服务器上的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
      协议 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
      在服务器上搭建 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
      生成 SSH 公钥 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
      配置服务器 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
      Git 守护进程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
      Smart HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
      GitWeb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
      GitLab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
      第三方托管的选择 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
      分布式 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
      分布式工作流程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
      向一个项目贡献 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
      维护项目 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
      GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
      账户的创建和配置 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
      对项目做出贡献 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
      维护项目 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
      管理组织 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
      脚本 GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
      Git 工具 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
      选择修订版本 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
      交互式暂存 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
      贮藏与清理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
      签署工作 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
      搜索 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
      重写历史 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
      重置揭密 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
      高级合并 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
      Rerere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
      使用 Git 调试 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
      子模块 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
      打包 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
      替换 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
      凭证存储 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
      自定义 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
      配置 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
      Git 属性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
      Git 钩子 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
      使用强制策略的一个例子 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
      Git 与其他系统 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
      作为客户端的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
      迁移到 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429
      Git 内部原理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
      底层命令与上层命令 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
      Git 对象 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
      Git 引用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
      包文件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445
      引用规范 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448
      传输协议 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
      维护与数据恢复 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
      环境变量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468
      附录 A: 在其它环境中使用 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
      图形界面 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
      Visual Studio 中的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
      Git in Visual Studio Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
      Eclipse 中的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
      Git in IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
      Git in Sublime Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478
      Bash 中的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478
      Zsh 中的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479
      Git 在 PowerShell 中使用 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483
      附录 B: 在你的应用中嵌入 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
      命令行 Git 方式. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
      Libgit2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
      JGit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489
      go-git. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493
      Dulwich. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494
      附录 😄 Git 命令 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
      设置与配置 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
      获取与创建项目 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497
      快照基础 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498
      分支与合并 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
      项目分享与更新 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502
      检查与比较 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504
      调试 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
      补丁 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
      邮件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506
      外部系统 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
      管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
      底层命令 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508
      索引 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509

      资料下载:progit_v2_1_36.pdf

      发布在 Linux
      miumiu
      WOW

    miumiu 发布的最新帖子

    • 安利一本书:《RISC-V 手册》

      作者:Hello小崔
      链接:https://zhuanlan.zhihu.com/p/148284839
      来源:知乎

      在A国封杀中国相关科技公司的大环境下,操作系统和芯片成为大家讨论很火的事情了。ARM公司受限A国法律限制,开始对HW明令禁止提供ARM架构芯片(当然也包括最近比较火的台积电不再接受HW芯片订单),国人又开始讨论如何打破芯片壁垒,是夹缝生存还是寻求突破?(额...其实没那么复杂,就是听说RISC-V能替代ARM和X86架构,并且社区比较火,觉得要与时俱进学习下)。

      学习新的架构(比如ARM或X86)有多种学习方法,比如通过阅读相关书籍著作了解学习,或是报名课程学习,或者查看官网资料。无论是哪种方式,最终都将回归到查看官网提供的芯片手册这条路,因为手册最准确,也最权威。

      RISC-V英文手册其实还好,相比ARMv8的6666页来说...如果有点吃力,就看下《RISC-V 手册》吧,下载地址:
      RISC-V-Reader-Chinese-v2p1.pdf

      为什么安利这本书,因为这本书对于想要了解RISC-V或者学习RISC-V指令,都比较适用。全书无论是介绍RISC-V还是相关指令,都说明为什么这样设计,有什么优点等等(现在X86为什么不好),让人容易理解和记住,总比上来就说架构寄存器多少个,都有什么功能等等,然后开始死记硬背好得多(恩,x86和arm都是这种感觉)。以下节选《RISC-V 手册》,算是对RISC-V和这本书有个印象。

      RISC-V是什么RISC-V(“RISC five”)的目标是成为一个通用的指令集架构(ISA):

      • 它要能适应包括从最袖珍的嵌入式控制器,到最快的高性能计算机等各种规模的处理器。

      • 它应该能兼容各种流行的软件栈和编程语言。

      • 它应该适应所有实现技术,包括现场可编程门阵列(FPGA)、 专用集成电路(ASIC)、 全定制芯片, 甚至未来的设备技术。

      • 它应该对所有微体系结构样式都有效:例如微编码或硬连线控制;顺序或乱序执行流水线; 单发射或超标量等等。

      • 它应该支持广泛的专业化,成为定制加速器的基础,因为随着摩尔定律的消退,加速器的重要性日益提高。

      • 它应该是稳定的,基础的指令集架构不应该改变。

        更重要的是,它不能像以前的专有指令集架构一样被弃用,例如AMD Am29000、 Digital Alpha、 Digital VAX、Hewlett Packard PA-RISC、 Intel i860、 Intel i960、 Motorola 88000、以及ZilogZ8000。

      RISC-V的不同寻常不仅在于它是一个最近诞生的指令集架构(它诞生于最近十年,而大多数其他指令集都诞生于20世纪70到80年代),而且在于它是一个开源的指令集架构。

      与几乎所有的旧架构不同,它的未来不受任何单一公司的浮沉或一时兴起的决定的影响(这一点让许多过去的指令集架构都遭了殃)。

      它属于一个开放的,非营利性质的基金会。 RISC-V基金会的目标是保持RISC-V的稳定性,仅仅出于技术原因缓慢而谨慎地发展它,并力图让它之于硬件如同Linux之于操作系统一样受欢迎。

      计算机体系结构的传统方法是增量ISA,新处理器不仅必须实现新的ISA扩展,还必须实现过去的所有扩展。

      目的是为了保持向后的二进制兼容性,这样几十年前程序的二进制版本仍然可以在最新的处理器上正确运行。

      这一要求与来自于同时发布新指令和新处理器的营销上的诱惑共同导致了ISA的体量随时间大幅增长。例如,图1.2显示了当今主导ISA80x86的指令数量增长过程。这个指令集架构的历史可以追溯到1978年,在它的漫长生涯中,它平均每个月增加了大约三条指令。

      这个传统意味着x86-32(我们用它表示32位地址版本的x86)的每个实现必须实现过去的扩展中的错误设计,即便它们不再有意义。例如, 图1.3描述了x86的ASCII Adjust afterAddition(aaa)指令,该指令早已失效。

      作为一个类比,假设一家餐馆只提供固定价格的餐点,最初只是一顿包含汉堡和奶昔的小餐。 随着时间的推移,它会加入薯条,然后是冰淇淋圣代,然后是沙拉,馅饼,葡萄酒,素食意大利面,牛排,啤酒,无穷无尽,直到它成为一顿大餐。食客可以在那家餐厅找到他们过去吃过的东西,尽管总的来说这样做可能没什么意义。这样做的坏处是,用餐者为每次晚餐支付的宴会费用不断增加。

      RISC-V的不同寻常之处,除了在于它是最近诞生的和开源的以外,还在于:和几乎所有以往的ISA不同,它是模块化的。它的核心是一个名为RV32I的基础ISA,运行一个完整的软件栈。

      RV32I是固定的,永远不会改变。这为编译器编写者,操作系统开发人员和汇编语言程序员提供了稳定的目标。模块化来源于可选的标准扩展,根据应用程序的需要,硬件可以包含或不包含这些扩展。

      这种模块化特性使得RISC-V具有了袖珍化、低能耗的特点,而这对于嵌入式应用可能至关重要。 RISC-V编译器得知当前硬件包含哪些扩展后,便可以生成当前硬件条件下的最佳代码。

      惯例是把代表扩展的字母附加到指令集名称之后作为指示。例如, RV32IMFD将乘法(RV32M),单精度浮点(RV32F)和双精度浮点(RV32D)的扩展添加到了基础指令集(RV32I)中。继续用我们刚才的类比来说, RISC-V提供的是菜单,而不是一顿应有尽有的自助餐。

      主厨只需要烹饪顾客需要的东西(而不是每次都做出一顿盛宴),顾客只需要按他们的订单付费。 RISC-V无需仅仅为了市场吸引力而添加指令。

      RISC-V基金会会决定什么时候在菜单里添加新的选项,而他们只会出于技术原因这样做,而且要在由软硬件专家组成的委员会进行专门的公开讨论以后才会添加。即使那些新选择出现在了菜单上,它们仍是可选的,不会像在增量ISA中那样成为未来所有实现的必要组成部分。

      很通俗易懂,为什么设计RISC-V,因为x86的又老又复杂,并且臃肿(很多用不到的指令)。RISC-V希望吸取前人经验和结合现在的实际情况,开发一种通用的指令集架构。

      发布在 灌水区
      miumiu
      WOW
    • 国内的中文Spec可以跟着看看,在这个网址下面都有

      https://cnrv.io/resource

      发布在 灌水区
      miumiu
      WOW
    • 了解RISC-V的指令架构,建议入手看官方的Spec

      riscv-spec-v2.2.pdf

      发布在 灌水区
      miumiu
      WOW
    • 中国开放指令生态(RISC-V)联盟发布的开放指令集与开源芯片发展报告:

      OpenISA-OpenSourceChip-Report.pdf

      发布在 灌水区
      miumiu
      WOW
    • 为什么RISC-V将超越ARM?

      作者:Morris.Zhang
      链接:https://www.zhihu.com/question/450092365/answer/1799057546
      来源:知乎

      近几年间在中/美走访过一些RISC-V基金会和创业项目。从厂商的视角推测,假想差不多10年左右的技术迭代期限,RISC-V技术代际不会挑战Intel,但有可能会挑战ARM M-core,应不会挑战到A-core。

      商业模式上: IP授权才是效益池。以RISC-V的血统,形成稳定传承的公版家族和发展公版生态十分重要的,这是避免IP碎片化和避免芯片产品无法赚钱的关键因素,也是流片成本摊薄并形成普遍经济效益的重要因素。

      RISC-V在这方面的短板是显而易见的:低成本自由授权+厂商随意定义指令的模式使得公版延续无法得到保护,软件和编译器生态所依仗的长期兼容性同样不稳固,碎片化不可避免,MIPS在个别方面亦有前车之鉴。

      与之相对比,RISC家族里的产品化实力和经济效益都很好的当然是ARM,质优+量足+门槛低+大规模流片应用的信誉,收敛了大量公版IP授权案例,比如Qcom虽然自己做CPU,也逐渐转向ARM公版,多快好省;而其严格管控的Architectural-license更是通过ARM design services驱动大厂投入ARM设计,进一步验证和发扬了ARM指令架构和IPs的信誉,同时经历大量workloads的洗礼验证;此外,ARM又十分重视拥抱商业EDA生态以及Fab合作,输出了大量设计工具和IP。

      而反观RISC-V,当下全球有一个百亿级晶体管密度的商用案例么?- 技术生态上: 如今RISC-V的声音不小,当然,RISC-V能够大幅简化电路,但对复杂应用拆解要么增加操作数牺牲性能,要么增加指令集又把系统复杂化,比如其SIMD指令就没有真正堪用的,唯一可用的Hwacha向量指令集(开源)本质上还是协处理器,连乱序执行流水线都整合不进去,更不用说做编译器层优化了;而进一步讲,所谓的复杂指令集实际是在电路层给这些操作建立shortcuts,需要经年累月的设计积累和workload验证,都是有晶圆面积代价的。

      这种情形下,就会限制芯片用途的想象力了,DSA的碎片化和软件生态会成为掣肘,而做通用芯片尤其是CPU的短期市场侵彻可能性是微小的。以及,提一句EDA库,稍大型的商用设计都需要大调RTL,毕竟RISC-V的应用实例少,参考工具不多,很多不能拿来直接用,需要适配经典IP以及开发出新的IP族,这也需要漫长演进以及牺牲晶圆面积代价,最终究竟是在通用领域或是专精领域沉淀出成果还未可知,但至少要形成自己的公版授权生态和装机量,才不至于IP碎片化而带来的窄赛道和低经济效益。

      此处不妨回顾一下历史:ARM有今天成绩,DEC功不可没,老DEC真是有不少财宝的,INTC凭借那次收购StrongARM的IP资源、设计经验积累以及door keeper级别的人才才稳步攻入服务器市场的,而ARM的真正商用也受益于DEC遗产;想象一下,RISC起源的时期有诸多大鲸:IBM Power, SPARC, ALPHA …最终仅有ARM一骑绝尘,倘若没有DEC,ARM也会遇到今天RISC-V的满地碎片局面。

      未来几年,RISC-V会有一些消费侧IoT的小实例,但由于IP碎片化而不容易赚钱,很难挑战ARM-M,不会挑战到A,更不会挑战x86版图。而另一个掣肘是,目前可见开发RISC-V芯片项目有三种方式,一是购买商用IP,二是参考开源代码,三是理想化的从零自研(总不会从第1个管子开始画起)。

      而若从美国的RISC-V商用IP厂商购买IP,则会受EAR管制,比如不能出售IP及提供服务给华为;若采用开源代码或自行开发,目前看不受管制,但需要避免被标准组织终止会员资格,以及美国社区仍可能做出限制。

      引用一句戴伟民先生的讲话:Intel X86和ARM的IP授权虽然给中国带来了繁荣,但却是不自主和不可控的。而架构授权虽然不自主,但是可控且可以繁荣的。基于M-Core、MIPS Alpha的CPU则是自主、可控但不繁荣的。希望中国的CPU可借助RISC-V做到自主、可控、繁荣,并且持续性创新。

      发布在 灌水区
      miumiu
      WOW
    • Linux Poll 使用方法和实现

      转载自:https://blog.csdn.net/zhuxiaoping54532/article/details/51701549

      Linux socket之四:使用POLL机制处理多连接

      使用select函数可以处理socket多连接的问题(select的用法参见:http://blog.csdn.net/zhandoushi1982/article/details/5070107),使用POLL也可以实现同样的功能,且调用方式更加简单。原型是:

      [cpp] view plain copy
      struct pollfd {
      int fd; //文件描述符
      short events; //要求查询的事件掩码
      short revents; //返回的事件掩码
      };
      int poll(struct pollfd *ufds, unsigned int nfds, int timeout);

      poll函数使用pollfd类型的结构来监控一组文件句柄,ufds是要监控的文件句柄集合,nfds是监控的文件句柄数量,timeout是等待的毫秒数,这段时间内无论I/O是否准备好,poll都会返回。

      timeout为负数表示无线等待,timeout为0表示调用后立即返回。

      执行结果:为0表示超时前没有任何事件发生;-1表示失败;

      成功则返回结构体中revents不为0的文件描述符个数。pollfd结构监控的事件类型如下:

      [cpp] view plain copy
      #define POLLIN 0x0001
      #define POLLPRI 0x0002
      #define POLLOUT 0x0004
      #define POLLERR 0x0008
      #define POLLHUP 0x0010
      #define POLLNVAL 0x0020

      #define POLLRDNORM 0x0040
      #define POLLRDBAND 0x0080
      #define POLLWRNORM 0x0100
      #define POLLWRBAND 0x0200
      #define POLLMSG 0x0400
      #define POLLREMOVE 0x1000
      #define POLLRDHUP 0x2000

      如上是events事件掩码的值域,POLLIN|POLLPRI类似于select的读事件,POLLOUT|POLLWRBAND类似于select的写事件。当events属性为POLLIN|POLLOUT,表示监控是否可读或可写。

      在poll返回时,即可通过检查revents变量对应的标志位与events是否相同,比如revents中POLLIN事件标志位被设置,则表示文件描述符可以被读取。代码段示例:

      [cpp] view plain copy
      int sockfd; //套接字句柄
      struct pollfd pollfds;
      int timeout;

      timeout = 5000;
      pollfds.fd = sockfd; //设置监控sockfd
      pollfds.events = POLLIN|POLLPRI; //设置监控的事件

      for(;;){
      switch(poll(&pollfds,1,timeout)){ //开始监控
      case -1: //函数调用出错
      printf("poll error \r\n");
      break;
      case 0:
      printf("time out \r\n");
      break;
      default: //得到数据返回
      printf("sockfd have some event \r\n");
      printf("event value is 0x%x",pollfds.revents);
      break;
      }
      }
      原文:http://blog.csdn.net/zhandoushi1982/article/details/7738424

      Linux poll()解析
      poll()函数:这个函数是某些Unix系统提供的用于执行与select()函数同等功能的函数,下面是这个函数的声明:
      #include <poll.h>

      int poll(struct pollfd fds[], nfds_t nfds, int timeout);

      参数说明:

      fds:是一个struct pollfd结构类型的数组,用于存放需要检测其状态的Socket描述符;

      每当调用这个函数之后,系统不会清空这个数组,操作起来比较方便;

      特别是对于 socket连接比较多的情况下,在一定程度上可以提高处理的效率;

      这一点与select()函数不同,调用select()函数之后,select() 函数会清空它所检测的socket描述符集合,导致每次调用select()之前都必须把socket描述符重新加入到待检测的集合中;

      因 此,select()函数适合于只检测一个socket描述符的情况,而poll()函数适合于大量socket描述符的情况;

      nfds:nfds_t类型的参数,用于标记数组fds中的结构体元素的总数量;

      timeout:是poll函数调用阻塞的时间,单位:毫秒;

      返回值:

      0:数组fds中准备好读、写或出错状态的那些socket描述符的总数量;

      ==0:数组fds中没有任何socket描述符准备好读、写,或出错;此时poll超时,超时时间是timeout毫秒;换句话说,如果所检测的 socket描述符上没有任何事件发生的话,那么poll()函数会阻塞timeout所指定的毫秒时间长度之后返回,如果timeout==0,那么 poll() 函数立即返回而不阻塞,如果timeout==INFTIM,那么poll() 函数会一直阻塞下去,直到所检测的socket描述符上的感兴趣的事件发 生是才返回,如果感兴趣的事件永远不发生,那么poll()就会永远阻塞下去;

      -1: poll函数调用失败,同时会自动设置全局变量errno;

      如果待检测的socket描述符为负值,则对这个描述符的检测就会被忽略,也就是不会对成员变量events进行检测,在events上注册的事件也会被忽略,poll()函数返回的时候,会把成员变量revents设置为0,表示没有事件发生;

      另外,poll() 函数不会受到socket描述符上的O_NDELAY标记和O_NONBLOCK标记的影响和制约,也就是说,不管socket是阻塞的还是非阻塞 的,poll()函数都不会收到影响;而select()函数则不同,select()函数会受到O_NDELAY标记和O_NONBLOCK标记的影 响,如果socket是阻塞的socket,则调用select()跟不调用select()时的效果是一样的,socket仍然是阻塞式TCP通讯,相 反,如果socket是非阻塞的socket,那么调用select()时就可以实现非阻塞式TCP通讯;

      所以poll() 函数的功能和返回值的含义与 select() 函数的功能和返回值的含义是完全一样的,两者之间的差别就是内部实现方式不一样,select()函数基本上可以在所有支持文件描述符操作的系统平台上运 行(如:Linux 、Unix 、Windows、MacOS等),可移植性好,而poll()函数则只有个别的的操作系统提供支持(如:SunOS、Solaris、AIX、HP提供 支持,但是Linux不提供支持),可移植性差;

      strust pollfd结构说明:

      typedef struct pollfd {
      int fd; /* 需要被检测或选择的文件描述符*/
      short events; /* 对文件描述符fd上感兴趣的事件 /
      short revents; /
      文件描述符fd上当前实际发生的事件*/
      } pollfd_t;

      typedef unsigned long nfds_t;

      经常检测的事件标记: POLLIN/POLLRDNORM(可读)、POLLOUT/POLLWRNORM(可写)、POLLERR(出错)

      如果是对一个描述符上的多个事件感兴趣的话,可以把这些常量标记之间进行按位或运算就可以了;

      比如:对socket描述符fd上的读、写、异常事件感兴趣,就可以这样做:struct pollfd fds;

      fds[nIndex].events=POLLIN | POLLOUT | POLLERR;

      当 poll()函数返回时,要判断所检测的socket描述符上发生的事件,可以这样做: struct pollfd fds;

      检测可读TCP连接请求:

      if((fds[nIndex].revents & POLLIN) == POLLIN){//接收数据/调用accept()接收连接请求}

      检测可写:

      if((fds[nIndex].revents & POLLOUT) == POLLOUT){//发送数据}

      检测异常:

      if((fds[nIndex].revents & POLLERR) == POLLERR){//异常处理}

      每一个pollfd结构体指定了一个被监视的文件描述符,可以传递多个结构体,指示poll()监视多个文件描述符。每个结构体的events域是监视该文件描述符的事件掩码,由用户来设置这个域。

      revents域是文件描述符的操作结果事件掩码。内核在调用返回时设置这个域。events域中请求的任何事件都可能在revents域中返回。合法的事件

      如下:
      POLLIN
      有数据可读。

      POLLRDNORM
      有普通数据可读。

      POLLRDBAND
      有优先数据可读。

      POLLPRI
      有紧迫数据可读。

      POLLOUT
      写数据不会导致阻塞。

      POLLWRNORM
      写普通数据不会导致阻塞。

      POLLWRBAND
      写优先数据不会导致阻塞。

      POLLMSG
      SIGPOLL 消息可用。
      此外,revents域中还可能返回下列事件:

      POLLER
      指定的文件描述符发生错误。

      POLLHUP
      指定的文件描述符挂起事件。

      POLLNVAL
      指定的文件描述符非法。

      这些事件在events域中无意义,因为它们在合适的时候总是会从revents中返回。使用poll()和select()不一样,你不需要显式地请求异常情况报告。

      POLLIN | POLLPRI等价于select()的读事件,POLLOUT |POLLWRBAND等价于select()的写事件。POLLIN等价于POLLRDNORM |POLLRDBAND,而POLLOUT则等价于POLLWRNORM。

      例如,要同时监视一个文件描述符是否可读和可写,我们可以设置 events为POLLIN |POLLOUT。在poll返回时,我们可以检查revents中的标志,对应于文件描述符请求的events结构体。

      如果POLLIN事件被设置,则文件描述符可以被读取而不阻塞。

      如果POLLOUT被设置,则文件描述符可以写入而不导致阻塞。

      这些标志并不是互斥的:它们可能被同时设置,表示这个文件描述符的读取和写入操作都会正常返回而不阻塞。

      timeout参数指定等待的毫秒数,无论I/O是否准备好,poll都会返回。

      timeout指定为负数值表示无限超时;timeout为0指示poll调用立即返回并列出准备好I/O的文件描述符,但并不等待其它的事件。这种情况下,poll()就像它的名字那样,一旦选举出来,立即返回。

      返回值和错误代码
      成功时,poll()返回结构体中revents域不为0的文件描述符个数;如果在超时前没有任何事件发生,poll()返回0;失败时,poll()返回-1,并设置errno为下列值之一:

      EBADF
      一个或多个结构体中指定的文件描述符无效。

      EFAULT
      fds指针指向的地址超出进程的地址空间。

      EINTR
      请求的事件之前产生一个信号,调用可以重新发起。

      EINVAL
      nfds参数超出PLIMIT_NOFILE值。

      ENOMEM
      可用内存不足,无法完成请求。


      linux的poll机制
      Poll就是监控文件是否可读的一种机制,作用与select一样。
      应用程序的调用函数如下:

      int poll(struct pollfd *fds,nfds_t nfds, int timeout);

      Poll机制会判断fds中的文件是否可读,如果可读则会立即返回,返回的值就是可读fd的数量,如果不可读,那么就进程就会休眠timeout这么长的时间,然后再来判断是否有文件可读,如果有,返回fd的数量,如果没有,则返回0.

      内核实现流程:

      当应用程序调用poll函数的时候,会调用到系统调用sys_poll函数,该函数最终调用do_poll函数,do_poll函数中有一个死循 环,

      在里面又会利用do_pollfd函数去调用驱动中的poll函数(fds中每个成员的字符驱动程序都会被扫描到),驱动程序中的Poll函数的工作 有两个,

      一个就是调用poll_wait 函数,把进程挂到等待队列中去(这个是必须的,你要睡眠,必须要在一个等待队列上面,否则到哪里去唤醒你呢??),

      另一个是确定相关的fd是否有内容可 读,如果可读,就返回1,否则返回0,如果返回1 ,do_poll函数中的count++,

      然后 do_poll函数然后判断三个条件(if (count ||!timeout || signal_pending(current)))如果成立就直接跳出,如果不成立,

      就睡眠timeout个jiffes这么长的时间(调用schedule_timeout实现睡眠),如果在这段时间内没有其他进程去唤醒它,

      那么第二次执行判断的时候就会跳出死循环。如果在这段时间内有其他进程唤醒它,那么也可以跳出死循环返回

      (例如我们可以利用中断处理函数去唤醒它,这样的话一有数据可读,就可以让它立即返回)。

      1.  sys_poll函数位于fs/select.c文件中,代码如下:
        

      asmlinkagelong sys_poll(struct pollfd __user *ufds, unsigned int nfds, long timeout_msecs)

      {

      s64 timeout_jiffies;

           if (timeout_msecs > 0) {
      

      #ifHZ > 1000

               /* We can only overflow if HZ >1000 */
      
               if (timeout_msecs / 1000 >(s64)0x7fffffffffffffffULL / (s64)HZ)
      
                   timeout_jiffies = -1;
      
               else
      

      #endif

                   timeout_jiffies =msecs_to_jiffies(timeout_msecs);
      
           } 
      

      else

      {
      /* Infinite (< 0) or no (0)timeout */

               timeout_jiffies = timeout_msecs;
      
           } 
      
           return do_sys_poll(ufds,nfds, &timeout_jiffies);
      

      }

      它对超时参数稍作处理后,直接调用do_sys_poll。

      1.  do_sys_poll函数也位于位于fs/select.c文件中,我们忽略其他代码:
        

      intdo_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)

      {
      ……

      poll_initwait(&table);

      ……

           fdcount = do_poll(nfds, head,&table, timeout);
      

      ……

      }

      poll_initwait函数非常简单,它初始化一个poll_wqueues变量table:

      poll_initwait> init_poll_funcptr(&pwq->pt, __pollwait); > pt->qproc = qproc;

      即table->pt->qproc= __pollwait,__pollwait将在驱动的poll函数里用到。

      1.  do_sys_poll函数位于fs/select.c文件中,代码如下:
        

      static int do_poll(unsigned int nfds, struct poll_list *list, struct poll_wqueues *wait, s64 *timeout)

      {
      01 ……

      02 for (;;){
      03 ……

      04 if(do_pollfd(pfd, pt)) {
      05 count++;

      06 pt = NULL;

      07 }

      08 ……

      09 if(count || !*timeout || signal_pending(current))

      10 break;

      11 count= wait->error;

      12 if(count)

      13 break;14

      15 if(*timeout < 0) {
      16 /*Wait indefinitely */

      17 __timeout= MAX_SCHEDULE_TIMEOUT;

      18 }else if (unlikely(timeout >= (s64)MAX_SCHEDULE_TIMEOUT-1)) {
      19 /

      20 * Wait for longer than MAX_SCHEDULE_TIMEOUT. Do it in

      21 * a loop

      22 */

      23 __timeout= MAX_SCHEDULE_TIMEOUT - 1;

      24 *timeout-= __timeout;

      25 }else {
      26 __timeout= *timeout;

      27 *timeout= 0;

      28 }29

      30 __timeout= schedule_timeout(__timeout); // 休眠时间由应用提供

      31 if(*timeout >= 0)

      32 *timeout+= __timeout;

      33 }

      34 __set_current_state(TASK_RUNNING);

      35 returncount;

      36 }

      分析其中的代码,可以发现,它的作用如下:

      ① 从02行可以知道,这是个循环,它退出的条件为:

      a. 09行的3个条件之一(count非0,超时、有信号等待处理)

      count顺0表示04行的do_pollfd至少有一个成功。

      b. 11、12行:发生错误

      ② 重点在do_pollfd函数,后面再分析

      ③ 第30行,让本进程休眠一段时间,注意:应用程序执行poll调用后,如果①②的条件不满足,进程就会进入休眠。那么,谁唤醒呢?除了休眠到指定时间被系统唤醒外,还可以被驱动程序唤醒──记住这点,这就是为什么驱动的poll里要调用poll_wait的原因,后面分析。

      1.  do_pollfd函数位于fs/select.c文件中,代码如下:
        

      static inline unsigned int do_pollfd(struct pollfd*pollfd, poll_table *pwait)

      {
      ……

               if(file->f_op && file->f_op->poll)
      
                       mask= file->f_op->poll(file, pwait);
      

      ……

      }

      可见,它就是调用我们的驱动程序里注册的poll函数。

      二、驱动程序:

      驱动程序里与poll相关的地方有两处:一是构造file_operation结构时,要定义自己的poll函数。二是通过poll_wait来调用上面说到的__pollwait函数,pollwait的代码如下:

      staticinline void poll_wait(struct file * filp, wait_queue_head_t * wait_address,poll_table *p)

      {
      if (p && wait_address)

               p->qproc(filp, wait_address, p);
      

      }

      p->qproc就是__pollwait函数,从它的代码可知,它只是把当前进程挂入我们驱动程序里定义的一个队列里而已。它的代码如下:

      staticvoid __pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)

      {
      struct poll_table_entry *entry =poll_get_entry(p);

           if (!entry)
      
               return;
      
           get_file(filp);
      
           entry->filp = filp;
      
           entry->wait_address = wait_address;
      
           init_waitqueue_entry(&entry->wait,current);
      
           add_wait_queue(wait_address,&entry->wait);
      

      }

      执行到驱动程序的poll_wait函数时,进程并没有休眠,我们的驱动程序里实现的poll函数是不会引起休眠的。让进程进入休眠,是前面分析的do_sys_poll函数的30行“__timeout = schedule_timeout(__timeout)”。

      poll_wait只是把本进程挂入某个队列,应用程序调用poll > sys_poll> do_sys_poll > poll_initwait,do_poll > do_pollfd > 我们自己写的poll函数后,再调用schedule_timeout进入休眠。

      如果我们的驱动程序发现情况就绪,可以把这个队列上挂着的进程唤醒。可见,poll_wait的作用,只是为了让驱动程序能找到要唤醒的进程。即使不用poll_wait,我们的程序也有机会被唤醒:

      chedule_timeout(__timeout),只是休眠__time_out这段时间。

      现在来总结一下poll机制:

      1. poll > sys_poll > do_sys_poll >poll_initwait,poll_initwait函数注册一下回调函数__pollwait,它就是我们的驱动程序执行poll_wait时,真正被调用的函数。

      2. 接下来执行file->f_op->poll,即我们驱动程序里自己实现的poll函数

        它会调用poll_wait把自己挂入某个队列,这个队列也是我们的驱动自己定义的;

        它还判断一下设备是否就绪。

      3. 如果设备未就绪,do_sys_poll里会让进程休眠一定时间,这个时间是应用提供的“超时时间”

      4. 进程被唤醒的条件有2:一是上面说的“一定时间”到了,二是被驱动程序唤醒。驱动程序发现条件就绪时,就把“某个队列”上挂着的进程唤醒,这个队列,就是前面通过poll_wait把本进程挂过去的队列。

      5. 如果驱动程序没有去唤醒进程,那么chedule_timeout(__timeou)超时后,会重复2、3动作1次,直到应用程序给定的时间, 然后返回。

      驱动的poll函数编写模板如下:

      static DECLARE_WAIT_QUEUE_HEAD(my_waitq); //休眠要挂的等待队列
      static unsigned drv_poll(struct file *file, poll_table *wait)
      {
      unsigned int mask = 0;
      poll_wait(file, &my_waitq, wait); // 不会立即休眠
      if (有数据)
      mask |= POLLIN | POLLRDNORM;
      return mask;
      }

      发布在 Linux
      miumiu
      WOW
    • 精通 Git

      转载自:http://whycan.com/t_4495.html

      目录
      许可证 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
      Scott Chacon 序 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
      Ben Straub 序 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
      献辞 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
      贡献者 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
      引言 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
      起步 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
      关于版本控制 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
      Git 简史 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
      Git 是什么? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
      命令行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
      安装 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
      初次运行 Git 前的配置. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
      获取帮助 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
      Git 基础 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
      获取 Git 仓库. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
      记录每次更新到仓库 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
      查看提交历史 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
      撤消操作 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
      远程仓库的使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
      打标签 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
      Git 别名 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
      Git 分支 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
      分支简介 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
      分支的新建与合并 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
      分支管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
      分支开发工作流 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
      远程分支 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
      变基 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
      服务器上的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
      协议 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
      在服务器上搭建 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
      生成 SSH 公钥 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
      配置服务器 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
      Git 守护进程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
      Smart HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
      GitWeb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
      GitLab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
      第三方托管的选择 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
      分布式 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
      分布式工作流程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
      向一个项目贡献 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
      维护项目 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
      GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
      账户的创建和配置 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
      对项目做出贡献 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
      维护项目 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
      管理组织 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
      脚本 GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
      Git 工具 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
      选择修订版本 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
      交互式暂存 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
      贮藏与清理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
      签署工作 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
      搜索 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
      重写历史 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
      重置揭密 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
      高级合并 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
      Rerere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
      使用 Git 调试 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
      子模块 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
      打包 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
      替换 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
      凭证存储 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
      自定义 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
      配置 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
      Git 属性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
      Git 钩子 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
      使用强制策略的一个例子 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
      Git 与其他系统 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
      作为客户端的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
      迁移到 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429
      Git 内部原理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
      底层命令与上层命令 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
      Git 对象 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
      Git 引用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
      包文件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445
      引用规范 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448
      传输协议 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
      维护与数据恢复 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
      环境变量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468
      附录 A: 在其它环境中使用 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
      图形界面 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
      Visual Studio 中的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
      Git in Visual Studio Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
      Eclipse 中的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
      Git in IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
      Git in Sublime Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478
      Bash 中的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478
      Zsh 中的 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479
      Git 在 PowerShell 中使用 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
      总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483
      附录 B: 在你的应用中嵌入 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
      命令行 Git 方式. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
      Libgit2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
      JGit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489
      go-git. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493
      Dulwich. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494
      附录 😄 Git 命令 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
      设置与配置 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
      获取与创建项目 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497
      快照基础 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498
      分支与合并 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
      项目分享与更新 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502
      检查与比较 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504
      调试 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
      补丁 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
      邮件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506
      外部系统 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
      管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
      底层命令 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508
      索引 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509

      资料下载:progit_v2_1_36.pdf

      发布在 Linux
      miumiu
      WOW
    • Linux命令行获取本机外网地址

      转载自:http://whycan.com/t_5187.html (出处:哇酷开发者社区)

      sudo apt-get install curl -y
      以下任意一个命令行均可以:

      curl checkip.amazonaws.com
      curl ifconfig.me
      curl icanhazip.com
      curl ipecho.net/plain
      curl ifconfig.co

      参考: https://www.cyberciti.biz/faq/how-to-find-my-public-ip-address-from-command-line-on-a-linux/

      发布在 Linux
      miumiu
      WOW
    • Linux 工具快速教程

      转载自:http://whycan.com/t_4494.html (出处:哇酷开发者社区)

      致谢
      README
      Linux基础

      1. 学会使用命令帮助
      2. 文件及目录管理
      3. 文本处理
      4. 磁盘管理
      5. 进程管理工具
      6. 性能监控
      7. 网络工具
      8. 用户管理工具
      9. 系统管理及IPC资源管理
        Linux工具进阶
      10. 程序构建
      11. 程序调试
      12. 性能优化
        工具参考篇
      13. gdb 调试利器
      14. ldd 查看程序依赖库
      15. lsof 一切皆文件
      16. ps 进程查看器
      17. pstack 跟踪进程栈
      18. strace 跟踪进程中的系统调用
      19. ipcs 查询进程间通信状态
      20. top linux下的任务管理器
      21. free 查询可用内存
      22. vmstat 监视内存使用情况
      23. iostat 监视I/O子系统
      24. sar 找出系统瓶颈的利器
      25. readelf elf文件格式分析
      26. objdump 二进制文件分析
      27. nm 目标文件格式分析
      28. size 查看程序内存映像大小
      29. wget 文件下载
      30. scp 跨机远程拷贝
      31. crontab 定时任务

      Linux工具快速教程.pdf

      发布在 Linux
      miumiu
      WOW
    • 嵌入式 Linux 知识库

      转载自:http://whycan.com/t_4493.html(哇酷开发者社区)

      致谢
      当前文档 《嵌入式 Linux 知识库 (eLinux.org)》 由 进击的皇虫 使用 书栈
      (BookStack.CN) 进行构建,生成于 2018-02-21。
      书栈(BookStack.CN) 仅提供文档编写、整理、归类等功能,以及对文档内容的生成和导出工
      具。
      文档内容由网友们编写和整理,书栈(BookStack.CN) 难以确认文档内容知识点是否错漏。如
      果您在阅读文档获取知识的时候,发现文档内容有不恰当的地方,请向我们反馈,让我们共同携手,
      将知识准确、高效且有效地传递给每一个人。
      同时,如果您在日常生活、工作和学习中遇到有价值有营养的知识文档,欢迎分享到 书栈
      (BookStack.CN) ,为知识的传承献上您的一份力量!
      如果当前文档生成时间太久,请到 书栈(BookStack.CN) 获取最新的文档,以跟上知识更新换
      代的步伐。
      文档地址:http://www.bookstack.cn/books/tinyclub-elinux
      书栈官网:http://www.bookstack.cn
      书栈开源:https://github.com/TruthHun
      分享,让知识传承更久远! 感谢知识的创造者,感谢知识的分享者,也感谢每一位阅读到此处的
      读者,因为我们都将成为知识的传承者。

      嵌入式 Linux 知识库 (eLinux.org)
      Embedded Linux Wiki 采用 MediaWiki 系统,由 CE Linux Forum 创建。
      基于上述 Mediawiki 版本,这里的 GitBook 版本由 eLinux.org 中文翻译组 创建,目的是为
      了更好地通过网络协作把它翻译成其他语言,而副产品是该知识库可以作为可打印和可阅读的免费书
      籍下载而且支持 pdf,epub 或者 mobi 格式。
      项目首页: http://www.tinylab.org/elinux
      Git 仓库: https://github.com/tinyclub/elinux
      在线阅读: http://tinylab.gitbooks.io/elinux
      实验云台:在线学 Linux,Linux 0.11,汇编,Shell,C ...

      介绍
      欢迎访问 eLinux 知识库!
      本知识库的目标是保存和呈现各类信息,既涉及使用 Linux 进行嵌入式系统开发,也涵盖与通用嵌
      入式开发相关的开源项目和工具。
      点击左侧的导航菜单,即可开启本知识库之旅!
      该站主要带来各类资源列表和信息收集,可用于解决特定领域的问题。例如,如果碰到嵌入式 Linux
      系统启动时间有关问题,则可以阅读启动时间。

      固件
      固件

      安全
      安全
      目录
      简介
      技术/项目主页
      Linux Kernel 中的安全子系统
      SELinux
      Tomoyo
      SMACK
      陈旧的信息 ( 2005 年,CELF 调查的相关信息)
      文档
      关键需求与相关技术点
      资源
      安全框架
      安全组件
      安全特性
      其他资源
      安全活动
      邮件列表
      会议
      安全相关的文章
      论文
      实例和开源代码
      原文:eLinux.org
      翻译:@lzz5235
      校订:@lzufalcon
      安全
      目录
      2 简介
      3 技术/项目主页
      4 Linux Kernel 中的安全子系统
      4.1 SELinux
      4.2 Tomoyo
      4.3 SMACK
      安全
      5 陈旧的信息 ( 2005 年,CELF 调查的相关信息)
      5.1 文档
      5.2 关键需求与相关技术点
      5.3 资源
      5.3.1 安全框架
      5.3.2 安全组件
      5.3.3 安全特性
      5.3.4 其他资源
      5.3.4.1 安全活动
      5.3.4.2 邮件列表
      5.3.4.3 会议
      5.3.4.4 安全相关的文章
      5.3.4.5 论文
      5.3.4.6 实例和开源代码

      实时
      实时
      简介
      实时领域 Wiki
      软件项目
      硬件实现
      文档
      更多开源项目

      启动时间
      启动时间
      目录
      简介
      技术/项目主页
      测量启动时间
      减少启动时间的技术和技巧
      引导程序(Bootloader)加速
      内核加速
      文件系统方面的问题
      用户空间和应用程序加速
      系统休眠相关的改进
      杂项
      一些未经验证的想法
      文章和演讲稿
      案例研究
      其他的项目/邮件列表/资源
      SysV ‘init’ 的替代品
      busybox init
      upstart
      Android init
      systemd
      Kexec
      启动画面(Splash Screen)项目
      其他
      正在从事快速启动的公司、个人或者项目
      启动时间检查清单

      网络
      网络
      目录
      简介
      嵌入式 Linux 网络

      多媒体
      多媒体
      目录
      简介
      CELF 2.0 AVG 规范
      音、视频工作组
      DirectFB 研究
      什么是 DirectFB,DirectFB 如何工作
      嵌入式 Linux 平台上 DirectFB 示例实现
      嵌入式 Linux 平台上一些 DirectFB 基准测试结果
      相关项目
      图形/视频输出
      Framebuffer/帧缓冲
      DirectFB
      V4L2
      X11
      NanoX
      OpenGL (OpenML)
      SDL
      Cairo
      Clutter
      Enlightenment Foundation Libraries ( EFL )
      Qt
      演示图板套件 (演示图板设计师/引擎,来自 Crank Software)
      GStreamer
      Xine
      MPlayer
      文档
      Video in
      V4L[2]
      OpenML
      LinuxTV (DVB API)
      音频输入/输出
      OSS
      ALSA
      OpenAL
      PulseAudio
      AVG 标准的使用者
      Video Lan
      Freevo
      多媒体
      LinuxTV
      MythTV
      DVR
      OpenPVR
      Morphine.TV
      其他
      ARIB 架构(一个数字广播系统标准)
      启动画面
      数字家庭工作组
      Disko 框架
      Free Type(软件字体引擎)
      UPnP
      TV Anytime 论坛
      TV Linux 联盟

      系统裁剪
      系统裁剪
      介绍
      减少系统尺寸的技术
      内核尺寸缩减
      配置选项
      Linux-tiny 补丁集
      “dietnet”
      减少内核尺寸相关的编译选项
      垃圾回收补丁集
      运行时内核大小
      内核栈大小
      自动裁剪
      PRINTK 消息压缩
      裁剪的一些想法和近期的工作
      文件系统压缩
      应用裁剪
      程序大小相关编译选项
      缩减你的程序
      手动优化程序大小
      库尺寸裁剪技术
      使用更小的 libc
      静态链接
      库裁剪
      延时加载库
      就地执行(XIP)
      内核 XIP
      应用 XIP
      原地数据读取 (DRIP)
      尺寸测量的技术和相关工具
      内核尺寸测量数据
      怎样计算内核镜像的大小
      怎样动态计算内存使用情况
      Linux 内核 从 2.4 到 2.6 的尺寸增加
      GCC 代码大小基准测试
      案例研究
      uClinux
      微型处理器上的 Linux (这里是在 M3 上)
      发行版本的尺寸缩减相关尝试
      杂项
      系统裁剪
      内核内存溢出检测
      系统的大小是怎样影响性能的
      缩减桌面发行版本的文件系统
      极小系统

      文件系统
      文件系统
      目录
      简介
      MTD
      UBI
      分区
      eMMC and UFS
      嵌入式文件系统
      AXFS
      Btrfs
      CramFS
      F2FS
      InitRAMFS
      JFFS2
      LogFS
      NFS
      PRAMFS
      Romfs
      SquashFS
      UBIFS
      YAFFS2
      挂载文件系统
      在 PC 上用 mtdram 挂载 JFFS2 镜像
      在 PC 上用 nandsim 挂载 UBI 镜像
      在嵌入式中使用通用文件系统的问题
      MMC/sdcard 卡特性
      专用文件系统
      ABISS
      分层的文件系统
      UnionFS
      aufs
      mini_fo
      性能和基准测试
      性能评测工具
      闪存文件系统比较
      Cogent Embedded 公司的测试 (2013)
      Free Electrons 公司的测试 (2011)
      其他项目
      多媒体文件系统
      文件系统
      维基百科文件系统
      维基文件系统

      电源管理
      目录
      简介
      电源管理技术与项目网页
      Linux 电源管理迷你峰会
      峰会记录
      CE Linux 论坛的需求标准
      资料文档
      开源项目/邮件列表

      内存管理
      目录
      感兴趣的领域
      内存检测和分析
      巨页/大页/超级页
      页缓存压缩
      启动时预留和访问高地址内存
      OOM 处理机制的优化/改进
      Cgroups (控制组)中的 OOM 通知
      mem_notify 补丁
      谷歌 cgroup (控制组) OOM 处理方法
      诺基亚对 OOM 的改进
      基于 LSM 的低内存通知
      基于类型的内存分配(老旧的方法)
      附加资源/邮件列表
      关于缓存的文章

      资源管理
      目录
      开源项目
      CKRM/RG
      UBC/Beancounters
      其他

      设备驱动
      使用手册
      样例驱动
      资源

      设备树
      目录
      前言
      扁平设备树是
      扁平设备树不是
      历史
      未来
      优势
      对于内核发行
      对于片上系统(SoC)供应商
      对于主板设计者
      对于嵌入式 Linux 生态系统
      对于固件或 bootloader 开发者
      其他的优势
      竞品的解决方案
      板子相关特性的数据结构
      ACPI(高级配置与电源接口)
      UEFI(统一的可扩展固件接口)
      Open FirmWare
      关于竞品的解决方案的一些注解
      资源
      Wiki 和内核中的参考资料
      FAQ,小贴士和最佳范例
      演示文稿,论文和文章
      各种子系统的设备树描述的笔记
      较老的材料
      工具
      调试
      设备树 irc (互联网中继聊天)
      设备树邮件列表

      玩转硬件
      目录
      工程设备
      官方支持的设备
      汽车
      工业
      迷你集群
      硬件工具和信息
      软件工具和信息

      开发平台
      目录
      最受欢迎的设备
      ARM
      AVR32
      Blackfin
      MIPS
      PowerPC
      SuperH
      i386 及其兼容平台
      未分类

      贡献内核补丁(Kernel Mainlining)
      目录
      通用资源
      相关演讲
      演讲列表
      训练,指导和挑战
      具体项目
      最佳行动说明
      来自 Andrew Morton
      来自 Deepak Saxena
      来自 Jonathan Corbet
      来自 Arnd Bergmann
      来自 David Arlie
      克服 Mainlining 遇到的障碍

      法律问题
      嵌入式中使用 Linux 的法律问题
      内核只被 GPL V2 许可
      署名行 (signed-off-by) 和原创开发者证书 (DCO)
      有关法律分析和合规的资源
      EXPORT_SYMBOL_GPL
      针对内核 USB API 的 EXPORT_SYMBOL_GPL
      二进制专有的内核模块
      在用户空间中使用内核头文件
      其它链接

      事件/会议
      目录
      即将举办会议
      2015 年
      2015 年 10 月
      已举办的事件
      2015 年
      2015 年 6 月
      2015 年 3 月
      2014 年
      2014 年 10 月
      2014 年 9 月
      2014 年 5 月
      2014 年 4 月
      2013 年
      2013 年 10 月
      2013年5月
      2013 年 2 月
      2012 年
      2012 年 11 月
      2012 年 9 月
      2012 年 8 月
      2012 年 7 月
      2012 年 6 月
      2012 年 4 月
      2012 年 2 月
      2011 年
      2010 年
      2009 年
      2008 年
      2007 年
      2006 年
      2005 年
      2004 年
      来自其他事件的论文集
      内核峰会上的演讲稿
      事件计划
      嵌入式 Linux 会议演讲稿

      术语表
      高频主题术语表
      A
      B
      C
      D
      E
      F
      G
      H
      I
      J
      K
      L
      M
      N
      O
      P
      Q
      R
      S
      T
      U
      V
      W
      X
      Y
      Z

      处理器
      Processors
      Contents
      ARC
      ARM
      MIPS
      SuperH
      Renesas SuperH Overview
      Devices
      PowerPC
      Processors
      Tools
      RT Patches
      Documents
      XScale
      x86
      AVR32
      Blackfin
      m68k
      Further reading

      社区
      Community
      Contents
      Netiquette
      Community sites
      General Portals
      Hardware-Specific Communities
      Software-Specific Communities
      Communities for beginners
      People
      Linux kernel
      Important kernel figures
      Kernel arch maintainers
      Feature developers/maintainers
      Other People
      Interview candidates
      Foundations and Forums
      Linux User Groups
      Development Model
      Reasons for contributing to open source
      Community-building ideas
      Quality Assurance
      Certificate of Origin

      发布在 Linux
      miumiu
      WOW