Parsing the System_call interrupt processing process through system calls

Source: Internet
Author: User

Luo Chong + Original works reproduced please specify the source + "Linux kernel analysis" MOOC course http://mooc.study.163.com/course/USTC-1000029000

1. Experiment Preparation 1.1 Environment preparation

Download the source code for the linux3.18.6. According to Http://mooc.study.163.com/learn/USTC-1000029000?tid=2001214000#/learn/content?type=detail&id= 2001400011 give the steps to compile

    # Download Kernel source code compile kernelCD ~/linuxkernel/wget https://www. Kernel. org/pub/linux/kernel/v3. x/linux-3.18. 6. Tar. XZXz-d linux-3.18. 6. Tar. XZTAR-XVF linux-3.18. 6. TarCD linux-3.18. 6Make I386_defconfig make# usually compile for a long time, less 20 minutes more hours    # make root file systemCD ~/linuxkernel/mkdir rootfs git clone https://github. com/mengning/menu. Git  # If you are wall, you can use accessories menu.zipCD Menu Gcc-o init linktable. CMenu. CTest. C-m32-static–lpthread CD. /rootfsCP.. /menu/init./Find. | Cpio-o-HNEWC |gzip-9>.. /rootfs. IMG    # Start the menuos systemCD ~/linuxkernel/qemu-kernel linux-3.18. 6/ARCH/X86/BOOT/BZIMAGE-INITRD Rootfs. IMG
1.2 Code Preparation

Download the Monensin Teacher's menu code and modify the TEST.C function. The following changes are followed:

    Char* Path ="/root/test_c";intMkdir (intargcChar*argv[]) {intttChar* Path ="/root/test_c";unsigned  ShortMoD =0750; tt = mkdir (path, mod);printf("mkdir ret =:%d\n", TT);return 0;}intMkdirasm (intargcChar*argv[]) {intttChar* Path ="/root/test_asm";unsigned  ShortMoD =0750;ASM volatile("mov $0x27,%%eax\n\t"      "int $0x80\n\t"      "mov%%eax,%0\n\t":"=m"(TT):"B"(path),"C"(mod));printf("mkdir ASM ret =:%x\n", TT);return 0;}intMain () {printmenuos (); Setprompt ("Menuos>>"); Menuconfig ("Version","Menuos V1.0 (Based on Linux 3.18.6)", NULL); Menuconfig ("Quit","Quit from Menuos", Quit); Menuconfig ("Time","Show System Time", time); Menuconfig ("Time-asm","Show System Time (ASM)", timeasm); Menuconfig ("MkDir","Create folder", Mkdir);//New plus codeMenuconfig ("Mkdir_asm","Create folder (ASM)", mkdirasm);//New plus codeExecutemenu ();}

compiler function

`sem_open‘`mktemp‘`mkstemp‘

Re-create the root file system

1.3 GDB Command Preparation

According to courseware
Debug kernel with GDB trace

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S # 关于-s和-S选项的说明:# -S freeze CPU at startup (use ’c’ to start execution)# -s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项

Open another Shell window

gdb(gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表(gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行(gdb)break start_kernel # 断点的设置可以在target remote之前,也可以在之后
2. Experimental Process 2.1 GDB breakpoint settings

When the system receives the interrupt signal from the system call, it calls the ENTRY_32.S in the

So we set the breakpoint at entry.

(GDB) B sys_mkdirbreakpoint1  at 0XC113DB10:fileFS/NAMEI.C, Line 3525.(GDB) Info LineENTRY_32.S:493       ----Find the memory address where Entry_32.s's entry residesLine493  of "Arch/x86/kernel/entry_32.s"Starts atAddress0xc176b747  and ends  at 0xc176b748. (GDB) b *0xc176b747                  ----Break a breakpoint on the memory addressBreakpoint2  at 0xc176b747:fileARCH/X86/KERNEL/ENTRY_32.S, Line 493.

After you hit the breakpoint, start execution. Because we are in the System_call place breakpoint, all interrupts will be from this entrance, we need in the tracking, we need to determine whether we need.

2.2 Experiment started 2.2.1 before calling kernel Sys_mkdir

1) in the pop-up window, enter the command we set previously MKDIR_ASM

2). At this point we can see that gdb stops at the breakpoint we set earlier, and look at the value of the EAX that we set earlier 0x27

2at arch/x86/kernel/entry_32.S:493493     pushl_cfi %eax          # save orig_eax(gdb) info reg eaxeax            0x2739

Execute NI command in GDB and discover that the system is save_all, so save_all is defined for the macro, so GDB does not display its code properly

(gdb)ni0xc176b764  494     SAVE_ALL  ----保存堆栈值(gdb)ni

The next step is to determine if you need to turn on child tracking.
In "Linux kernel scenario analysis," there is a paragraph, is described as follows: "In the TASK_STRUCT data structure has a component flags, where the flag is called Pt_tracesys." a process can call Ptrace () through the system, and the pt_ of a child process The TRACESYS flag bit is tuned to 1, which tracks the system call of the child process. There is a command in the Linux system Strace is doing this, is a very useful tool. ”

495     GET_THREAD_INFO(%ebp) (gdb) ni0xc176b76d  495     GET_THREAD_INFO(%ebp)(gdb) ni        497     $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)(gdb) ni498     jnz syscall_trace_entry(gdb) ni

The next step is to get ready to enter the system call.

499     $(%eax   --- 对比一下传入的系统调用号是否合法(gdb) ni500     jae syscall_badsys         ----- 不合法,则跳入到异常处理(gdb) ni502     *sys_call_table(,%eax,4)  ---合理,则进入我们的内核的mkdir处理函数

Sys_call_table is a function array, and the system finds the corresponding function through the system call number 39.

2.2.2 After calling Sys_mkdir

After the system calls the kernel's code Sys_mkdir

It is first to save the value of EAX. The interruption is immediately followed by a guarantee that the next processing will not be interrupted.
Where disable_interrupts is defined as follows:

define DISABLE_INTERRUPTS(x)    cli

The debugging information is as follows:

(GDB) n?? () at ARCH/X86/KERNEL/ENTRY_32.S:504504Movl%eax, Pt_eax (%esp)# Store The return value(GDB) Info reg ECXECX0xb92    2962(GDB) n507Disable_interrupts (Clbr_any)# Make sure we don ' t miss an interrupt(GDB) n511MOVL Ti_flags (%EBP),%ecx(GDB) Info reg ECXECX0xb92    2962(GDB) n +Testl$_tif_allwork_mask,%ecx # current->work(GDB) Info reg ECXECX0x0  0(GDB) n513Jne syscall_exit_work (GDB) n519MOVL Pt_eflags (%esp),%eax  # Mix EFlags, SS and CS(GDB) n523Movb Pt_oldss (%esp),%ah

Judging in the No. 512 Guild is the key to the syscall_exit_work. When the value of ECX is zero:

And when the value of ECX is not zero, it jumps

It is not always clear here, why the same execution action ECX value will not be the same?
In another netizen's blog "Linux from the user layer to the Kernel Layer series-TCP/IP Stack part series 11: Re-talk Linux system calls" is described in this way:

        TRACE_IRQS_OFF        movl TI_flags(%ebp%ecx    //寄存器ecx是通用寄存器,在保护模式中,可以作为内存偏移指针(此时,DS作为 寄存器或段选择器),此时为返回到系统调用之前做准备        $_TIF_ALLWORK_MASK%ecx   //TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).
2.2.3 Interrupt Entry 2.2.3.1 Interrupt table initialization

Before parsing the interrupt call, take a look at the initialization process of the interrupt table.
The interrupt table is initialized by the Trap_init in the Start_kernel. For system calls, analyze only the System_call process

void __init trap_init(void){        ......#ifdef CONFIG_X86_32    set_system_trap_gate(SYSCALL_VECTOR, &system_call);    set_bit(SYSCALL_VECTOR, used_vectors);#endif       ...... }

Where the value of Syscall_vector is

# define SYSCALL_VECTOR         0x80

And the implementation of the Set_system_trap_gate function:

staticinlinevoid set_system_trap_gate(unsignedintvoid *addr){    BUG_ON((unsigned0xFF);    0x30, __KERNEL_CS);}

Where Gate_trap corresponds to the trap gate, the value of n is 0x80, and the value of addr is System_call's entry function address. Take a look at the implementation of _set_gate:

Static inline void_set_gate (intGateunsignedTypevoid*ADDR,unsignedDplunsignedIstunsignedSEG) {Gate_desc s;//corresponding parameters: Gate--0x80        //Type--gate_trap, as an enumeration value, corresponding to Gate_trap = 0xF,        //addr--corresponds to the entry address of the function, i.e. System_call        //DPL---permissions, which is 0x3        //ist--permissions, that is, kernel state 0        //seg--The segment descriptor of the door, through __kernel_cs we can find the corresponding table entry in the GDT table to get the segment base        //pack_gate's role is to set the code address settings according to the Linux kernel requirementsPack_gate (&s, type, (unsigned Long) addr, DPL, ist, seg);/ * * does not need to being atomic because it is only done once at * setup time */    //Set idt_table tableWrite_idt_entry (idt_table, Gate, &s); Write_trace_idt_entry (Gate, &s);}

And Write_idt_entry is very simple.

staticinlinevoidintconst gate_desc *gate){    memcpysizeof(*gate));}

Set IDT[0X80] This value to the System_call value we need.

2.2.3.2 Interrupt Entry

When entering an interrupt service program through an int instruction, an interrupt vector is given in the instruction. The CPU first finds a door based on the vector and interrupt vector table, in which case the gate is always interrupted. Then, the door will be the DPL and the CPU of the CPL compared to the CPL must be less than or equal to DPL, that is, priority is not less than DPL, in order to pass through the door. After crossing the interrupt gate, further compare the DPL in the target snippet description to the CPL, the target segment's DPL must be less than or equal to the CPL.

Experimental conclusion
    1. INT 0x80 is processed by the CPU and then finds the address of System_call by looking up the IDT table for Linux initialization, which is the address of ENTRY_32.S
    2. When you enter the ENTRY_32.S, the stack information is saved first. EAX Save system call number
    3. The system then finds the corresponding system call table Sys_call_table according to the system call number, and this table holds the actual kernel processing function.
    4. When the kernel processing is completed, it is returned to Entry_32.s, at which time the system will perform a series of processing, such as off interrupt, and then return to the user state. This completes the entire system call.

Reference:
1. Linux 3.5.4 system call analysis http://blog.csdn.net/shen332401890/article/details/17434425
2. GDB Trace Debug Command collation: http://www.cnblogs.com/kzloser/archive/2012/09/21/2697185.html
3. Linux from the user layer to the Kernel Layer series-TCP/IP Stack part series 11: Re-talk Linux system call: Http://blog.csdn.net/byhankswang/article/details/9412093?utm_ Source=tuicool&utm_medium=referral
4. "Linux kernel source code scenario analysis (previous)" Maudeca/Hu Himing

Parsing the System_call interrupt processing process through system calls

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.