2012-03-16 09:45:20 mzwang123 阅读数 1157
  • YOLOv3目标检测:原理与源码解析

    Linux创始人Linus Torvalds有一句名言:Talk is cheap, Show me the code.(冗谈不够,放码过来!)。 代码阅读是从入门到提高的必由之路。尤其对深度学习,许多框架隐藏了神经网络底层的实现,只能在上层调包使用,对其内部原理很难认识清晰,不利于进一步优化和创新。   YOLOv3是一种基于深度学习的端到端实时目标检测方法,以速度快见长。 YOLOv3的实现Darknet是使用C 语言开发的轻型开源深度学习框架,依赖少,可移植性好,可以作为很好的代码阅读案例,让我们深入探究其实现原理。   本课程将解析YOLOv3 的实现原理和源码,具体内容包括: *      YOLO目标检测原理  *      神经网络及Darknet的C语言实现,尤其是反向传播的梯度求解和误差计算  *      代码阅读工具及方法  *      深度学习计算的利器:BLAS和GEMM  *      GPU的CUDA编程方法及在Darknet的应用  *      YOLOv3的程序流程及各层的源码解析   本课程将提供注释后的Darknet的源码程序文件。   除本课程《YOLOv3 目标检测:原理与源码解析》外,本人推出了有关YOLOv3目标检测的系列课程,包括: *   《YOLOv3目标检测实战:训练自己的数据集》 *   《YOLOv3目标检测实战:交通标志识别》 *   《YOLOv3目标检测:原理与源码解析》 *   《YOLOv3目标检测:网络模型改进方法》   建议先学习课程《YOLOv3目标检测实战:训练自己的数据集》或课程《YOLOv3 目标检测实战:交通标志识别》,对YOLOv3的使用方法了解以后再学习本课程。

    957 人正在学习 去看看 白勇

When I read the book linux 内核源代码剖析, I confused by the defination of conforming code segment & nonconforming code segment. I referrenced many website,but I couldn't get a clear answer. The following only stand for my opinion.

When I am researching the demo  in chapter 4.9. There is a timmer interrupt handling function.  Notice the instructinos "ljmp  $TSS1_SEL,$0 and  ljmp $TSS2_SEL,$0".
It presents that cpu will execute a intersegment jump. The following action will be perform by cpu .

IF instruction = relative JMP
   (* i.e. operand is rel8, rel16, or rel32 *)
THEN
   EIP := EIP + rel8/16/32;
   IF OperandSize = 16
   THEN EIP := EIP AND 0000FFFFH;
   FI;
FI;
IF instruction = near indirect JMP
   (* i.e. operand is r/m16 or r/m32 *)
THEN
   IF OperandSize = 16
   THEN
      EIP := [r/m16] AND 0000FFFFH;
   ELSE (* OperandSize = 32 *)
      EIP := [r/m32];
   FI;
FI;

IF (PE = 0 OR (PE = 1 AND VM = 1)) (* real mode or V86 mode *)
   AND instruction = far JMP
   (* i.e., operand type is m16:16, m16:32, ptr16:16, ptr16:32 *)
THEN GOTO REAL-OR-V86-MODE;
   IF operand type = m16:16 or m16:32
   THEN (* indirect *)
      IF OperandSize = 16
      THEN
         CS:IP := [m16:16];
         EIP := EIP AND 0000FFFFH; (* clear upper 16 bits *)
      ELSE (* OperandSize = 32 *)
         CS:EIP := [m16:32];
      FI;
   FI;
   IF operand type = ptr16:16 or ptr16:32
   THEN
      IF OperandSize = 16
      THEN
         CS:IP := ptr16:16;
         EIP := EIP AND 0000FFFFH; (* clear upper 16 bits *)
      ELSE (* OperandSize = 32 *)
         CS:EIP := ptr16:32;
      FI;
   FI;
FI;

IF (PE = 1 AND VM = 0) (* Protected mode, not V86 mode *)
   AND instruction = far JMP
THEN
   IF operand type = m16:16 or m16:32
   THEN (* indirect *)
      check access of EA dword;
      #GP(0) or #SS(0) IF limit violation;
   FI;
   Destination selector is not null ELSE #GP(0)
   Destination selector index is within its descriptor table limits ELSE
#GP(selector)
   Depending on AR byte of destination descriptor:
      GOTO CONFORMING-CODE-SEGMENT;
      GOTO NONCONFORMING-CODE-SEGMENT;
      GOTO CALL-GATE;
      GOTO TASK-GATE;
      GOTO TASK-STATE-SEGMENT;
   ELSE #GP(selector); (* illegal AR byte in descriptor *)
FI;

CONFORMING-CODE-SEGMENT:
   Descriptor DPL must be <= CPL ELSE #GP(selector);
   Segment must be present ELSE #NP(selector);
   Instruction pointer must be within code-segment limit ELSE #GP(0);
   IF OperandSize = 32
   THEN Load CS:EIP from destination pointer;
   ELSE Load CS:IP from destination pointer;
   FI;
   Load CS register with new segment descriptor;

NONCONFORMING-CODE-SEGMENT:
   RPL of destination selector must be <= CPL ELSE #GP(selector);
   Descriptor DPL must be = CPL ELSE #GP(selector);
   Segment must be present ELSE # NP(selector);
   Instruction pointer must be within code-segment limit ELSE #GP(0);
   IF OperandSize = 32
   THEN Load CS:EIP from destination pointer;
   ELSE Load CS:IP from destination pointer;
   FI;
   Load CS register with new segment descriptor;
   Set RPL field of CS register to CPL;

CALL-GATE:
   Descriptor DPL must be >= CPL ELSE #GP(gate selector);
   Descriptor DPL must be >= gate selector RPL ELSE #GP(gate selector);
   Gate must be present ELSE #NP(gate selector);
   Examine selector to code segment given in call gate descriptor:
      Selector must not be null ELSE #GP(0);
      Selector must be within its descriptor table limits ELSE
         #GP(CS selector);
      Descriptor AR byte must indicate code segment
         ELSE #GP(CS selector);
      IF non-conforming
      THEN code-segment descriptor, DPL must = CPL
      ELSE #GP(CS selector);
      FI;
      IF conforming
      THEN code-segment descriptor DPL must be <= CPL;
      ELSE #GP(CS selector);
      Code segment must be present ELSE #NP(CS selector);
      Instruction pointer must be within code-segment limit ELSE #GP(0);
      IF OperandSize = 32
      THEN Load CS:EIP from call gate;
      ELSE Load CS:IP from call gate;
      FI;
   Load CS register with new code-segment descriptor;
   Set RPL of CS to CPL

TASK-GATE:
   Gate descriptor DPL must be >= CPL ELSE #GP(gate selector);
   Gate descriptor DPL must be >= gate selector RPL ELSE #GP(gate
     selector);
   Task Gate must be present ELSE #NP(gate selector);
   Examine selector to TSS, given in Task Gate descriptor:
   Must specify global in the local/global bit ELSE #GP(TSS selector);
   Index must be within GDT limits ELSE #GP(TSS selector);
   Descriptor AR byte must specify available TSS (bottom bits 00001);
      ELSE #GP(TSS selector);
   Task State Segment must be present ELSE #NP(TSS selector);
SWITCH-TASKS (without nesting) to TSS;
Instruction pointer must be within code-segment limit ELSE #GP(0);

TASK-STATE-SEGMENT:
   TSS DPL must be >= CPL ELSE #GP(TSS selector);
   TSS DPL must be >= TSS selector RPL ELSE #GP(TSS selector);
   Descriptor AR byte must specify available TSS (bottom bits 00001)
      ELSE #GP(TSS selector);
   Task State Segment must be present ELSE #NP(TSS selector);
   SWITCH-TASKS (without nesting) to TSS;
   Instruction pointer must be within code-segment limit ELSE #GP(0);


Now you can image that when task0 is executing, then it's cpu slice time is finished.It must be generate an  timer interrupt. The register of  EIP,CS,Flags will be sotre in the kernel stack.Remeber that the CPL will not be change,because the interrupt gate descriptor in the  interrupt vector table indicate the timer_interrupt function is a conforming code segment. It's easy to find that the format of the trap gate ,interrupt gate .

Bits Description
0-15 first 16 bits of a pointer to a kernel function which need to be invoked when this gate is hit
16-31 indicates the index of segment descriptor in GDT (Global Descriptor Table)
32-36 these bits are reserved and are not currently used
37-39 always 000, not used
40-43 specify entry type (its value for interrupt gate is 1110)
44 always 0, not used
45-46 this specifies the DPL (Descriptor Previlege Level) level of gate entry
47 specifies if this entry is valid or not (1 - valid, 0 - invalid)
48-63 last 16 bits of a pointer to a kernel function which need to be invoked when this gate is hit


Bits Description
0-15 first 16 bits of a pointer to a kernel function which need to be invoked when this gate is hit
16-31 indicates the index of segment descriptor in GDT (Global Descriptor Table)
32-36 these bits are reserved and are not currently used
37-39 always 000, not used
40-43 specify entry type(its value for trap gate is 1111)
44 always 0, not used
45-46 this specifies the DPL (Descriptor Previlege Level) level of gate entry
47 specifies if this entry is valid or not (1 - valid, 0 - invalid)
48-63 last 16 bits of a pointer to a kernel function which need to be invoked when this gate is hit

The type fields value are 1110(trap gate)  and 1111(interrupt gate). The following is the segment descriptor format.

                           DATA SEGMENT DESCRIPTOR

  31                23                15                7               0
 +-----------------+-+-+-+-+---------+-+-----+---------+-----------------+
 |#################|#|#|#|A| LIMIT   |#|     |  TYPE   |#################|
 |###BASE 31..24###|G|B|0|V| 19..16  |P| DPL |         |###BASE 23..16###| 4
 |#################|#|#|#|L|         |#|     |1|0|E|W|A|#################|
 |-----------------+-+-+-+-+---------+-+-----+-+-+-+-+-+-----------------|
 |###################################|                                   |
 |########SEGMENT BASE 15..0#########|        SEGMENT LIMIT 15..0        | 0
 |###################################|                                   |
 +-----------------+-----------------+-----------------+-----------------+

                        EXECUTABLE SEGMENT DESCRIPTOR

  31                23                15                7               0
 +-----------------+-+-+-+-+---------+-+-----+---------+-----------------+
 |#################|#|#|#|A| LIMIT   |#|     |  TYPE   |#################|
 |###BASE 31..24###|G|D|0|V| 19..16  |P| DPL |         |###BASE 23..16###| 4
 |#################|#|#|#|L|         |#|     |1|0|C|R|A|#################|
 |-----------------+-+-+-+-+---------+-+-----+-+-+-+-+-+-----------------|
 |###################################|                                   |
 |########SEGMENT BASE 15..0#########|        SEGMENT LIMIT 15..0        | 0
 |###################################|                                   |
 +-----------------+-----------------+-----------------+-----------------+

                         SYSTEM SEGMENT DESCRIPTOR

  31                23                15                7               0
 +-----------------+-+-+-+-+---------+-+-----+-+-------+-----------------+
 |#################|#|#|#|A| LIMIT   |#|     | |       |#################|
 |###BASE 31..24###|G|X|0|V| 19..16  |P| DPL |0| TYPE  |###BASE 23..16###| 4
 |#################|#|#|#|L|         |#|     | |       |#################|
 |-----------------+-+-+-+-+---------+-+-----+-+-------+-----------------|
 |###################################|                                   |
 |########SEGMENT BASE 15..0#########|       SEGMENT LIMIT 15..0         | 0
 |###################################|                                   |
 +-----------------+-----------------+-----------------+-----------------+
        A   - ACCESSED                              E   - EXPAND-DOWN
        AVL - AVAILABLE FOR PROGRAMMERS USE         G   - GRANULARITY
        B   - BIG                                   P   - SEGMENT PRESENT
        C   - CONFORMING                            R   - READABLE
        D   - DEFAULT                               W   - WRITABLE
        DPL - DESCRIPTOR PRIVILEGE LEVEL

There are five bits in data segment descriptor and executable segment descriptor,and the first bit is 1 in both ,it means this is the user-define descriptor ,but four bits in system segment descriptor,and it's left bit is 0.

I infer the second bit of the type meaning is Conforming code segment.

Section 2

.quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
00对应的是基址:16-23位
c对应的是G位,D/B位,0(系统默认) AVL(系统软件可用位)
f对应的是段限长的第16-19位
9对应的是:P|DPL|S 第一位表示P,P=1表示段在内在中, 第二三位表示DPL,DPL=00表示运行在系统0级,第四位表示S,s=0表示该段为系统段。 
a对应的是type字段:1100表示一致性代码段
00对应的是基址24-31位
0000对应的是基址0-15位
ffff对应的是段限长

但是以下写法要注意:

.word  0x68,tss0,0xe900,0x,0    #TSS0的段描述符格式

linux kernel source code

阅读数 840

linux SPI code

阅读数 778

没有更多推荐了,返回首页