How the Linux kernel loads and starts a removable stroke one. Experiment 1.1 understand the process of compiling links and the elf executable file format. 1.1.1 Compiling the link process
You can use the diagram to illustrate the problem, less with the text description:
1.1.2ELF executable file
There are three main target files in the elf executable file:
- A relocatable file holds the code and the appropriate data to create an executable file or a shared file with other object files. mainly the. o file .
- An executable file holds a Cheng for execution, which indicates how exec created the program process image.
- A shared object file holds the code and the appropriate data to be linked by the following two linker. The first one is the link editor, which can be used to create additional objects with other Relocatable shared object files. The second is a dynamic linker that unites an executable file and other shared object files to create a process image.
The object file participates in the program's link (creating a program) and the execution of the program (running a program). An elf head at the beginning of the file, the road map is saved, describing the organization of the document. The Program Header table tells the system how to create a memory image of a process. The section Header table contains information describing the sections of the file. Each section has an entry in the table, and each entry gives information about its name, size, and so on. [email protected]:~/homework$ readelf -h main
C View information for a main target file:
1.2 Programming using the exec* library function to load an executable file, dynamic links are divided into executables when loading dynamic links and runtime dynamic links, programming to practice the dynamic link Library of these two ways to use. 1.2.1 using EXECLP to load last week's GCC inline assembly main program
An introduction to the EXECLP function.
int main(int argc,char *argv[]){ int pid; pid = fork(); if(pid < 0){ fprintf(stderr,"Fork failed!"); exit(-1); } else{ execlp("/home/sillysen/homework/11.14/main","./main","2","0","1","7","9","2","0","9",NULL); exit(0); } return 0;}
The results of the operation are as follows:
The first parameter of the EXECLP function is the path to the executable program, and the argument behind it is the parameter of the executable when it is run, and it is worth noting that the command itself is a parameter, so the second parameter is generally the command itself. As for why this output two times, and is such a format, I am not very clear, welcome to correct me.
1.2.2 Programming exercises These two ways to use the dynamic link library 1.2.2.1 when the executable is loaded dynamically
The code we tested was simple enough to explain the problem. Make the SHARELIB.C into a dynamic library and call it in the main function. The source code is as follows:
/* main 函数*/#include <stdio.h>extern int print();int main(int argc, char *argv[]){ print(); return 0;}/* sharelib*/int print(){ printf("This is share lib!\n"); return 0;}
[email protected]:~/homework/11.16$ gcc -fPIC -shared -o libsharelib.so sharelib.c //制作动态库libsharelib.so[email protected]:~/homework/11.16$ sudo cp libsharelib.so /usr/lib //将生成的动态库拷贝到/usr/lib目录,只有这样生成的程序才能执行
1.2.2.2 run-time dynamic linking of executable programs
Modify the main function as follows:
#include <stdio.h>#include <stdlib.h>#include <dlfcn.h>int main(int argc, char *argv[]){ //print(); void * handle = dlopen("libsharelib.so",RTLD_NOW); if(handle == NULL){ printf("Open Lib libsharelib.so Error:%s\n",dlerror); return -1; } int (*func)(void); char * error; func = dlsym(handle,"print"); if((error = dlerror()) != NULL){ printf("print not found:%s\n",error); return -1; } func(); dlclose(handle); return 0;}
The compile command is to [email protected]:~/homework/11.16$ gcc -o main main.c -ldl
use the DL series function to add-LDL parameters to the compile link, in addition to the dlfcn.h included in the header file.
1.3 using GDB Trace to analyze a EXECVE system call kernel processing function Sys_execve
According to the whole process of EXECVE system call in the video of Meng teacher, we can extract some important functions, draw the following simple flowchart (incomplete flowchart, including the process that the teacher explained) as follows:
For this I set breakpoints in key locations (in addition to the three in the video, plus a few more):
Start GDB Trace:
Analysis :
- Eight breakpoints tracked only four EXEC commands are executed. The first one is sys_execve, not because I was in the first place in the Sys_execve, the second is Do_open_exec breakpoint, the third is load_elf_binary, the fourth is start_thread. Where do_execve this breakpoint does not appear because in the SYS_EXECVE function last
return do_execve(getname(filename),argv,envp);
time I did not go in to see, and the Load_elf_interp breakpoint does not appear because the fork is called static loading executable program, This function is called only by dynamic loading, and there are two breakpoints Do_execve_common and EXEC_BINPRM do not appear. For this reason, I also deliberately broke the EXEC_BINPRM in the Search_binary_handler function, GDB shows no this symbol, here is left a question, why does this happen? According to the video, the purpose of this function is to load the BPRM data structure, but the GDB tracking process does not have this step ...
- The starting point of the new executable program is different depending on how the program is linked, and if it is a static link, the starting point is the entry address specified in the executable file and the location of the main function, and if it is a dynamic link, elf_entry is the starting point for the dynamic linker.
- EXECVE returns after the successful execution is because the executable program in the current process calls EXECVE kernel functions are ready, return to the user state of the process before the "wake" to start executing the program.
Two. 13th, 14 Chapter 2.1 Virtual file system (VFS)
The virtual file system, as a kernel subsystem, provides the user program with a file-and file-system-related interface. All file systems in the system rely not only on VFS coexistence, but also on the VFS system to work together. Through the virtual file system, the program can use standard Uinx system calls to read and write to different file systems or even file systems on different media. All in all, Linux under All files!
2.2 File System Abstraction Layer
It is possible to operate on all types of file systems using this common interface because the kernel creates an abstraction layer on its underlying file system interface. This abstraction layer enables Linux to support a variety of file systems, that is, they are very different in function and behavior, in order to support the multi-file system, VFS provides a common file system model, which contains the common feature set and behavior of any file system. Linux can support a wide variety of file systems, from the fat of DOS systems to the NTFS of Windows systems, to various UNIX-style file systems and Linux-specific filesystems. The VFS abstraction layer is capable of bridging a wide variety of file systems because it defines basic, conceptual interfaces and data structures that are supported by all file systems. At the same time, the actual file system will also be its own such as "How to open the file", "What Directory is" and other concepts in the form and the definition of VFS consistent. Because the actual file system code hides the specific implementation details under the same interface and data structure, all file systems are identical in the VFS layer and other parts of the kernel.
Four main object types in 2.3VFS
- Super Block Object Super_operations
- Index Node Object inode_operations
- Catalog Item Object Dentry_opreations
- File Object File_operations
2.4 Pieces of equipment and character devices
- hardware devices in the system that have random access to fixed-size pieces of data are called block devices, and these fixed-sized pieces of data are called blocks. The most common block devices are hard disks, floppy drives, Blu-ray drives, and flash memory. They are used in a way that installs the file system-a common way for block devices to access them.
- Character devices are ordered to be accessed in a character stream, such as a serial port and a keyboard that belong to the device. If a hardware device is accessed in a character stream, it should be classified as a character device, and if a device is randomly accessed, it belongs to a block device.
The difference between the two types of devices is the random access to the data-in other words, the ability to randomly jump from one location to another while accessing the device.
2.5 Pieces of equipment
The smallest addressable unit in a block device is a sector. The sector size is generally 2 integer multiples, the most common being 512 bytes. The size of the sector is the physical property of the device, and the sector is the basic unit of all block devices-The block device cannot compare its smaller units for addressing and operation, although many block devices can operate on multiple sectors at once.
2.6 Buffers and buffer headers
When a block is called into memory (that is, after it is read or waiting to be written), it is stored in a buffer. Each buffer corresponds to a block, which is equivalent to the representation of a disk block in memory. Since the kernel is dealing with data that requires some relevant control information, each buffer has a corresponding descriptor. This descriptor is represented by the Buffer_head struct, called the buffer header, defined in file <linux/buffer_head.h>, which contains all the information needed for the kernel to manipulate the buffer. Buffer header structure and description of each domain:
struct buffer_head{ unsigned long b_state; //缓冲区状态标志 struct buffer_head *b_this_page; //页面中的缓冲区 struct page *b_page; //存储缓冲区的页面 sector_t b_blocknr; //起始块号 size_t b_size; //映像的大小 char *b_data; //页面内的数据指针 . . .}
2017-2018-1 20179209 "Linux kernel Fundamentals and analysis" Eighth week assignment