Linux Asm CH English
Linux Asm CH English
Revision V1.9.5
www.oldlinux.org [email protected]
Linux Kernel 0.11 Full comments
A Heavily Commented Linux Kernel Source Code
Linux Version 0.11
Revision 1.9.5
(Revision 1.9.5)
Zhao Zhao
Jiong Jiong
www.plinux.org
www.oldlinux.org
2004-05-21
brief introduction
This book Linux Early operating system kernel ( v0.11) All code files were detailed and comprehensive notes and illustrations, designed to enable the reader to in the shortest possible time Linux The
working mechanism of access to comprehensive and profound understanding for further study and research Linux System lay a solid foundation. Although lower the selected version, but the core has
been able to compile and run properly, which already includes a LINUX The essence of works by reading its source code to quickly complete understanding of the operating mechanism of the kernel. The
book first to Linux Changes in the source code version of the history of the main line, introduced in detail Linux The history of the system, highlighted the important differences and improvements between
the various kernel version, it gives the choice 0.11 (0.95) Version reason as an object of study. Further organizational structure describes the relationship between the core and the source code, and also
describes a method to compile and run the version of the kernel. Then book based on the organizational structure of the kernel source code is commented and detailed description of all core programs
and files. Each chapter arrangement is basically divided into an overview of the research object, the function of each file description, comments within the code, the code and the difficulties related to the
information, the main difference with the current version of the other parts. The last chapter summary introduction to continue to study Linux The method and system start point.
Copyright statement
All rights reserved modification of e-books and formal publication. Readers are free to transmit all chapters of the book and the content, but requires attribution. Due to the current book is still in
draft stage, so there are many errors and deficiencies , I hope that readers will respond well to give criticism or advice you can give me information via e-mail: [email protected] , Or a letter directly to:
Shanghai Tongji University Mechanical and Electronic Engineering Research Institute (Shanghai Siping Road 1239 No, Zip: 200092, China).
table of Contents
-I-
table of Contents
11.10 STDDEF.H file.............................................. 479 14.3 Create a disk image file ........................................ 578
11.11 STRING.H file............................................... 480 14.4 Access to the disk image file information ........................ 581
11.12 TERMIOS.H file............................................ 490 14.5 Production root file system ............................................ 584
11.13 TIME.H file................................................. .. 497 14.6 in L INUX 0.11 The build system 0.11 Kernel ........... 590
11.14 UNISTD.H file............................................... 498 14.7 in R EDHAT 9 Under the build system L INUX 0.11 Kernel .. 591
11.15 UTIME.H file................................................ 504 14.8 use BOCHS Debugging kernel ................................... 594
- II -
Preface
Preface
This book is about a Linux The operating system kernel primer on basic working principles.
The book's main goal is to use as little space or in a limited space, to complete Linux Kernel source code were dissected in order to obtain a comprehensive understanding
of the basic functions of the operating system and the actual implementation. To do linux Kernel has a complete and profound understanding, linux The basic principle of the
Positioning book readers are aware of some Linux General use of the system or have some programming basics, but the relative lack of basic knowledge of reading the
current latest kernel source code, but also eager to further understand UNIX Like operating system kernel and the actual code that implements the principle of enthusiasts. Some
readers of this level should be bound in between the primary and secondary levels. Currently, this part of the readership in Linux The proportion of enthusiasts share is very high,
and for this part of the reader much easier to understand and to explain effective means of core information books.
At present, the description Linux Core books, try to use all the latest Linux Kernel version (eg Redhat 7.0 in use 2.2.16
Stable, etc.) are described, but due to the current Linux The entire size of the kernel source has very very large (e.g. 2.2.20 Version has 268
Million lines of code! ), So these books only to Linux Selectively kernel source principle or illustrated, many implementation details of the system are ignored. And therefore can not
give the reader the actual Linux The core has a clear and complete understanding.
Scott Maxwell With a book. " Linux Kernel source code analysis "(Lu Lina translated) substantially facing Linux Readers intermediate level, requiring more
comprehensive knowledge base to fully understand. And may be due to limited space, the book is not for all Linux Annotate kernel code, many kernel implementation details
are omitted, for example where each kernel headers used (*. h) , Utilities generate code for the kernel image file, each make The role and realize etc files not involved. So read
the book for readers in some difficulties between the intermediate level of it.
Zhejiang University, published " Linux Kernel source code Scenario Analysis, "a book, basically these deficiencies. Even though some have higher Linux Application level of
undergraduate computer system high school students, because the length of the book and the actual implementation only problem selectively explain kernel source code, can not
really thoroughly understand the kernel, which often just start reading to give up. This basic problem will appear in the student teaching process. When the book is just coming to
market, I had tried to persuade the students to read the purchase and investigate the case after two months learning to read, and so there is basically could not stand or can not
John Lions With the "Leon's UNIX Source code analysis, "a book though is a learning UNIX Like operating system kernel source code is a very good book, but because of
its use is UNIX V6 Part of the code version, in which the system calls is outdated PDP-11 Assembly language series machine, so when reading the hardware portion of the
ASTanenbaum The book "Operating Systems: Design and Implementation" is a book about the operating system kernel to achieve good introductory book, but the book
as described MINIX System is a kernel implementation of the message passing mechanism, and Linux Kernel implementation differ. Therefore, after studying the book, and not
very successfully instantly begin to learn more newer Linux Kernel source code.
When using these books to learn there will be a "elephant" feeling, not really understand Linux The overall concept of core system to achieve specific, especially for those
who Linux Beginner or just learned how to use the system Linux Those who use the system kernel book learning
-1-
Preface
When the principles, the structure of the overall operation of the kernel and not clearly formed in my mind. This in my years Linux Kernel learning process too deep. in 1991 year 10 month,
Linux Founder Linus Toravlds In the developed Linux 0.03 After the written version of the article also mentioned the same problem. In the article, entitled " LINUX - a free unix-386
kernel "The article, he said:" Developing Linux It is for students who train enthusiasts and operating system use of computer science, learning and entertainment. ... Free Software
Foundation GNU Hurd If the system has been developed becomes too large and not suitable for learning and understanding. " And today Linux System than GNU of Hurd More large
and complex system, and therefore also not suitable as a starting point for entry-learning operating system for beginners. This is also one of the motivations of writing this book.
To fill this gap, the main goal of this book is to use as little space or in a limited space, to complete Linux Kernel source code to conduct a comprehensive anatomy, with a
view to practical implementation of the basic functions and the operating system to get the full range of understanding. To do Linux Kernel has a complete and profound
understanding, Linux The basic principle of the operating system really understand and get started.
At present, there have been many Based Linux Early kernel developed kernel version specifically for embedded systems, such as DJJ of x86
operating system, Uclinux And so on (in www.linux.org On a dedicated directory), the world there are many people know from an early Linux Benefits kernel source code learning,
currently has some people are organizing manpower comments published books like this one. Thus, by reading Linux
Early versions of the kernel source code, is indeed a learning Linux An effective way systems, and research and application Linux Embedded systems are also a great help.
In the annotation process early kernel source code, the authors found that early kernel source code is almost a streamlined version of the newer kernel currently used.
Which already includes a new version of the current content in almost all of the basic functions of principles. Just as: the author of "Introduction to System Software System
Programming," a book Leland L. Beck Introducing the operating system program and system design, the introduction of a very simple instruction simplified computer ( SIC) System to
illustrate the design and implementation of all principles of system programs, which not only avoids the complexity of the actual computer system, but also a thorough description of
the problem. Select here Linux Early versions of the kernel as a learning object, its guiding ideology and Leland Consistent. This pair Linux Beginners learn the kernel, it is one of the
most ideal choice. Depth understanding can in the shortest possible time Linux The basic principle of the kernel.
For those already familiar with core operating principle, in order to make themselves do not create a sense of castles in the air of the actual workings of the system in
Of course, as with earlier kernel learning objects also have shortcomings. Chosen Linux Early kernel version does not include the virtual file system VFS Support, support
for network systems support only a.out Executable files and description of other existing complex kernel subsystem. But because the book is as Linux Core operating mechanism
to achieve entry materials, so this choice is also one of the advantages of an early version of the kernel. By studying this book, you can lay a solid foundation for further study of
Just like Linux Founder of the system on a newsgroup posting said, to understand the true operating mechanism of a software system, be sure to read the source code ( RTFSC
- Read The Fucking Source Code ). The system itself is a complete whole, with many of the seemingly unimportant details exist, but if we ignore these details, it will bring
difficulties to understand the entire system, and can not really understand the ways and means to achieve a practical system.
Although the operating system by reading some classic books principle (eg MJBach of" UNIX Operating System Design ") capable of UNIX
Works like operating systems have some theoretical guidance, but actually understand the true relationship between the composition and internal operating system implemented
is still not very clear. Just like AST Said, "many operating systems textbooks are heavy theory and practice of light", "Most books and courses for scheduling algorithms spend a lot
of time and space and completely ignored I / O In fact, the former is usually less than one code, which often account for a third of the total amount of code for the entire system.
"After the kernel lot of important details were not mentioned. So do not make the reader understand the operating system to achieve a true secret lies only in reading too detailed
full kernel source code, you will have a clear insight of feeling on the system ,Correct
-2-
Preface
The operation of the overall system have a deep understanding. Then, when you choose the latest or newer kernel source code to learn, you will not run into a big problem,
So, how can achieve the above requirements, without being too much content and confuse the mind, to select a suitable Linux Kernel version to learn, to improve the
efficiency of learning it? After the author of a large number of kernel versions to compare and choose, he chose the current Linux
The basic functions of the kernel more similar, and very short 0.11 Kernel version as the best version of entry-learning. Below is some of the major Linux
100,000,010,000,000
100,010,000,100,000
V1.0
V0.01
V0.11
V0.12
V0.95
V0.97
V0.96a
V1.1.52
V1.2.13
V1.3.95
V2.0.38
V2.2.20
V2.4.17
current Linux Kernel source code amount in the number of millions of rows of extremely large, full versions of these notes, and is almost impossible, and 0.11 Version of
the kernel does not exceed 2 Million lines of code amount, so they could explain clearly and notes in a book. Small but complete.
In addition, this version can avoid using existing newer kernel version has become increasingly complex research was part of the various subsystems (such as virtual file
system VFS , ext2 or ext3 File system, network subsystem, the new complex memory management mechanisms, etc.).
In reading this book, the authors hope that the reader has some basic knowledge of or related reference books at hand. One is about 80x86
Processor architecture and programming knowledge or information. For example, can be downloaded from the Internet 80x86 Programming Manual ( INTEL 80386 Programmer's
Reference Manual ); The other is related to 80x86 Hardware architecture and interface programming knowledge or information. A lot of information in this regard; it should also have
In addition, since Linux System kernel implementation, according to the earliest MJBach of" UNIX The basic principles of operating system design, "a book
-3-
Preface
Development, the source code of many variable or function name comes from the book, so when reading this book, if appropriate reference book, easier to understand the source
code.
Linus In the initial development Linux Operating system, referring to the MINIX operating system. For example, the initial Linux Copying the kernel version MINIX 1.0 File
system. Therefore, when reading this book, ASTanenbaum The book "Operating Systems: Design and Implementation" also has great reference value. but Tanenbaum Book
describes a message passing communication (exchange of information) between each of the core modules, and Linux The working mechanism of the kernel is not the same. You
can only refer to the contents of which operating system works on general chapter and file system implementation.
On the surface this book Linux Early versions of the kernel content like comments Linux When the operating system just released Tanenbaum It is considered outdated ( Linux
is obsolete ) The same idea, but by the content of this book, you will find that the use of book learning Linux Kernel, because the kernel source code quantity short and lean, so
there will be a high learning efficiency, able to do more with less, quick start. And lay a solid foundation for further selection to continue learning new kernel part of the source
code. After learning this postscript, you principle of operation of the system will have a very complete and practical concept, a complete concept that can make people more easily
select and study any part of the new kernel source code, without the need to read a huge amount of code to chew on a new kernel with full source code.
Currently Linux The system used Ext2 (Or latest Ext3 ) File system, the kernel is 1.x After the development of the file system, its functionality and its performance is very
detailed and complete stability, it is Linux The default operating system on standard file system. However, as Linux Complete operating system works in getting started section to
be used, in principle, is more streamlined as possible. In order to achieve a complete understanding of the operating system, and can not be overwhelming and excessive
complexity of the details of each subsystem in the choice of study analysis using kernel version, part of the code system can be described as long as the content of the actual work
Linux Kernel 0.11 At that time the version contains only the most simple MINIX 1.0 File system, an operating system for understanding the actual file system and working
principle sufficient. This is also the choice Linux One of the main kernel versions earlier study.
After a complete reading this book, I believe you will certainly send out such a sigh: "For Linux Core system, I'm finally a beginning! . "At this point, you should be very
sure to further learn the latest Linux Works and processes in various parts of the kernel.
Tongji University,
2002.12
--4--
1.1 Linux birth and development
This chapter first reviews Linux Operating system birth, development and growth process, whereby you can understand why this book would choose Linux
Some earlier versions of the system as a reason for learning object. Then specifically described early selection Linux Kernel version of the advantages and shortcomings of
learning and how to begin further study. Finally, the content of each chapter gives a brief introduction.
Linux The operating system is UNIX One kind of operating system cloning system. It was born in 1991 Year 10 month 5 Day (this is the first time outside the official
published). Since the aid Internet Network, through the joint efforts of computer enthusiasts around the world, has now become the world's most used one UNIX Like operating
Linux OS birth, development and growth process relies on the following five pillars: UNIX operating system, MINIX operating system, GNU plan, POSIX Standard and Internet The
internet. This is based on the following five basic clues to pursue it Linux The development process, its brewing process and the initial development experience. First, the four basic
elements introduced therein, and then in accordance with Linux Founder Linus Toravlds From the computer to the computer of interest and self-knowledge, to prepare my heart
Kernel 0.01 Since then released version and how the hard way in the world step by step hacker With the help of a relatively complete final launch 1.0
After this time the development version, that is to Linux The early history of the development in detail.
Of course, Linux Kernel version has been developed to 2.5.52 Version. Most Linux The system used by the kernel is stable
2.4.20 Version of the kernel (the first of which 2 If the odd numbers indicates is being developed version, we can not guarantee the stability of the system). for Linux
The general history of many articles and books have introduced, will not repeat here.
Linux The operating system is UNIX A clone version of the operating system. UNIX The operating system is the US Bell Labs
Ken.Thompson with Dennis Ritchie to 1969 In the summer DEC PDP-7 Developed on a small computer time-sharing operating system.
Ken Thompson To be able to idle the PDP-7 He runs very much like Star Trek on your computer ( Space travel ) Game, so in 1969 During the summer
vacation back home in California take his wife, developed in a month UNIX Operating system prototype. It was using BCPL Language (Basic programming language
Language has been rewritten so that UNIX System in universities and colleges have been promoted.
MINIX The system is composed of Andrew S. Tanenbaum ( AST )developing. AST In the Netherlands Amsterdam of Vrije Mathematics and Computer Science University
system work, is ACM with IEEE Fellow (only a few people around the world also is a senior member of the NPC and CPPCC). A total of 100 Articles, 5 Computer books.
AST Although born in New York, but it is a Dutch nationals ( 1914 In his ancestors came to the United States). His high school in New York, MIT
The university, the University of California Berkeley Campus PhD study. Since reading postdoctoral reason, he came home to the Netherlands. Since then, he remained in touch with
home. Later in Vrije University began teaching, research students. Dutch capital Amsterdam He is a perennial rainy city, but for AST , This is the best, however, because in such an
MINIX It's him 1987 In preparation, mainly for students to learn principles of operating systems. To 1991 Versions years 1.5 . Currently there are two versions in use: 1.5 Version
and 2.0 Version. The operating system was used in the university is free, but other uses are not. Head of course
--5--
1.1 Linux birth and development
before MINIX The system is already free from many FTP On the download.
for Linux The system, he later has said its developer Linus Praise. But he believes Linux The development of a large reason is because in order to keep him MINIX Miniaturization,
students will be able to make completion within one semester, so many people around the world did not accept MINIX
The expansion requirements. So inspired in this context Linus write Linux system. of course Linus Also happens to seize this good time.
As an operating system, MINIX Not a good person, but it also provides a C Written language and assembly language source code system. This is the first time so that aspiring
programmer or hacker Be able to read the operating system source code. At the time, the source code is the software vendors have been carefully guarded secret.
similar UNIX And is a complete operating system free software: GNU system( GNU Yes" GNU's Not Unix " Recursive acronym, it's pronounced " guh-NEW " ). Use a variety of Linux
As the core of GNU The operating system is being widely used. While these systems are generally referred to as " Linux " ,but Stallman Think, strictly speaking, they should be
The last century 90 Early years, GNU Project has developed a number of high-quality free software, including the famous emacs Editing system, bash shell program, gcc Series
compiler, gdb Debugger and so on. These software Linux Operating system development has created a suitable environment. this is Linux One of the foundations can be born, so
that many people now will Linux Operating system called " GNU / Linux " operating system.
POSIX ( Portable Operating System Interface for Computing Systems )By IEEE with ISO / IEC The development of a cluster of standards. The standard is based on the
existing UNIX Practice and experience, describes the operation of the system calls the service interface. Preparation for securing portable applications and can run on multiple
operating systems on the source code level. It is 1980 In early a UNIX user group
(Usr / group) Acquired on the basis of earlier work. That UNIX User group had tried to AT & T of System V Operating system and Berkeley CSRG of BSD The difference between the
operating system call interface re-reconcile integration. And to 1984 In the custom / usr / group standard.
1985 year, IEEE Operating Systems Technical Committee Standards Subcommittee ( TCOS-SS ) In the beginning ANSI With the support of enjoin IEEE
Standards Committee procedures operating system source code portability service interfaces formal standards. Arrived 1986 year 4 month, IEEE Worked out a trial standards. The
first is the formal standard 1988 year 9 Month approved ( IEEE 1003.1-1988 ), Also often referred to both the future
POSIX.1 standard.
To 1989 year, POSIX The work was transferred to ISO / IEC Community by 15 Working Group to continue to develop into ISO standard. To 1990
year, POSIX.1 And has been adopted C Joint language standard, formally approved IEEE 1003.1-1990 (Also ANSI Standard) and ISO / IEC 9945-1: 1990 standard.
POSIX.1 Only provides system services application programming interface ( API ), Only outlines the basic system service standards. The Working Group is expected other
functions of the system are also to develop standards. such IEEE POSIX Work begins launched. At first there are ten approved plan was afoot, nearly 300 People attended a
one-week meeting every quarter. The work that has commands and tools standard ( POSIX.2) Standard test method ( POSIX.3 ),real time API ( POSIX.4 )Wait. Arrived 1990 In the first
Working groups participating. At the same time, there are a number of organizations are also developing similar standards, such as X / Open , AT & T , OSF Wait.
in 90 Early years, POSIX Standards are in the final vote, when finalized, it is 1991-1993 Years. It is at this time Linux
Just starting up, this UNIX Standards Linux Providing important information so that Linux It can be developed under the guidance of the standard, and can with
most UNIX Operating systems. In the first Linux Kernel source ( 0.01 Version, 0.11 Version) is already Linux System and POSIX Compatible with standard ready
for work. in Linux 0.01 Version of the kernel / include / unistd.h File already defines several related POSXI Standard symbolic constant, and Linus Already he
-6-
1.1 Linux birth and development
1991 year 7 month 3 Day in comp.os.minix Posted on post The already mentioned are gathering POSIX data of. Which revealed he is looking to develop an operating
system, and in the early stage of development and has been thought to be achieved POSIX Compatible problem.
in 1981 year, IBM The company introduced a world-renowned microcomputer IBM PC . in 1981-1991 Years, MS-DOS Operating system has been dominated by
micro-computer operating system. At this point though declining price of computer hardware, but the software price is still high. then Apple of MACs The operating system can be
said to be the best performance, but its high price makes no one can easily close.
At that time the camp is another computer technology UNIX world. but UNIX The operating system is not only expensive problem. In order to seek high profit
margins, UNIX Dealers to raise prices too high, PC Small users can not close it. Once received Bell Labs
The license can be used for teaching at the university UNIX The source code has been carefully guarded allowed to open. For the majority of PC User, the software industry's large
At that moment, there was MINIX Operating system, and there is a book that describes the design and implementation of the principles will also be issued. due to AST Of
this writing it is very detailed, and narrated orderly, so almost computer enthusiasts around the world are beginning to look at this book, in order to be able to understand the
workings of the operating system. Which also includes Linux The founder of the system Linus Benedict Torvalds .
then( 1991 year), Linus Benedict Torvalds Is a sophomore at the University of Helsinki Department of Computer Science, is also a self-taught computer hacker . This one twenty
one Young Finnish-year-old likes to tinker with his computer and test computer performance and limitations. But when he lacks is a professional-grade operating system.
During the same year, GNU Program has developed a number of tools. Two of the most anticipated GNU C The compiler has emerged, but have not yet developed free GNU operating
system. Even the use of teaching MINIX Operating system also began to have copyright, need to buy to get the source code. although GNU Operating Systems HURD It has been in
development, but it seems can not be completed within a few years at that time.
In order to better learn computer knowledge (perhaps just for fun ☺ ), Linus Christmas and New Year's money to use the loan to purchase a 386 Compatible computer, and
a set of mail order from the United States MINIX system software. Just wait MINIX During the software, Linus To seriously study the relevant Intel 80386 Hardware knowledge. In
order to pass Modem Dial-up connection to the host school, he used assembly language and use 80386 CPU Multitasking characteristics worked out a terminal emulation program.
Since then copies itself to the software on the old computer to a new computer, he also worked out the appropriate driver for the floppy disk drive, keyboard and other hardware
devices.
By programming practices, and that in the learning process MINIX Many restrictions system ( MINIX Although good, but just a simple operating system for teaching
purposes, rather than a strong practical operating system), and the above practice Linus There have been some similar operating system, hardware device driver code, so he
began to prepare a new operating system ideas. at this time GNU Program has developed a number of software tools, which most expect GNU C The compiler has occurred.
From 1991 year 4 Since May, he by modifying the terminal emulation programs and hardware drivers, started to compile from their own operating system. At first, his
purpose is very simple, just to learn Intel 386 Programming techniques in architecture protected mode operation mode. But then Linux
The development has completely changed his mind. according to Linus in comp.os.minix Published on the newsgroup message, we know that he can gradually learn from MINIX System
Linus The first 1 Times to comp.os.minix The message is delivered in 1991 year 3 month 29 day. The postings on the topic " gcc on minix-386 does not optimize ", Is about
gcc Compiler MINIX-386 On system operation optimization problem ( MINIX-386 It is made Bruce Evans Improved use Intel 386 Characteristic 32 Place MINIX system). It can be
seen, Linus in 1991 Early years has already begun in-depth study MINIX System, and has improved during this time MINIX Operating system thought. In a further study MINIX After
the system, the idea gradually evolved into a redesign based think Intel 80386 The idea of the new operating system architecture.
He was raised in answer MINIX When on a question, said the first sentence is "read source code" ( "RTFSC (Read the F ** ing Source Code :-)" ). He believes the answer lies
in the source. This also shows that the system software for learning, we not only need to understand the basic principles of operation of the system, but also the actual system,
learning the actual implementation of the system. Because, after all, the theory is the theory, which omitted many minor, and these minor issues, although there is not much
theoretical content, but it is a necessary component of the system, like a feather sparrow body.
-7-
1.1 Linux birth and development
From 1991 year 4 The beginning of May, Linus He spent almost all the time to study MINIX-386 system( Hacking the kernel) And try to transplant GNU Software
on the system ( GNU gcc , bash , gdb Wait). And to 4 month 13 Day in comp.os.minix The release said he had successfully bash Ported to MINIX On, and has not put
First and Linux In related news 1991 year 7 month 3 Day in comp.os.minix The release (of course, that time does not exist
Linux The name was Linus Had in mind names may be FREAX ☺ , FREAX English meaning is grotesque, monster, whimsical, etc.). Which he revealed his ongoing Linux System
development, and it has been thought to be achieved and POSIX Compatible with the problem.
in Linus Another announcement in ( 1991 year 8 month 25 day comp.os.minix) He all MINIX Users ask " What would you like to see in minix? "( "Do you want the
most MINIX What the system to see? "), He first revealed in the message is developing a (free) 386 (486) Operating system, and said that just a hobby, the code will not be
great, would not like GNU As a professional. For some of the feedback we hope MINIX Features like system which does not like what other information and instructions for
practical and other reasons, the newly developed system beginning with MINIX Much like (and use MINIX The file system). And has successfully bash (1.08
Version) and gcc (1.40 Version) ported to the new system, but in a few months will be practical.
At last, Linus He affirmed that the development of the operating system does not use a line MINIX Source; and the use of the 386 The task switching characteristics, so that
the operating system is not good transplant (not portable), and can only be used AT hard disk. for Linux Portability problems,
Linus I did not consider. But now Linux It can run on almost any hardware architecture.
Arrived 1991 Year 10 month 5 day, Linus in comp.os.minix Post messages on newsgroups, announced outwards Linux The birth of the system kernel ( Free minix-like
kernel sources for 386-AT ). This message may be called Linux The birth of the Declaration, and has been widely circulated. therefore 10 month 5 Day of Linux Community is a
special day, many later Linux The new version released have chosen this day. and so RedHat The company chose this day to release its new system is not accidental.
Linux Operating system from birth to 1.0 The official version appeared, it issued a total of table 1 - 1 Some of the major versions shown.
0.00 (1991.2-4) Two processes, are displayed on the screen 'AAA' with 'BBB' .
The first official announcement of outward Linux Kernel version. Multi-threaded file system,
0.01 (1991.8)
segmentation and paging memory management.
0.02 (1991.10.5) This version and 0.03 Version is the build, it has been unable to find the characteristics above.
0.10 (1991.10) by Ted Ts'o Published Linux Kernel version. Increased memory allocation library functions.
0.11 (1991.12.8) The basic version of the kernel can be normal operation. At this point the hard drive and floppy drive.
The main increase in the software simulation program math coprocessor, increasing job control, virtual
0.12 (1992.1.15)
console, file symbolic links and virtual memory swap function.
Join the virtual file system support, increase the login function. Improve the performance of the floppy
0.95 (0.13) (1992.3.8)
disk drivers and the file system. Change the hard drive numbering. stand by CDROM .
Start adding network support. Improve the performance of the serial driver, cache, memory
0.96 (1992.5.12)
management, support dynamic link libraries, and can run X-Windows program.
0.98 (1992.9.29) Improved to TCP / IP ( 0.8.1 ) Network support, corrected extfs mistake.
0.99 (1992.12.13) Re-allocation of memory to use the design process, each process has 4G Linear space.
-8-
1.1 Linux birth and development
will Linux system 0.13 Direct renamed version of the kernel 0.95 Version, Linus It does mean that we do not feel isolated 1.0 Version is still far away. At the same time,
from 0.95 Version began, many improvements to the kernel (provided patches) are mainly on other people, and Linus The main task starts to become the kernel decide whether to
adopt a maintenance and patches. Until now, the latest version of the kernel is 2003 year 12 month 18
Announced 2.6.2 Version. Including about 15,000 Files, and use gz Compressed source code package also 40MB about! Until now, the latest version of the Table 1-2
Fig.
Kernel version number Release date Source code size (by gz After compression)
Linux Operating system just has not been referred to at the beginning Linux , Linus To his operating system named FREAX , The English meaning of the grotesque,
monster, whimsical and other means. In his new operating system will be uploaded ftp.funet.fi When the server administrator Ari Lemke
Not like this name. He believes that since it is Linus The operating system will take its homophonic Linux As a directory of the operating system of it, so
in Linus Autobiography " Just for Fun "A book, Linus explain 1 : "Frankly, I never thought to use Linux The name of the publication of this operating system,
because the name a little too arrogant. And I am ready for the final release version of what is the name of it? Freax . In fact, some early kernel code Makefile - Used
to describe how to compile the source code file - File already contains " Freax " The name, there is about half a year or so. But this will not matter, do not need a
name at the time, because I have not had anyone to publish kernel code. "
"and Ari Lemke He insisted on his way into the kernel code ftp On the site, and I did not like Freax The name. He insisted on the name now ( Linux)
I admit that I did not argue with him and more. But it is his to take the name. So I can openly say that I'm not conceited, or partially frankly I was not
thinking selfishness. But I think Well, this is a good name, but after this thing I can always convince others, as I now do so. "
From Linux Early in the source code can be seen, Linux Early in addition to the main developer of the system Linus One except the person, who is most famous Theodore
Ts'o (Ted Ts'o) . He was 1990 He graduated from MIT Computer Science. In college he actively participated in various student activities organized by the school. He likes cooking,
biking, and of course there is the Hacking on Linux . Later, he began to like the sport from amateur radio reported. He is currently in IBM Work in systems programming and other
important matters. He is an international network design, operations, sales organizations and researchers open IETF member.
Linux Popular in the world also has his great credit. already Linux When the operating system has just come out, he was with great enthusiasm linux The
development of a Maillist Almost in Linux At first release since, he has been to Linux make a contribution. He is also the first to Linux Kernel add a program people ( Linux
Kernel 0.10 Virtual disk driver Edition ramdisk.c And kernel memory allocator kmalloc.c) . So far he is still engaged with Linux Related work. He was the first in North
ftp Site ( tsx-11.mit.edu ), But the site is still for the majority Linux Users. He's right Linux One of the biggest contributions is proposed and implemented ext2 File
system. The file system has become Linux The world's de facto standard file system. He recently launched a ext3 File system. The system greatly improves the
stability and efficiency of access to the file system. As respected for his first 97 period( 2002 year 5 Months) Linux Journal Journal of him as a Cover, and interviewed
-9-
1.2 Summary of contents
Technology Center, and engaged in related Linux Standard Library LSB (Linux Standard Base) Work and other aspects.
Linux Another prominent figure in the community is Alan Cox . He had to work at the University of Wales Swansea ( Swansea University College) . At first he was particularly
fond of playing computer games, especially MUD ( Multi-User Dungeon or Dimension , Multi-user network games). in 90 Early years games.mud Newsgroup posts You can find a lot
of posts he published. He even wrote an article for this purpose MUD The history of the development ( rec.games.mud Newsgroups, 1992 year 3 month 9 day, A history of MUD) .
due to MUD The game is closely related to the network, and slowly he began to computer networks fascinated by them. To play the game and increase the speed and
network transmission speed computer running the game, he needs to choose a most satisfactory platform. So he came into contact with various types of operating systems.
Because of money, even MINIX He could not afford the system. when Linux 0.11 with 386BSD When released, he was considered a long time and finally bought a 386SX computer.
due to 386BSD Need a math coprocessor support, while the use of Intel 386SX CPU The computer is without a math coprocessor, so he installed Linux system. So he began
studying with the free source code Linux And began to Linux
The system generates interest, particularly the achievement of the relevant networks. About the Linux Single-user mode operation issues under discussion, he even praised Linux Achieve
cleverly ( beautifully) .
Linux 0.95 After release, he began Linux Writing system patches (modified program) (remember his first two patches have not been Linus Adoption), and became Linux On
the system TCP / IP One of the first people to use the network code. He later gradually joined the Linux The development team, and become a maintenance Linux One of the main
people responsible for the kernel source code, it can be said to be Linux Associations relay
Linus After the most important figure. after Microsoft The company had invited him to join, but he flatly refused. From 2001 In the beginning, he was responsible for maintenance Linux
Kernel 2.4.x Code. and Linus It is mainly responsible for the development of the latest development version of the kernel development (odd version, such as 2.5.x
Version).
"Kernel Hacker's Handbook" ( The Linux Kernel Hackers' Guide ) Author of the book Michael K. Johnson It is the first contact
Linux One of the operating system of people (from 0.97 Version). He is also famous Linux Documentation Project ( Linux Document Project - LDP ) Is one of the initiators. Once in Linux
Linux The backbone of the system is not only able to develop into what it is today, there are many experts on computer Linux He made a great contribution, not list them
here. Specific can be found in the list of major contributors Linux Kernel CREDITS Files, which are listed in alphabetical order of Linux Make a greater contribution of nearly 400 A list
of list of people, including their email Address and mailing address, home page and the main contribution to the deeds and other information.
Through the above description, we can above Linux The five pillars are summarized as follows:
UNIX operating system - UNIX to 1969 He was born in Bell laboratory. Linux It is UNIX A cloning system. UNIX
MINIX operating system - MINIX Operating system is UNIX A cloning system, in which 1987 By the famous professor of computer
Andrew S. Tanenbaum Developed. due to MINIX Event of a system and provides the source code (only free for the university) whipped up a study at universities throughout the
world in UNIX Cyclone system. Linux At first reference is MINIX System to 1991 Only began to develop.
GNU Program - Development Linux Operating system, and Linux Most software used on basically come from GNU plan. Linux
Just a kernel of an operating system, no GNU Software environment (for example, bash shell) ,then Linux We will be unable to move.
POSIX standard - The standard push Linux After the operating system plays an important role towards the development of formal way. Yes Linux Forward lighthouse.
INTERNET - if there is not Intenet Net, no computer hackers all over the world countless selfless dedication, then Linux Can only develop to 0.13 (0.95) Version
level.
This article will focus on Linux Early kernel 0.11 Version of a detailed description and notes. Linux-0.11 Version is 1991 year 12 month 8
--10--
1.2 Summary of contents
linux-0.11.tar.Z - kernel source code file. Size is 94KB, 325KB is also just expanded; as86.tar.Z
- Bruce Evans' binaries. It is 16 and the loader assembly;
INSTALL-0.11 - Updated installation information file.
Currently in addition to the original rootimage.Z File, the other four documents can be found. However, the authors have used Internet Resources for
Linux 0.11 Re-create a fully used rootimage-0.11 Root file system. And re-compile their energy in 0.11
Use the environment gcc 1.40 Compiler, configure the available experimental development environment. Currently, these documents are available from oldlinux.org Download on
the website.
In this paper, a detailed analysis of linux-0.11 All of the kernel source code for each source file have carried out detailed notes, including Makefile Annotation files. The
main analysis was performed according to the computer startup process. Therefore, analysis of coherence to the end of the kernel initialization start calling shell So far the
program. Each of the remaining procedures were carried out for its own analysis, there is no continuity, it can be read according to their needs. But in the analysis or provide some
application examples.
All programs in the analysis process if you encounter authors believe is difficult to understand the statement, will give a detailed description of relevant knowledge. For
example, in reading the code the first time encountered C Inline assembly code language, will GNU C Inline assembly language language more detailed description; in the face of the
interrupt controller input / output operations, will Intel Interrupt Controller ( 8259A ) Chip detailed description is given, and lists the commands and the methods used. This will help
deepen the understanding of the code, but also a better understanding of the use of hardware used, the authors believe that this interpretation method than the content listed in a
separate chapter to introduce a much higher overall hardware or other knowledge to efficiency.
take Linux 0.11 Version of the kernel to "cut" in order to improve our understanding of Linux Efficiency operation mechanism. Linux-0.11 Whole kernel source code version
only 325K Bytes, of which the content comprises basically Linux The essence. The latest 2.5.XX Version of the kernel is very large, nearly 188 Megabytes, even if you spend a
lifetime experience may not be able to read all read. Maybe you want to ask "If you want to start from simple, why not analyze smaller Linux 0.01 Version of the kernel source
code? It only 240K Byte about "The main reason is because 0.01
Version of the kernel code has too many shortcomings, not even including the driver of the floppy disk, there is no good to the use of a math coprocessor and a description of
the landing procedure. And its boot program structure with the current version is not the same, and 0.11 Version of the boot and program structure is now basically the same.
Another reason is to be found 0.11 The early version has been compiled to make a good kernel image file ( bootimage) , It can be used to guide the presentation. If matched
with a simple root file system image file ( rootimage) , Then it can be a normal run.
take Linux 0.11 Learning version also has shortcomings. For example, the kernel version is not yet included in the relevant specialized processes waiting queue,
TCP / IP Some very important current code and other aspects of the network, distribution and use of memory with the current kernel is also somewhat different. But the good news
Linux The network code is basically a self-contained, the relationship between the core mechanism is not very big, so you can understand the Linux After analyzing the basic
In this paper, Linux All of the kernel code are described. In order to maintain structural integrity, the composition is described structure of the code in the source code of the
kernel carried out, basically each source code directory introduces a chapter. The introduction of the order source files can be found in front of the file list index. entire Linux Kernel
source code directory structure following Table 1.1 Fig. All are based on the directory structure linux For the current directory.
--11--
1.2 Summary of contents
fs / 1991-12-08 14:08:27
mm / 1991-12-08 14:08:21
This book can be divided into three parts. The first 1 The first chapter to 4 Chapter is to describe the kernel and boot 32 Prepared Bit operating mode, as a beginner to
learn the kernel should all be read. A second portion from the first 5 The first chapter to 10 Chapter is the main part of the kernel code. The first of 5
Chapter can be read as part of the subsequent sections of this index. The first 11 The first chapter to 13 The third chapter is part of, the information can be read as a reference to
The first 2 Chapter summary description of the Linux Architecture operating system kernel source code file organizational structure and placement of each file function
substantially. Also introduced Linux Use of physical memory allocation, using several stacks and how to use the linear kernel and the virtual address to be allocated. Finally, the
kernel package start comment Linux / The first file in the directory have seen, that the overall kernel code
Makefile Contents of the file. The kernel source file is compiled manage all configuration files for build management tools make use.
The first 3 Chapter detailed notes boot / Three assembler directory, including the disk boot program bootsect.s ,Obtain BIOS Parameters in setup.s Assembler and 32 Bit
run boot code program head.s . This is done three assembler kernel boot loader into the working memory from a block device, and the detection system configuration parameters,
the entry is completed 32 All work before the bit protected mode. For the core system to perform further initialization work ready.
The first 4 Chapter introduces init / Kernel initialization program directory system main.c . It is a key place to do all the kernel initialization and into normal operation. After
completing all of the initialization system, created for shell Process. Introducing the program will need to see it to call other programs, so the order of the following chapters of
reading can be invoked in accordance with this. Since the function of memory management program is widely used in the kernel, so this should be the first chapter Readings.
When you can really understand until main.c When the program until all programs, you should already Linux Kernel have a certain understanding, it can be said to have half a
beginning ☺ But you also need to file systems, system calls, various drivers, etc. deeper reading.
The first 5 Chapter introduces kenel / All program directory. The most important part is the process of scheduling function schedule () , sleep_on ()
Functions and related system calls the program. At this point you should have an understanding of some important program them.
The first 6 Chapter kernel / dev_blk / Block device program directory will be described annotation. This chapter contains drivers for hard drives, floppy disks and other block
device, it is mainly used to deal with the file system and high-speed buffer, containing more content-related hardware. Therefore, when reading this chapter need some hardware
reference material. It is best to first look at the section of the file system.
The first 7 Chapter kernel / dev_chr / Character device driver directory annotation explained. This chapter is mainly involved in the serial line drivers, keyboard drivers, and
display drivers. These drivers make up 0.11 The kernel supports serial terminal console and terminal equipment. Therefore, this chapter also contains more content related to
hardware. In reading about the need to refer to the relevant hardware books.
The first 8 Chapter kernel / math / The simulation program directory math coprocessor. Because this book is annotated version of the kernel, it has not really begun to
support co-processor, and therefore less of this chapter, is relatively simple. Just to have a general understanding.
The first 9 Chapter kernel source code fs / File system program directory, I suggest you can pause to read it while watching this chapter
Andrew S. Tanenbaum "Operating System Design and Implementation," a book about MINIX Section of the file system because the initial Linux
The system is only supported MINIX A document system, Linux 0.11 Version is no exception.
--12--
1.2 Summary of contents
The first 10 Chapter Commentary mm / Memory manager directory. To get a full understanding of the content in this area, the need for Intel 80X86 Protected-mode operating
mode of the microprocessor has enough understanding, so this chapter contains more complete in place concerning 80X86 Description protected-mode operating mode, which
basically can refer to knowledge Intel 80386 Programmer Programming Manual ( Intel 80386 Programmer's Reference Manual) . But in this chapter, to use an example source code
will be explained as an object, you should be able to better understand how it works.
current Linux Kernel analysis books lack a description of the kernel headers, so for a beginner is concerned, at the time of reading the kernel will encounter many
obstacles. The first book 11 Chapter include / All files in a directory header been described in detail, for each substantially define, each have a constant or data structures and
detailed comments. In order to facilitate access to reference when reading this book in the appendix also some important data structures and variables often use the comments
were summarized, but the content actually can be found in this chapter. Although this chapter is primarily for the reader to other sections of reference to use, but if you want a
thorough understanding of core operating mechanism, still need to understand these header files in many of the details.
The first 12 Chapter describes the Linux 0.11 Version of the kernel source code lib / All files in the directory. These documents mainly library functions provides interface
functions to the compiler system, a system program for the future have a greater understanding of the system software help. Due to lower this version, so there's not a lot of
content, you can quickly read. This is why we have chosen 0.11 One of the reasons edition.
The first 13 Chapter tools / Directory build.c program. This program will not be included in the compiled kernel image ( image) File, it is only for the disk boot program
core blocks connected to other modules to form a complete primary kernel kernel image ( kernel image )file.
The first 14 Chapter describes the experimental environment and experimental method when learning the kernel source code. Introduces the Bochs Use and compile
emulation system Linux Kernel methods and the production method of a disk image file. Also explains how to modify Linux 0.11 The syntax of the source code to enable him RedHat
Finally, the appendices and index. Given in the Appendix Linux The basic definition of the constants and the kernel data structure definitions, and a concise description of
For ease of reference, also in the appendix of this book are listed separately in the kernel to use the relevant PC Information machine hardware. In the references, we
have only given when reading the source code can refer to the information on books, articles, etc., are not all-inclusive complex gives a list of a bunch of messy literature. For
example, in reference Linux Documentation Project LDP ( Linux Document Project When the file), we will clearly list the specific needs Which one HOWTO Article, and not only give LDP
Linus In the initial development Linux When the operating system kernel, the main reference 3 Book. One is MJ Bach Significant " UNIX Operating System Design ", the
book describes the UNIX System V Core operating principle and data structures. Linus The book uses a lot of functions in the algorithm, Linux Kernel source code names of many
important functions are taken from the book. Therefore, when reading this book, which is an essential aspect of the kernel works reference books. This is another John H. Crawford
80x86 Protected mode programming method of the books. There is a Andrew S.Tanenbaum Significant " MINIX The first operating system design and implementation, "a book 1 Version.
Linus The main use described in the book MINIX File system 1.0 Version, but in the early Linux Kernel only supports the file system, so when reading this book a chapter about the
file system, working knowledge of the principles of respect from the file system can Tanenbaum Book available.
At the time of each program explanation, we will describe briefly the main object and purpose of the program, the relationship between input and output parameters, and
other programs, and then list the complete code of the program and in which the code annotation detail, when the original comment program code or text without modification or
delete any aspect, because C Language is an English language class, a small amount of any original program English annotations symbolic constant, variable names, also
provided a lot of useful information. After the code is more in-depth dissection program, some of the language or knowledge of the hardware and code appear explained. If you go
back and look through the program after reading this information, you will have a deeper level of experience.
For some knowledge of the basic concepts introduced in this book required reading are scattered in various sections of the respective places, so was able to easily find,
but when combined with the source code to read, some basic concepts to have a deeper understanding.
Finally, note that when you have fully understood all illustrated herein, does not mean you have become a Linux The expert,
--13--
1.3 Summary
You only just set foot on Linux The journey has to be a certain amount of Linux GURU The preliminary knowledge. Then you should be reading more of the source code, it is best
progressively from 1.0 Until the beginning of the odd-numbered version of the latest version under development. In writing this book the latest Linux The kernel is 2.5.44 Version.
When you can quickly understand the latest versions of these developers are even able to make their own suggestions and patches ( patch ) Program, I also beats the ☺ .
First elaborated Linux The birth and development of five essential pillars: UNIX The original open-source version Linux The basic theory and algorithm
implementation, Rechard Stallman of GNU Plans for Linux The system provides a rich variety of free and utilities,
POSIX Appear as standard Linux It provides a reference guide to achieve standards-compliant system. AST of MINIX Operating system Linux
The birth played a lack of reference can not be ignored, Internet Yes Linux The necessary environment for growth and expansion. The last chapter provides an overview of the
--14--
2.1 Linux kernel mode
This chapter first provides an overview of Linux Preparation mode kernel and architecture, and is described in detail Linux The main function of each organization, and
code files and subdirectories in the hierarchy of basic calling kernel source directory. Then direct to the point, from the kernel source files Linux / The first file in the directory Makefile
The beginning of each line of code detailed explanatory notes. This chapter can be seen as a summary overview of the kernel source code can be used as reference information
Available a complete operating system mainly consists of 4 Components: hardware, operating system kernel, operating system services and user applications, see Fig. 2-1 Fig.
User applications are those word processing program, Internet Various applications or user-browser program compiled; operating system services are those services provided to
users of the program is seen as part of the operating system functions. in Linux Operating system, these programs include X Window system, shell Command interpreter system and
those kernel programming interface system program; the operating system kernel that is part of the book is of interest, it is mainly used for the scheduling abstract and access to
hardware resources.
User application
Hardware system
Linux The main purpose of the kernel is to perform with the computer hardware interaction programmable control and interface operation of the hardware components,
scheduling access to hardware resources, and provide a high level of execution environment and the virtual interface hardware for the user program on the computer. In this
chapter, we first based Linux 0.11 Version of the source code kernel, concisely describe Linux The basic architecture of the core, constituting the main module. Then several
important data structures occur in the source code will be explained. Finally, it describes the construction Linux 0.11 Methods kernel compile test environment.
At present, the structure of the operating system kernel mode can be divided into single monolithic kernel mode and hierarchical micro-kernel mode. The book comments Linux
0.11 Kernel, is the use of single-core mode. The main advantages of the single-core mode structure is compact kernel code, execution speed, the deficiency is primarily structural
In the system of single-core mode, the operating system for the flow of services provided: application programs are used to specify parameter values call instruction
execution system ( int x80) ,Make CPU From the user mode ( User Mode ) Is switched to the core state ( Kernel Model ), Then the operating system service call specific call procedure
according to the specific system parameter values, and these services are programs in accordance with some functions need to support the bottom to accomplish specific functions.
After completion of the required service application, operating system, and from switch back to user mode kernel mode, returns to the application program execution continues
following instructions. Therefore Summary speaking, single-kernel-mode kernel can be roughly divided into three levels: call the main program level services,
--15--
2.2 Linux kernel system architecture
Service layer and the underlying function support system call system call. See Fig. 2-2 Fig.
system service
Support Functions
Linux Mainly by the kernel 5 A module configuration, they are: inter-process scheduling module, a memory management module, a file system module, a process
Process scheduling module is used to control the process responsible for CPU Use of resources. Scheduling policy adopted by each process can be fair and reasonable
access CPU While ensuring the core can perform hardware operations in a timely manner. Memory management module is used to ensure that all processes can share the
machine's main memory area safely, at the same time, the memory management module also supports virtual memory management, so that Linux Support for the process uses
more memory space than the actual memory capacity. And can not use the file system to the temporary memory block is switched to the external storage device up, and then
switched back when necessary. The file system module for supporting and driving the external storage device. The virtual file system module by providing a common to all of the
external storage device file interface, hiding the details of the various hardware devices. And to provide support for other operating systems are compatible with a variety of file
system formats. Interprocess communication subsystem modules for support information exchange between multiple processes. The network interface module provides access to
Dependencies between these modules see FIG. 2-3 Fig. Wherein the connection on behalf of dependencies, and an imaginary broken line between them represents the
frame portion Linux 0.11 Section has not been realized (from Linux 0.95 Version gradually began to realize the virtual file system, and support to the network interface 0.96 Version
only).
--16--
2.2 Linux kernel system architecture
Memory Management
Network Interface
As can be seen from the figure, all modules are dependencies and process scheduling module. Because they need to rely on the process scheduler to suspend (pause) or
re-run their course. Typically, a module will be suspended while waiting for the hardware to operate, and can continue to run after the operation is completed. For example, when a
process attempts to write a block of data up diskette, floppy disk driver may start the rotation of the floppy disk during the process put on hold waiting state, and in the floppy disk
and then proceeds to the normal speed so that the process can continue run. Other 3 Modules also due to similar reasons and process scheduling module dependencies.
Some few other dependencies less obvious, but equally important. Process scheduling subsystem need to use memory manager to adjust the physical memory space used
by a particular process. Interprocess communication subsystems will need to rely on the memory manager to support shared memory communication mechanism. This
communication mechanism allows two processes to access the same area of memory for inter-process exchange of information. The virtual file system will also use the network
interface to support the Network File System ( NFS ), Also can use the memory management subsystem to provide virtual memory disk ( ramdisk )device. And the memory file system
management subsystem is also used to support the switching operations of the memory block.
If the kernel mode from single structural model, we can also according to Linux 0.11 Structure kernel source code kernel module mainly plotted 2-4 Shown in block
diagram.
--17--
2.3 interrupt mechanism
User-level
Kernel-level
Process
program
Cache
Control Subsystem Scheduler
Hardware Control
Kernel-level
Hardware-level
hard Parts library user
Wherein the kernel level of several blocks, in addition to the hardware control block, other blocks correspond to thick line directory organization kernel source.
In addition to the dependency of these figures we have been given, all of which will depend universal resource modules in the kernel. These resources include all
subsystems kernel memory allocation and recovery of function calls will print a warning or error message function and a number of system debugging functions.
In use 80X86 consist of PC Machine, using two 8259A Programmable interrupt controller chip. Each piece can be managed 8 Interrupt sources. By cascading multiple sheet
management can constitute up 64 System interrupt vectors. in PC / AT Series compatible, the use of the two 8259A
Chip, a total of management 15 Level interrupt vectors. Which is shown schematically in Figure cascaded 2-5 Fig. From which the chips INT Pin is connected to the main chip
IR2 Pin on. the Lord 8259A Chip is the port address 0x20 From chip 0xA0 .
--18--
2.4 System Timing
Address 0x20-0x3f A0
CS
CAS2-0
Address 0xA0-0xbf A0
CS
Under control of the bus controller, 8259A Chip may be a programmed state and an operating state. Programming status is CPU use IN or OUT
Instructions 8259A Chip initial programming state. Once the initial programming, i.e. chips into operation, this device has to respond to the interrupt request by the external
apparatus at any time ( IRQ0 - IRQ15 ). By interrupting the arbitration select the chip will select the current highest priority interrupt request as an interrupt service objects, and by CPU
Pin INT Notice CPU The arrival of external interrupt requests, CPU After the response, the data bus from the chip D7-D0 The current service object programmed interrupt number
sent, CPU Thus obtaining the corresponding interrupt vector values, and execute the interrupt service routine.
for Linux Kernel, the interrupt signal is usually divided into two categories: hardware interrupt and software interrupt (abnormal). Each interrupt by 0-255
A number between identified. For interrupt int0 - int31 (0x00--0x1f) Each interrupt function by the Intel The company set a fixed or retained by, It belongs to the software interrupt, but
Intel The company called the exception. Because these interrupts are in CPU When an abnormality is detected due to instruction execution. Typically failure can be divided into ( Fault)
And traps ( traps) Categories. Interrupt int32 - int255 (0x20--0xff) It can be set by the user. in Linux System will int32 - int47 (0x20--0x2f) Corresponds to 8259A Interrupt control chip
IRQ0-IRQ15 And programming the system calls made ( system_call) Interruption to int128 (0x80) .
in Linux 0.11 Kernel, PC Machine programmable timer chip Intel 8253 It is set to every 10 Ms to issue a clock interrupt ( IRQ0 )signal. This time to beat is the pulse of the
operation of the system, which we call 1 A system tick. So after each 1 Ticks will be called once the clock interrupt handler ( timer_interrupt ). The handler is mainly used by jiffies Variable
to the cumulative elapsed since the system starts the clock ticks. Whenever the clock interrupt occurs once the value is increased 1 . Then get the current privilege level from the
do_timer () According to the privilege level as a function of the cumulative operating time for the current process. in case CPL = 0 , Then the process is running in kernel
mode is interrupted, so the kernel run-time process statistics stime increase 1 Otherwise, the user mode process run time statistics by 1 . If the program had to add a timer, then the
timer list for processing. If a timer expires (after decreasing equal 0 ), The timer handler is invoked. Then the current process run time to process, the current process run time slice
--19--
2.5 Linux Process Control
Sheet and is also greater than 0 , Said its time slice has not run out, so he quit do_timer () Continue the current process. If at this time the process has been decreasing for the time
slice 0 , Indicating that the process has run out of the use of CPU Time slice, the program will then determine further processing according to the level of the interrupted program.
The current process is interrupted if they are greater than the work (privilege level of the user state 0 ),then do_timer () The scheduler will call schedule () Switch to the other
processes to run. If the current process is interrupted the work in kernel mode, that is interrupted program run in the kernel, then do_timer () Eject immediately. Therefore, this
approach decision Linux Runtime system in kernel mode is not switched scheduler. Kernel mode programs can not be preempted, but it can be preempted at run time the user
mode program.
Program is an executable file, and the process ( process ) Is an instance of the program execution. The use of time-sharing technology, Linux
The operating system can simultaneously run multiple processes. The basic principle is to time-sharing technology CPU The running time is divided into a prescribed length of time
one piece, so that each process runs in a time slice. When the process of the system using a time slice expires scheduler switches to another process to run. So in fact, for a
single CPU The machine is only run one at a time process. However, due to time slice for each process running very short (eg 15 Systems ticks = 150 Ms), so the surface it seems
for Linux 0.11 The kernel is concerned, the system can have up to 64 A process exist. In addition to the first process is outside the "manual" is established, the rest are using
the system calls the process fork The new process is created, the process is created called the child process ( child process ), Creator, called the parent process ( parent process ).
Kernel using the process identification number ( process ID , pid ) To identify each process. A process executable instruction code, data, and stack region. Process code and data
portions respectively corresponding to a code segment file, the data block execution. Each process can only execute code and access their own data and stack area.
Communication between each process needs to be carried out by a system call. For only a CPU The system, at a time only one process is running. By sharing the kernel scheduler
Linux System, it may be a kernel mode process ( kernel mode ) Or a user state ( user mode ) Under execution, therefore, Linux
Kernel stack and user stack is separated. User stack in user mode processes for temporarily holding the function call parameters, local variables and other data. The kernel stack
contains a kernel program execution information at the time of the function call.
Kernel to manage processes by table, each process occupies an entry in the process table. in Linux Systems, the entry process is a task_struct Task structure pointer.
Task data structure defined in the header file include / linux / sched.h in. Referred to as process control block some books PCB ( Process Control Block ) Or process descriptor PD ( Processor
Descriptor ). Which holds all the information for the control and management processes. State includes the current running process information, signals, process ID, parent process
ID, the cumulative operating time value, the local descriptors, and TSS information file is being used and this task. The configuration shown in the specific meaning of each field is
as follows.
struct task_struct {
long state // task of running state (-1 inoperable, 0 run (ready),> 0 has stopped).
long counter // task running time count (decrement) (ticks), run time slice.
long priority // Run priority number. When the task starts running counter = priority, the greater the long run.
long signal // signal. Bitmap, each bit represents a signal, the signal value of the bit offset value = +1.
struct sigaction sigaction [32] // flag information signal and performs the operation attribute structure, a corresponding signal will be executed. long blocked
int exit_code // task exit code execution stops, the parent process will take.
unsigned long end_data // the code length + data length (number of bytes).
--20--
2.5 Linux Process Control
When a process is executing, CPU State value in the register of all, the contents of the stack and the process is referred to as the process context. When the kernel needs to
switch ( switch ) When to another process, it needs to save all the status of the current process, that is, save the context of the current process, so that when the process is executed
again, the state can be restored when the switch to execute it. in Linux In the context of the current process data are stored in the task structure in the process. When an interrupt
occurs, the kernel in the context of the interrupted process, the execution in kernel mode interrupt service routine. But while retaining all of the necessary resources in order to
resume the interrupted interrupt process executed at the end of the service.
A process for its lifetime, may be under a different set of states, a process known state. See Fig. 2-6 Fig. Process status in the process saved the task structure state
Field. When the process is waiting for system resources in a wait state, called it in sleep wait state. in Linux System, the state is divided into sleeping wait interruptible
- twenty one -
2.5 Linux Process Control
Users running
state running
Sleep Pause
Dispatch
Wake
Uninterruptible Pause state
2 00 4
uninterruptible sleep state stopped
wake carry on
Ready state
running
When the process is being CPU Perform, or is ready to perform at any time by the scheduler, the process is said to be running ( running ). The process can run in kernel
mode, you can also run in user mode. When the system resources already available, the process will be awakened and ready to operate, the state called the ready state.
The state (FIG middle column) represents the same manner as in the kernel, were to become in a TASK_RUNNING status. ◆ can interrupt sleep state ( TASK_INTERRUPTIBLE
When the process is in an interruptible wait, the system will not schedule the execution. When the system generates an interrupt or release the process is waiting for a
resource or process receives a signal, you can wake up the process of transition to the ready state (running state). ◆ uninterruptible sleep state ( TASK_UNINTERRUPTIBLE )
And can interrupt sleep-like state. But the process in this state is only to be used wake_up () It can be converted to a ready state to run when a clear wake-up function. ◆
When the process receives a signal SIGSTOP , SIGTSTP , SIGTTIN or SIGTTOU When it will enter a suspended state. May send
SIGCONT Signal so that the process of shifting to the operation. in Linux 0.11 , The conversion process has not been achieved to the state. The state is in the process will
When the process has stopped, but the parent process has not asked about their status, the process is said to be in dead state.
When running a process time slice is exhausted, the system will switch to force the scheduler to execute other processes. In addition, if the process executed in the kernel
mode have to wait for a resource system, in which case the process will call sleep_on () or sleep_on_interruptible ()
Voluntarily give up CPU The right to use, and let the scheduler to execute other processes. The process goes to sleep ( TASK_UNINTERRUPTIBLE
or TASK_INTERRUPTIBLE ).
Only when the process is transferred from the "kernel running state" to "sleep", the kernel will carry out the process of switching operations. A process running in another
process can not be preempted kernel mode, but can not change the state of a process to another process. To avoid data errors during the process of switching the kernel, the
- twenty two -
2.5 Linux Process Control
in boot / Directory bootstrap the kernel is loaded from disk into memory, and let the system run in protected mode to enter, they begin to perform system initialization
program init / main.c . The program first to use the system to determine how to allocate physical memory, then calls kernel initialization function of each part separately for memory
management, interrupt handling, block and character devices, process management as well as hard and floppy disk hardware initialization process. After completion of these
operations, the various parts of the system having been in the running state. Since then the program themselves "manual" to the task 0
(process 0 ) Running, and use fork () Calls for the first time create a process 1 . In the process 1 The program will continue with the application environment initialization and execution shell
Login procedure. The original process 0 Scheduling will be performed when the system is idle, then the task 0 Execution only pause () System call, and it will call the dispatch
function.
"Move to the task 0 The implementation of "the process by the macro move_to_user_mode ( include / asm / system.h )carry out. It main.c
The program execution flow from kernel mode (privilege level 0 ) To the user mode (privilege level 3 ) Task 0 Continue to run. Before moving, during initialization of the system
scheduler ( sched_init () ), The first task 0 The operating environment has been set. This includes artificial pre-set task 0 Value data structure of each field ( include / linux / sched.h ),
Insertion of the task in global descriptor table 0 The Task State Segment ( TSS ) And a local descriptor table descriptor ( LDT ) Segment descriptor, and they are loaded into the task
It should be emphasized that the kernel initialization is a special process, the kernel initialization code that is, the task 0 Code. From the task 0
The initial set data structure can be seen, the task 0 The base address of the code and data segments are 0 , Segment length is limited 640KB . The base address of the kernel
code and data segments are 0 , Segment length is limited 16MB , The task 0 Code and data segments are contained in the kernel code and data segments. Kernel initialization
procedure main.c That is the task 0 Code, just moves on to task 0 Before the system is in a privileged kernel mode
0 Running main.c program. Macros move_to_user_mode The function is to run from privileged kernel mode 0 The user state level conversion
3 Level, but still continue with the original code instruction stream.
In moving to the task 0 Of course, the macro move_to_user_mode Use a method interrupt return instruction caused the privilege level change. The main idea of this
method is to build an interrupt return instruction required content in the stack, the return address of the segment selector is set to the task 0 Code segment selector, which is the
privilege level 3 . After the interrupt return instruction iret When will cause the system to CPU From the privileged 0 Jump to the outer layer of the privileged class
3 On the run. Referring to FIG. 2-7 Interrupt stack frame returns schematic privilege level changes as shown.
CS original ESP
Original EFLAGS
Original
Original EIP
SP1 - iret instructions before implementation of the new SS: ESP
Macros move_to_user_mode First to the kernel stack pressed into the task 0 Data segment selector and the kernel stack pointer. Then push the contents of the flag
register. Finally pressed into the task 0 Code segment selector and executing the interrupt execution of the next instruction required offset position upon return. The offset position
When executed iret Instruction, CPU The return address into CS: EIP While the pop-up flag stack register contents. due to CPU
It is judged that the privilege level of the code segment object is 3 , With the current state of the core 0 Different level. then CPU It will stack the stack segment and stack pointer
selector to pop SS: ESP in. Since a change in privilege level hair segment registers DS , ES , FS with GS The value becomes invalid, this time
CPU These segment registers will be cleared. Therefore, the implementation of the iret After the instruction needs to reload the segment registers. Since then, the system begins
- twenty
- three
2.5 Linux Process Control
To privileged 3 Running in Task 0 Of the code. User mode stack or the stack used originally used before moving. While its kernel mode stack were top of the page where the task
data structure began to specify its ( PAGE_SIZE + (long) & init_task ). Because later when creating a new process, you need to copy the task 0 The task data structures, including
the user stack pointer, thus requiring tasks 0 The user mode stack to create a task 1 (process 1 ) Prior to maintain "clean" state.
Linux The system creates a new process using fork () System call. All the processes are by copying process 0 Obtained, the process is 0
In the process of creating a new process, the system first finds an empty entry (empty slot) that has not yet been used by any process in the task array. If the system already
has 64 A process is running, fork () The system will call the array table because the task is not available empty entry and return an error. Then the application process for the new
system in the main memory area in a memory to store its data structure of the task information, and copy all the contents of the current process task data structure as a template for
a new process task data structure. In order to prevent this process has not been completed the new process is scheduled to perform a function, then the new process should
Then copy the data structure of the task to be modified. The current process is set to the parent process of the new process, a clear signal and reset for each bit map
statistics new process, and set the initial value of the running time slice 15 Two ticks system ( 150 millisecond). Then set the task state segment based on the current process ( TSS )
The value of each register. Since the new process returns the value creating process should be 0 , You need to set tss.eax = 0 . New process kernel mode stack pointer tss.esp0 The
new process is set to top the task data structure where memory pages, and stack segment tss.ss0 Is provided to the kernel data segment selector. tss.ldt It is set as a local
descriptor table GDT The index value. If the current process uses a co-processor, the state also need to preserve the integrity coprocessor to a new process tss.i387 Structure.
After setting up a new task system code and data segment base address, limit long and copy the current process page table memory paging management. If the parent
process has the file open, it should open the corresponding file number will increase 1 . Followed by GDT Set new tasks TSS with LDT Descriptor entries, wherein the group address
information point to the new progress of the task structure tss with ldt . Then the final set to run a new task state and returns a new process ID.
Apparent from the foregoing description, Linux Process is preemptive. Still in the process is preempted TASK_RUNNING State, not just temporary CPU run. Seize processes
occur in the implementation phase process is in user mode, kernel mode at the time of execution can not be preempted.
In order to make the process efficient use of system resources, but also make the process have a fast response time, it is necessary to switch the scheduling process
using certain scheduling policy. in Linux 0.11 It adopted a scheduling policy based on priority queuing.
Scheduler
schedule () The function first scan tasks array. By comparing each ready state ( TASK_RUNNING ) The task of running time tick count is decremented counter The value to
determine which process is currently running a minimum of time. Which is greater, it means that the running time is not long, so they select the process, and use the macro
If at this time all in TASK_RUNNING State of the process time slice have been exhausted, the system according to the priority value of each process priority Recalculated
for all processes (including the ongoing process of sleep) time slice value of each task needs to run counter . The formula is:
= + priority
counter counter
2
then schdeule () Function rescan all tasks in an array TASK_RUNNING State, repeating the process until a selected process so far. Last call switch_to () The actual
If no other process can be run at this time, the system selection process 0 run. for Linux 0.11 , The process 0 Will call pause ()
Himself put to sleep can be interrupted and called again schedule () . But in the scheduling process is running, schedule () And do not care process 0
- twenty four -
2.5 Linux Process Control
In what state. As long as the system is idle on the scheduling process 0 run.
Process switch
The actual process of switching tasks by switch_to () Some assembly code to complete the macro definition. Before the handover is performed, switch_to ()
First check if the process is to be switched to the current process, and if nothing is done, exit. Otherwise, the first kernel global variables current Pointer is set to the new task, the
new task and then jump to the long task state segments TSS Address the composition, resulting in CPU Perform a task switch operation. at this time CPU Will save the state of all
registers to the current task register TR in TSS Select the current process task segment data structure pointed to by the symbol tss Structure, then the new task to select a new task
state segment data structure pointed to by the symbol tss Register information structure is returned to CPU , The system officially began operation of the tasks of the new switch.
EAX CS
EBX DS
ECX ES
EDX FS
ESI GS
EDI SS
new table EBP LDTR
ESP
EIP
EFLAGS
CR3
TR
GDT tss
Useless, ignored
The new TSS descriptor
# Long branch TSS segment selector to cause the CPU to perform a task switch operation
When a process is running or terminate the end of the run in the middle, then the kernel will need to free up system resources consumed by the process. This includes
When a user calls the program exit () System call will be executed kernel functions do_exit () . This function will first release process code and data segments occupied
memory page, close all open files with the process, the current working directory of the process used, the root directory and run the program i Node synchronization. If Cheng Youzi
into the process, then let init Process as all of its parent process child process. If the process is a process and there will Buddist control terminal, then release the control terminal, all
the processes belonging to the session to send a signal to hang up SIGHUP This will usually terminate all processes in the session. Then the process status to dead state TASK_ZOMBIE
. And sends its former parent process SIGCHLD Signal to notify one of its child processes have terminated. At last do_exit () Call scheduling function to execute other processes.
Whereby
--25--
2.6 Linux kernel's memory usage
See you in the process is terminated, its task data structure still retains. Because the parent process also requires the use of the information therein.
During the execution of the child process, the parent process normally used wait () or waitpid () Function waits for one of its child processes to terminate. When the child
process is terminated and waiting in a dead state, the parent process will handle the processes running time used to accumulate their own process. The final release has been
terminated child process task data structure occupied by the memory page, and set the pointer entry process takes loopholes in the task array.
in Linux 0.11 Core, in order to efficiently use the machine physical memory, the memory is divided into several functional areas, as shown below 2-9
Fig.
0 640K 1M
among them, Linux Kernel occupies physical memory at the beginning, followed by a high-speed buffer portion for supplying a hard disk or floppy disk block devices. When
a process device data block needs to be read, the system will first to read data in the cache area; when data needs to be written to block up the equipment, the system is first
placed in the data buffer area, and then by the block device drivers written to the device. The last part of the application is available for all programs can use part of the main
memory area at any time. When using the kernel main memory area, too, must first apply to the kernel's memory management module can only be used after the application is
successful. To contain RAM Virtual disk system, the primary bank head also part of the plan to go for the virtual disk to store data.
Because the computer systems contained in the actual physical memory capacity is limited, and therefore CPU Usually it provides memory management mechanism of
memory in the system for effective management. in Intel CPU There is provided two kinds of memory management (conversion) systems: system memory segments ( Segmentation
System ) And paging systems ( Paging System ). And paging management system is selectable by the programmer determines whether to use the system by programming. In order
to efficiently use the physical memory, Linux The system uses both Intel CPU Memory segmentation and paging management mechanism.
in Linux 0.11 Kernel, during the address mapping, we need to distinguish 3 Address and transform the concept of species between them:
a. (Process) of the logical address; b. CPU Linear address; c. The actual physical memory address.
Logical address ( Logical Address ) Refers to the offset portion of the address associated with the generated program segment. in Intel Which means the program executing
in protected mode code segment offset address of indefinite length (assuming code segments, data segments exactly the same). Application programmers need only deal with
logical addresses, segmentation and paging mechanism for him is completely transparent, involving only by the system programmer.
Linear address ( Linear Address ) Is a logical address into a physical address of an intermediate layer between the conversion. Program code will produce a logical address,
or is the segment offset, plus the base address of the corresponding segment generates a linear address. If paging is enabled, the linear address can then be transformed to
produce a physical address. If the paging mechanism is not enabled, the linear address is the physical address directly. Intel 80386 Linear address space capacity 4G .
--26--
2.6 Linux kernel's memory usage
Physical address ( Physical Address ) Is to point out now CPU Addressing physical memory address signals on the external address bus, the result is the final address of the
address conversion. If the paging mechanism is enabled, the linear address will use the item page directory and page tables into a physical address. If the paging mechanism is not
Virtual Memory( Virtual Memory ) Refers to the amount of memory the computer showing a much larger memory than actually owns. It allows programmers to compile and
run the system memory than it actually has a much larger program. This has led many large-scale projects can be implemented on systems with limited memory resources. A very
appropriate analogy is: you do not have a long track can make a train from Shanghai to Beijing to open. You only need a sufficiently long tracks (for example, 3 Km) to complete
this task. The approach taken was to the back of the shop to the front of the train tracks at once, as long as you are operating fast enough and can meet the requirements, will be
able to train like running on a complete orbit. This is virtual memory management tasks to be done. in Linux 0.11 Kernel, for each program (process) have divided the total capacity
of 64MB Virtual memory space. Thus the logical address range of the program 0x0000000 To 0x4000000 .
Sometimes we also called the logical address of the virtual address. Because similar to the concept of virtual memory space, the logical address is the actual physical
Segment in memory system, logical address of a program is automatically mapping (conversion) by the segmentation mechanism to a linear address of the intermediate
layer. Each time a reference is a reference to the memory of the memory of the memory segment. When a program references a memory address, by the respective segment
base address is added to the programmer visible logical address is formed corresponding to a linear address. At this time, if the paging mechanism is not enabled, the linear
address is sent to CPU On the external address bus, a corresponding physical memory directly addressable.
If using a paging mechanism, the linear address at this time is only an intermediate result, the paging mechanism is also required to transform, and then finally mapped to
actual physical memory addresses. And segmentation mechanism is similar to paging mechanism allows us to redirect (conversion) memory reference every time to suit our
specific requirements. The most common use of paging occasions when the system memory is actually divided into many blocks messy, it can create a large, continuous image
memory space, so do not worry about the program and manage these distributed memory blocks. Paging mechanism to enhance the performance of the segmentation
mechanism. Page address translation is based on the transformation of the base section. Any protective measures paging mechanism and does not replace protection segment
therefore, CPU The main purpose of address translation (mapping) is to solve the problem of mapping the virtual memory space to physical memory space. Meaning refers to
virtual memory space utilizing two or external memory space, so that the program can not limit the actual amount of physical memory and a method of using the memory. Usually
virtual memory space is much greater than the actual amount of physical memory.
Then the virtual memory space management is how to achieve it? Similar principles and operation of the train metaphor. First, when a program needs to exist when a
memory not used (i.e., the corresponding memory page has been marked in the memory is not in the page table entry in memory), CPU We need a way to know the situation. This
is done by 80386 The page fault abort to achieve. When a process references a page in memory address does not exist, it will trigger CPU Generating a page fault abort, and the
cause of the interruption linear address into CR2 Control register. Therefore, the process of handling the interrupt can know the exact address of the page abnormalities occur,
which can process the required page is loaded from the secondary storage space (such as a hard disk) into physical memory. If at this time all of the physical memory has been
occupied, then the aid can be part of the memory space as two swap buffer ( Swapper ) The page memory temporarily used in the buffer exchange into two, then the requested
page into memory. This is the memory management of the missing pages loading mechanism, Linux 0.11 The kernel is in the program mm / memory.c Implemented.
Intel CPU Use segments ( Segment ) To address the concept of the program. Each section defines the priority information in a memory area and accessible. And each
program can have several memory segments. A logical address (or virtual address) that is a program for addressing the specific address and para positions. in Linux 0.11 ,
Program logical addresses to linear addresses transformation process using CPU Global descriptor table GDT And local descriptor table LDT . by LDT Mapped address space
called the global address space by LDT Mapped address space is called a local address space, both of which constitute the virtual address space. Figure specific use 2-10 Fig.
--27--
2.6 Linux kernel's memory usage
FIG drawn in the case where the two tasks. For Interrupt Descriptor Table idt It is stored in the kernel code segment. Because
Linux 0.11 The kernel, the kernel and the code and data segments for each task are respectively mapped to the same base address of the linear address space, and a segment
limit length of the same, so the code and data segments cores and tasks respectively overlap. In addition, Linux 0.11 The kernel does not use descriptor system.
The basic principles of memory paging management is the whole area into the main memory 4096 Byte pages of memory pages. When using the application program
When using this memory paging management, execution of each process (task) can be used much more than the actual memory capacity of continuous address space. for Intel
80386 System CPU It can provide up 4G Linear address space. for Linux 0.11 The kernel, the system sets a global descriptor table GDT The descriptor for the maximum number of
entries 256 ,among them 2 Entry is free, 2 Entry system, each process uses two. Thus, when the system can accommodate up to ( 256-4) / 2 + 1 = 127 Tasks, and the virtual
Approximately equal 8G . but 0.11 Kernel manually define the maximum number of tasks NR_TASKS = 64 , One for each process virtual address range 64M And the virtual address is
the starting position of each process (task number - 1) * 64MB . Therefore, virtual address space is used 64MB * 64 = 4G See Figure 2-11 Fig. 4G Coincided with CPU The same linear
address space or the physical address space, so 0.11 Kernel relatively easy to confuse the concept of three types of addresses.
--28--
2.7 Linux system to use the stack
We need to process virtual address by converting its local descriptor CPU The entire linear address space address, and then use the table of contents page PDT (A page
table) and page table PT (Two page tables) mapped to the actual physical address page. Therefore, the two translations should not be confused.
In order to use the actual physical memory, the linear address is mapped to each process a different memory page of the main memory area by two memory page table
dynamically. Therefore, the maximum available per process virtual memory space is 64MB . The logical address of each process by adding the task number * 64M , Can be
converted to a linear address. But in comments, we will process usually referred to simply as the address linear address.
For more information about memory paging management, see 10 For a description of the beginning of the chapter, or see the appendix. From Linux Kernel 0.99 Later
version, use of memory space has changed. Each process can be enjoyed the whole separate 4G The address space. Because of space constraints, this will not be described
here.
This section outlines the Linux Kernel boot from the boot to the system during normal operation of the embodiment using the stack. Description of the relationship between
this part of the kernel code is relatively close, you can skip. Come back at the beginning of the code carefully read the appropriate research.
Linux 0.11 Communist system uses four stack. One is the temporary use of the system to initialize the stack; one is for the stack (the kernel stack) kernel for its own
use only one system at a fixed location address space, but also was the task 0 Userland stack; the other is through a system call for each task, the stack used when
executing kernel, kernel mode stack we call the task, each task has its own separate kernel mode stack; the last one is tasks performed by the user mode stack, the end
, setup.s)
when bootsect Code is ROM BIOS Bootloader physical memory 0x7c00 When, the stack segment is not provided and, of course, did not use the program stack. until bootsect
Be moved to 0x9000: 0 At the time, and only then the stack segment register SS Set as 0x9000 , The stack pointer
esp Register is set to 0xff00 , That the top of the stack 0x9000: 0xff00 Office, see boot / bootsect.s The first 61 , 62 Row. setup.s
The program also follows the bootsect Set in the stack segment. This is the temporary use of the system to initialize the stack.
From head.s Program since the system began formal operation in protected mode. At this time, the kernel stack segment is set to the data segment ( 0x10 ), The stack
pointer esp Set to point user_stack The top of the array (see head.s The first 31 Line), retained 1 Page memory ( 4K ) Is used as a stack. user_stack In the array definition sched.c of
67--72 OK, containing a total of 1024 Long word. Its location in the physical memory can be found at FIG. 2-12 Fig. At this point the stack is the kernel stack own use.
--29--
2.7 Linux system to use the stack
Other modules
kernel module
head sched user_stack [1k], 1 this page
portion of code
Map 2-12 Schematic diagram of the kernel stack used when you enter the protected mode
Initialization ( main.c)
in main.c In the execution move_to_user_mode () Before the code, the system has been using the stack. In the executed
move_to_user_mode () after that, main.c The code is "switched" into tasks 0 In execution. By executing fork () System call, main.c
middle init () In the task 1 The execution and the use of task 1 It stacks. and main () In itself is " Switch " Become a task 0 After continued use of the above kernel stack as its own
task 0 The user mode stack. About tasks 0 A detailed description of the stacks can be found described later.
Each task has two stacks, respectively, for performing a user mode and kernel mode programs, and are referred to as user mode and kernel mode stack stack. The main
difference between these two small stacks comprising stack task kernel mode, the amount of data stored can not exceed ( 4096-- Task data structures) bytes, approximately 3K byte.
The user mode stack task but the user can 64MB Space extends.
Each task (except task 0 ) Has its own 64MB Address space. When a task (process) has just been created, the user mode stack pointer which is provided at the end of its
address space ( 64MB To the top), while the kernel mode stack were disposed at the end of the page where its task data structures. Applications have been using the stack when
running in user mode. Actual physical memory used by the stack CPU
Determine the paging mechanism. due to Linux Achieve a replication write ( Copy on Write ), So the process is created, if the process and its parent process does not use the stack,
the stack corresponds both share the same physical memory pages.
Each task has its own stack kernel mode, the task for each task data structure ( task_struct ) On the same page. This is when you create a new task, fork () Program
in the task tss Kernel-level segment of the stack field ( tss.esp0 with tss.ss0) Set, see
among them p Data structure pointer is the task of the new task, tss It is a task state segment structure. Save it as a new kernel memory for application tasks
task_struct Structure data, tss Structure (segment) is task_struct In a field. Kernel stack segment value of the task tss.ss0 also been
--30--
2.7 Linux system to use the stack
Set to become 0x10 (I.e., the kernel data section), and tss.esp0 Points to save task_struct End structure of the page. See Fig. 2-13 Fig.
Why allocate come from the main memory area by the memory manager of a memory for storing task data structures can also be set to the data in the kernel data
segment of it, that tss.ss0 Why can be set to 0x10 It? This range of length from the kernel code segments will be described. in head.s End of the program, are provided kernel code
and data segment descriptors. Wherein the length of the segment is set become 16MB . This length value Linux 0.11 Kernel physical memory can support the maximum length (see head.s
, 110 The beginning of the line comments). Thus, kernel code may be addressed to any location in the entire range of physical memory, of course, also includes a main memory
area. To Linux 0.98 After a long period of limited version of the kernel is modified into 1GB .
Whenever the task execution kernel needs to use its kernel stack, CPU Will use TSS Structure kernel mode it is composed of a stack arranged two values. When task
switching, old task kernel stack pointer ( esp0) It will not be saved. Correct CPU Is concerned, these two values are read-only. Thus whenever a task execution mode into the kernel,
task 0 Stack
task 0 The stack is rather special, special needs to be explained. task 0 The code and data segments of the same, from the base address are 0 Start, limited length are
also 640KB . This address range is where the basic kernel code and data reside. In the implementation of the move_to_user_mode () Thereafter, it is at the end of its core state
where the page stack task data structures, and it is in front of the user mode stack of the protected mode stack is used, i.e. sched.c of
user_stack The position of the array. task 0 Stack kernel mode initialization task is specified in the data structure in which manually set, but it is in user mode execution
stack movie_to_user_mode () When, in the simulation iret Set before the return stack. In the stack, esp is still user_stack In its original position, and ss It is set to 0x17 , I.e.
the local user mode data segment table, i.e. from memory address 0
Start and length limit 640KB Segments. Referring to FIG. 2-7 Fig.
2.7.3 Task switching between kernel mode and user mode stack Stack
The system will call the task when called into the kernel, execute kernel code. At this kernel code will use the task stack kernel mode operation. When entering kernel,
since the priority level has changed (from user mode to kernel mode), the stack segment and stack pointer and the user mode stack eflags It will be stored in the kernel mode stack
task. In execution iret Exit kernel when the user returns to the program that will restore the stack and user state eflags . This process is shown in Figure 2-14 Fig.
--31--
Directory Structure 2.8 Linux kernel source code
Press-fitting direction
EFLAGS
CS EIP
due to Linux The kernel is a single-system kernel mode, therefore, the kernel has almost all of the programs closely linked, dependence and calls their relationship is very
close. So when reading a source code file often need to refer to other relevant documents. It is therefore necessary before you start reading the kernel source code, familiarize
yourself with the directory structure of the source code files and arrangements.
Here we first list Linux Complete kernel source code directory, including its subdirectories. Then describe the main functions of the various procedures contained in the
directory, making arrangements in the form of whole kernel source code can establish a general framework in our minds in order to start the next chapter of the source code
reader work.
When we use tar Command linux-0.11.tar.gz When unlock, the kernel is placed in the source file linux / Directory. Wherein the directory structure shown in Figure 2-15 Below:
linux ├─ boot
System boot assembler
├─ fs File system
├─ include Header files (* .h)
├─ kernel Kernel process scheduling, signal processing, system calls and other procedures
├─ mm Memory Manager
└─ tools Image generation tool kernel file
The kernel version contained in the source code directory 14 Subdirectories, including a total of 102 Code files. The following one by one the contents of these
linux Directory is the home directory of the source code, in addition to including all the main directory 14 Other than a subdirectory also contains the only one
Makefile file. This file is compiled support tools make The parameter configuration file. make The main purpose tools is through knowledge
--32--
Directory Structure 2.8 Linux kernel source code
Which files have not been modified to automatically determine which files need to be recompiled in a system comprising a plurality of source program files. therefore, make Tools
linux This directory Makefile The document also calls for all nested subdirectories contained Makefile File, so that when linux
Any files in the directory (including subdirectories) modification is outdated, make It will be recompiled. Therefore, in order to compile all the entire kernel source code files, as long
boot Directory contains 3 An assembly language file, the kernel source code file first to be compiled program. This 3 The main function is to guide the completion of a
program when the computer is powered kernel startup, the kernel code is loaded into memory, and do some enter 32 System initialization before-bit protected mode of operation.
among them bootsect.s with setup.s Programs need to use as86 Software to compile, using as86 Assembly language format (similar to Microsoft), and head.s need to use GNU as To
compile, using AT & T Assembly language format. The two assembly language code list and the following brief description will be the next chapter in the code comments.
bootsect.s Disk boot program is a program block, the compiler will reside in the first sector of the disk (boot sector, 0 A track (cylinder),
0 Head first 1 Sectors). in PC Powered machine ROM BIOS After the self-test, it will be BIOS Loaded into memory 0x7C00 Department for execution.
setup.s The main program for reading the hardware configuration of the machine parameters and the kernel module system Moved to the appropriate memory location.
head.s Program will be compiled in connection system The foremost part of the module, mainly for initial setup and memory management page set up to detect the
hardware work.
Linux 0.11 Kernel file system uses 1.0 Edition MINIX File system, which is due to Linux It is in MINIX Development of the system, using MINIX File systems
facilitate cross-compiler, and may be from MINIX Loaded Linux Partition. Although the use of
MINIX File system, but Linux And its treatment MINIX Different systems. The main difference is that MINIX The file system uses single-threaded approach, and Linux The use of
multiple threads. As a result of multi-threaded approach, Linux Multi-threaded program must be addressed to bring the race conditions, deadlocks and other problems, so Linux Than
the file system code MINIX The system is much more complex. To avoid race conditions, Linux Resource allocation system has been rigorously checked, and runs in kernel
mode, if the task is not active sleep (call sleep () ), Do not allow the kernel to switch tasks.
fs / Directory is the directory file system implementation program, contains 17 More C Language program. The main reference relationships between these procedures Figure
2-16 Each block shown in FIG behalf of a document from top to bottom is placed substantially relation by reference. Where each file name suffixes are omitted. c , The dotted box is
not part of the file system program files, lines with arrows indicate reference relationships, each thick line represents a reference relationship there.
--33--
Directory Structure 2.8 Linux kernel source code
High-level function
file_table
exec fcntl ioctl
data access
open stat
read_write
char dev pipe block dev file dev Low-level manipulation functions
namei
inode
truncate
bitmap
super
Cache Management
buffer
ll_rw_block
As can be seen from the figure, the directory in which the program is divided into four sections: a high speed buffer management, low-level file, the file data and file level
access functions, when in this catalog file of notes, into which we will four parts are described.
For the file system, we can use it as a high-speed buffer memory extension. All access to the file system data, we need to first read the high-speed buffer. The
catalog management file system program mainly used in the distribution and use of block device buffer cache buffer blocks. Program Manager is a high-speed buffer buffer.c ,
While other programs are mainly used for file system management.
in file_table.c File, currently only defines a file handle (descriptor) an array of structures. ioctl.c File references
kernel / chr_drv / tty.c The function implements a character device io control function. exec.c The main program includes a program execution function
do_execve () It is all exec () The main function function cluster. fcntl.c A program for implementing file i / o Control system function is called.
read_write.c A program for realizing the file read / write and three positioning system calls. stat.c Program is implemented in two states get file system calls. open.c The main
program file contains the implementation of the system to modify the properties and close the file created with function calls.
char_dev.c The main characters include equipment to read and write function rw_char () . pipe.c Program includes piping system calls read and write functions and create
the pipe. file_dev.c Based on the program included i File node descriptor structure and read and write functions. namei.c The main program includes the operating system functions
and file system directory name and file name of the calling function. block_dev.c Program includes read and write function block data. inode.c Program includes a file system for i Nodes
operating function. truncate.c Procedures for releasing device data file space occupied when deleting files.
bitmap.c A program for processing the file system i Bitmap node and logical data blocks. super.c Handler program includes a file system superblock. buffer.c Program is
mainly used for high-speed buffer memory for processing. Virtual box ll_rw_block The bottom block is read function device, it is not in fs Catalog, but kernel / blk_drv /
ll_rw_block.c Reading and writing block device driver functions. Placed here just let us clearly see that the file system for block devices read and write data, you need a
high-speed buffer drivers and block device ( ll_rw_block () ) To be operated, the assembly itself is not the file system dealing directly with the device driver blocks.
In a program annotation process, we will give another call hierarchical relationships between the various main functions of these files.
--34--
Directory Structure 2.8 Linux kernel source code
A total of header files in a directory 32 A. h head File. There main directory 13 A, asm There subdirectories 4 A, linux There subdirectories 10 A, sys There subdirectories 5 A.
These header files, see the following Description of the respective functions, and the role of specific information contained in the header file annotations See chapter.
<A.out.h> a.out Header files, define a.out Executable file format and some macros.
<Const.h> Constant symbol header files, currently only defined i Node i_mode Each flag field.
<Ctype.h> Character type header files. It defines some judgment about the character type and converting macros.
<Errno.h> Error No. header files. The system comprises various error number. ( Linus From minix In the introduction).
<Fcntl.h> Document control header file. Operable control descriptor file and constants defined symbols.
<Signal.h> Heads files. Defined symbolic constant signal, the signal structure and the operation function prototype signal.
<Stdarg.h> Standard parameter header files. In the form of macro variables defined parameter list. Mainly explained - types ( va_list ) And tri
Macro ( va_start, va_arg with va_end ) For vsprintf , vprintf , vfprintf function.
<Stddef.h> Standard definition header file. Defined NULL, offsetof (TYPE, MEMBER) .
<String.h> String header file. Mainly defines the built-in functions related to operation of the string.
<Termios.h> Terminal input and output functions header file. The main terminal interface asynchronous communication define the control port.
<Time.h> Time Type header. Chief among these are defined tm Something about the structure and function prototype time.
<Unistd.h> Linux Standard header file. Symbols and constants defined type, and affirms that the various functions. As defined
__LIBRARY__ , It also includes the number of system calls and inline assembly _ syscall0 () Wait.
<Utime.h> User time header. It defines the structure and the access and modification times utime () prototype.
The header file defines some of the main CPU Data structure closely related to architecture, macro functions and variables. Altogether 4 Files.
<Asm / io.h> io head File. Macro assembler embedded form definition io Port function operation.
<Asm / memory.h> Memory copy header files. contain memcpy () Embedded assembler macro function.
<Asm / segment.h> Operating segment header file. For embedded segment register defines the operation assembly function.
<Asm / system.h> System header files. Set or modify the defined descriptors / interrupt gate or the like embedded macro assembler.
<Linux / config.h> Kernel configuration header file. Define the keyboard language and hard disk type ( HD_TYPE ) Options.
<Linux / fdreg.h> Floppy header files. Definitions of parameters comprises the floppy disk controller.
<Linux / fs.h> File system header files. Definition File Table Structure ( file, buffer_head, m_inode Wait).
<Linux / hdreg.h> Hard disk parameters headers. Accessing the hard disk port register definition information, status code, the partition table and the like.
<Linux / head.h> head Header file defines a simple structure segment descriptors, and several selectors constants.
<Linux / kernel.h> Kernel headers. It contains some common prototype custom kernel function.
<Linux / mm.h> Memory management header files. It contains the defined page size and page number of the release function prototypes.
<Linux / sched.h> Scheduler header file that defines the task structure task_struct The initial task 0 The data,
There are also several descriptors parameter set and get embedded assembly function macro statement.
<Linux / sys.h> System call header files. contain 72 System calls C Function handler to ' sys_ ' beginning.
<Linux / tty.h> tty Header file that defines the related tty_io Serial communications parameters constant.
<Sys / stat.h> File Status header file. Containing configuration file or system state stat {} And constants.
<Sys / times.h> It defines the process run time structure tms as well as times () Function prototype.
<Sys / types.h> Type header files. System defines the basic data types.
<Sys / wait.h> Wait for the call header. Definition of system calls wait () nuclear waitpid () And dependent constant symbol.
--35--
Directory Structure 2.8 Linux kernel source code
This directory contains only a file main.c . It used to perform all of the kernel initialization, and then move to create a new user-mode process, and run on the console device shell
program.
First, the program allocates the buffer memory capacity based on how much memory the machine, if it is set up to use the virtual disk, then later in the buffer
memory also left room for it. After it initializes all hardware, including the artificial creation of a task ( task 0 ), And set the interrupt enable flag. After executing the move from
kernel mode user mode, the system calls the process of creating the first function fork () Create a run for init () Process, the child process, the system console environment
linux / kernel Directory contains the CCP 12 And a code file Makefile File, in addition to 3 Subdirectory. All programs are stored in the processing tasks kernel / Directory,
including as fork , exit , The scheduler as well as some system calls procedures. Also includes a processing interrupt handling process exceptions and traps. Subdirectory includes a
low-level device driver, such as get_hd_block with tty_write Wait. Because of the complex relationship between these documents calling code, and therefore not listed here quote in
detail the relationship between the individual files, but can still be roughly classified as shown in Figure 2-17 Fig.
schedule.c
asm.s system_call.s Call relationship
panic.c mktime
asm.s A program for a processing system hardware interrupt caused by abnormal, for the respective actual hardware exception handler is in the traps.c File, in each
interrupt processing, respectively call traps.c The corresponding C Language processing function.
exit.c The main program includes procedures for handling system calls the process to terminate. It contains process releases the session (process group) to terminate the
program and exit handlers and kill the process, terminate the process, the process hangs and other system calls.
fork.c Program shows sys_fork () The system uses two calls C Language functions: find_empty_process () with
copy_process () .
mktime.c Program comprises a kernel function of time mktime () For calculating from 1970 year 1 month 1 day 0 When the play start date seconds, as a start
panic. Contains a core program displays an error message and stop function panic () .
sched.c Program including the basic functions related to scheduling ( sleep_on , wakeup , schedule Etc.) and some simple function call system. There are also several related
signal.c Program included in the signal processing relating to 4 System call and a corresponding interrupt handler function for processing signals do_signal () .
sys.c The program includes a number of system calls, some of which has not been achieved.
system_call.s Program implements Linux System call ( int 0x80 ) Interface process, contains the actual process in the system calls the corresponding C Language processing
functions, processing functions are distributed throughout the Linux Kernel code.
--36--
Directory Structure 2.8 Linux kernel source code
vsprintf.c Program implements now included in the standard library functions of string formatting functions.
Typically, the user is to access the device via the file system, device driver for the file system to achieve the call interface. When using block device, due to the large data
throughput, in order to efficiently use the data on a block device, between the user process and the block device using the cache mechanism. When accessing data on a block
device, the system first in the form of data blocks on the data block read into a cache of the device, and then provided to the user. blk_drv Subdirectory contains 4 More c File and 1
Header file. head File blk.h Since the block device is dedicated to the program, and so C Files together. Approximate relationship between these files, see Fig. 2-18 Fig.
blk.h ll_rw_blk.c
blk.h Defined 3 More C Block device configuration program and data blocks that are common to request structure. hd.c Procedure the main data blocks of the hard disk
drive underlying function read / write, mainly do_hd__request () function; floppy.c The main program implements the read data block floppy
/ Write drive function, mainly do_fd_request () function. ll_rw_blk.c Program implements low-level block device data read / write function
ll_rw_block () , All the other programs in the kernel data read and write operations are carried out by this function block device. You will see that the function is called block devices
to access data in many places, especially in the high-speed buffer handling file fs / buffer.c in.
Program Subcategory character device containing a total of 4 More C Language program and 2 An assembler files. These documents realized the serial port
rs-232 Driving a serial terminal, keyboard and console terminal device. Map 2-19 It is roughly call the hierarchical relationships between them.
tty_io.c tty_ioctl.c
Map 2-19 Showing the relationship between the character device program
tty_io.c Program includes tty Character device read function tty_read () And write function tty_write () It provides top access interface for file systems. Also included in
the serial interrupt process called C function do_tty_interrupt () The function will be called in the interrupt type as a character read in.
console.c File mainly contains initialize console and console write function con_write () For the tty Equipment called. Also contains a display and a keyboard
rs_io.s Assembler for implementing two serial interrupt handler interface. The interrupt handler from the interrupt identification register in accordance with (port 0x3fa or 0x2fa
) Acquired 4 Two interrupt types are processed separately, and in the process the interrupt type the code read characters call
do_tty_interrupt () .
serial.c Asynchronous serial communication chip for UART Initiate operation, and sets the interrupt vector two communication ports. Also
--37--
2.9 core system and the relationship between the user program
tty_ioctl.c Program implements tty of io Control interface functions tty_ioctl () As well as termio (s) terminal io Read and write functions structure, and will call for system sys_ioctl
The subdirectory is currently only one C program math_emulate.c . one of them math_emulate () Function is interrupted int7 The interrupt handler to be called C function.
When the machine is not math coprocessor, and CPU But when executing the coprocessor instruction, it will trigger the interrupt. Therefore, the use of the software interrupt can be
used to simulate the function of the coprocessor. Kernel version discussed in this book does not yet contain emulation code relating coprocessor. This program simply print an
SIGFPE .
Kernel Library function is used for the kernel initialization process init / main.c Running in user mode process (process 0 , 1 ) Provides call support. It is exactly the same as
ordinary static library implementation. Readers can learn about the general libc The basic principles of composition libraries. in lib / There directory 12 More C Language files, except
for one by the tytso Compiled malloc.c Longer than the program, other programs are short, some only twelve lines of code that implements the interface function of some system
calls.
These documents include the main exit function _ exit () Close the file functions close (fd) , Copy the file descriptor function dup () , The file open function open () Write file
functions write () , Program execution function execve () , Memory allocation function malloc () , Wait for the child state function wait () , Create session system calls setsid () And in include
The catalog includes 2 Code files. Mainly used for the main memory area management program to achieve a process of logical addresses to linear addresses and linear
addresses to the main memory area mapped physical memory address by paging memory management mechanism, the process virtual memory page of the main memory to
Linux The kernel handles memory paging and segmentation using two ways. The first is the 386 of 4G Virtual address space into 64
Segments, each segment 64MB . All kernel occupies a first segment of which, and the physical address of the segment with the same linear address. Then assign each task a
segment to use. Paging mechanism for mapping the specified page to the physical memory segment, detecting fork Create any duplicate copies, and perform the copy-on-write
mechanism.
page.s Including memory page file abort ( int 14 ) Handler, mainly due to lack of procedures for processing page page caused by an illegal address access and abort
memory.c Program includes a function to initialize the memory mem_init () ,by page.s Memory interrupt procedure call
do_no_page () with do_wp_page () function. When you create a new process and perform the copy process operations that use memory processing functions of the file
This directory build.c Program for the Linux Respective directories are separately compiled object code generated combined image file into the kernel of an operating image .
2.9 The relationship between core system and the user program
in Linux System, the kernel provides an interface for both applications. One is the system call interface (the first 5 Section for instructions), that interrupt call int 0x80 ; The
other hand, the kernel library function (at 12 Section for instructions) to exchange information with the kernel. Kernel is the basic library functions C Library libc made of. Many system
The main system call is available to be used directly or system software used to implement the library functions. The average user is a program developed by calling
--38--
2.10 linux / Makefile file
Like with libc And other library functions to access core resources. By these libraries program calls application code to complete a variety of common tasks, e.g., opening and
closing access to a file or device, for scientific computing, error handling and the user identification number and access group ID And other system information.
System call is the highest level kernel interface with the outside world. In the kernel, each system call has a sequence number (in
include / linux / unistd.h Defined in the file header), and often implemented as macros. Applications should not directly use the system call, because in that case, portability
program on the bad. So now Linux Standard Library LSB ( Linux Standard Base ) And many other standards do not allow applications to directly access the system call macros. For
documentation system calls can be found in Linux The first operating system manuals online 2 section.
Library functions typically include C The language does not provide advanced functions perform user-level functions, such as input / output functions and string handling.
Some library functions just Enhancements version of the system call. For example, the standard I / O Library Functions fopen with fclose It provides the system call open
with close Similar functionality, but it is at a higher level. In this case, the system calls usually offer slightly better performance than the library functions, library functions but was
able to provide more functionality, and more error detection capability. The system provides library functions can be found in the documentation for the operating system online
Manual 3 section.
From this section, we begin the kernel source code file comments. First Comment linux The first file encountered in the directory Makefile . The subsequent sections according
Makefile File is equivalent to a batch file program during compilation. It is a tool program make The input data file at run time. As long as containing Makefile The
current directory, type make Command, it will be based on Makefile Setting file of source or object code files are compiled, connection or installation activities.
make Utilities can automatically determine a large program systems in those files need to be recompiled, and issue the command to compile the program files. In use make
Before, we need to write Makefile Information file that describes the relationship between the respective programs in the entire package, and give a specific control command for
each file to be updated. Generally, when the program is updated in accordance with its target file, and these objects are created by the compiler. Once you've written a suitable Makefile
File, then after you some source code files of every program in the system modified, to perform make Command will be able to carry out all the necessary work to recompile. make Program
is to use Makefile Last modified data files and code files ( last-modification time) To determine which files need to be updated for each file needs to be updated it will be based Makefile
The information issuing the appropriate commands. in Makefile File, beginning with '#' are comments lines. The beginning of the file '=' assignment statement defines some
This one Makefile The main role is to indicate file make Programs compiled independently connected end-use of tools / Directory build Executing program code to
connect all compiled kernel and combined into a running kernel image image . Specific is boot / middle
bootsect.s , setup.s use 8086 Compile assembler respectively generate respective execution module. Re-use of all other program source code GNU Compiler gcc / gas Compiling
and connected module system . Then build These three tools are combined into a kernel image file image. Basic Compiler connected / combined structure in FIG. 2-20 Fig.
--39--
2.10 linux / Makefile file
Build Tools
Kernel image file
Image
1#
2 # If you want the ram-disk device, define this to be the # if you want to use the RAM disk device, then it
3 # Size in blocks. # Define the size of the block.
4#
5 RAMDISK = # -DRAMDISK = 512
67 AS86
= As86 -0 -a # 8086 assembler and linker, see after the introduction of the list. Definition of each rear strap
8 LD86 = Ld86 -0 # They are: -0 8086 to generate an object program; -a compatible with the gas generating portion and gld code.
910 AS
= Gas # GNU assembler and linker, see after the introduction of the list.
11 LD = Gld
12 LDFLAGS = -s -x -M # Options used GNU connector gld running. Meaning: -s output file are omitted
# Some symbol information; delete all the -X-local symbols; -M represents the standard output device requires
# Connecting the print image (display) (link map), it refers to a linker generated from
# Memory address mapping, which lists the programs loaded into segment position information in memory. specific
# • Connect all the files contained references to members and their symbols.
13 CC = Gcc $ (RAMDISK) # gcc is the GNU C compiler. For UNIX-like script (script) program,
# When referring to the definition identifier, required in front of and around the identifier $ sign in parentheses.
--40--
2.10 linux / Makefile file
1718 #
twenty three ROOT_DEV = / dev / hd6 # ROOT_DEV specify the default root file system when creating a kernel image (image) files used
# In the device, which may be a floppy (FLOPPY), / dev / xxxx or simply empty, empty time
# build procedure (in tools / directory) uses the default value / dev / hd6.
2425 ARCHIVES = substituting certain kernel / kernel.o mm / mm.o fs / fs.o # kernel directory, mm directory and directory fs generated
# Ordered set of libraries, typically the GNU ar generating program. GNU ar is a binary
# Document processing program for creating, modifying and extracting files from the archive.
# Stop (-S), resulting in assembly language with the respective files corresponding to the input C of
# Code files. By default, the assembler file generated by the original file name to remove the C .c
# And plus .s suffix. -o representation followed in the form of the output file. Of which $ *. S (or $ @ )
34 $ (AS) -c -o $ *. O $ <# compiler will use gas assembler compiled .o object files. -c indicates that only compiled
# Or assembly, without connecting operation.
# Program (below will explain how to generate) will bootsect, setup and system files
# To $ (ROOT_DEV) the root file system device is assembled into the kernel image file Image.
# sync synchronization command is to force the second line buffer block data immediately write disk and updates the super block.
46 dd bs = 8192 if = Image of = / dev / PS0 # dd is the standard UNIX command: copy a file, according to the options
--41--
2.10 linux / Makefile file
# Here / dev / PS0 is the first floppy disk drive (device file).
4748 tools / build: tools / build.c
# Build.c program generated by the program execution tools directory build.
49 $ (CC) $ (CFLAGS) \
50 - o tools / build tools / build.c # compiler generates the build command execution program.
5152 boot / head.o: boot / head.s
# Generating a .so head.o object file using rules given above.
5354 tools / system:
boot / head.o init / main.o \
55 $ (ARCHIVES) $ (DRIVERS) $ (MATH) $ (LIBS) # represents a file system tools directory
# Listed elements to be generated by the right semicolons.
64 (Cd kernel / math; make) # Into the kernel / math / directory; run the make utility.
# The following similar meaning here from 66--82 row.
6566 kernel / blk_drv / blk_drv.a:
# Function block device file blk_drv.a
67 (Cd kernel / blk_drv; make)
6869 kernel / chr_drv / chr_drv.a:
# Function character device file chr_drv.a
70 (Cd kernel / chr_drv; make)
7172 kernel / kernel.o:
# Kernel object module kernel.o
73 (Cd kernel; make)
7475 mm / mm.o:
# Memory management module mm.o
85 $ (AS86) -o boot / setup.o boot / setup.s # Setup.s file for compiling generated setup file.
86 $ (LD86) -s -o boot / setup boot / setup.o # - s option indicates that you want to remove the symbols from the object file.
# Line length information about the file system. The method is first generated contain "SYSSIZE = actual length of the file system."
# Line information tmp.s file, and then add in the subsequent bootsect.s file. The method of obtaining the length of the system is:
--42--
2.10 linux / Makefile file
# Firstly ls command to the file system displays a long list, the list to obtain the line segment with the digital file grep command byte
# Information and orientation stored in tmp.s temporary file. The cut command for cutting string, tr carriage for removing the end of the line.
# Wherein the actual length :( + 15) / 16 for obtaining length information 'section' representation. Section 1 = 16 bytes.
93 (Echo -n "SYSSIZE = ("; ls -l tools / system | grep system \
94 | Cut -c25-31 | tr '\ 012' ''; echo "+ 15) / 16")> tmp.s
95 cat boot / bootsect.s >> tmp.s
96 a
97 clean: # when executing 'make clean', it will execute the command on the line 98--103, remove all documents generated by the compiling and linking.
# 'Rm' command is to delete the file, meaning -f option is to ignore the file does not exist, and does not delete the information.
# The new archive '| compress -' said it would execute tar program by the pipeline operator ( '|')
# Transmitted to the output compressor compress, and is stored as a compressed program file backup.Z.
108109 dep:
# The rule used to target or dependencies between files. These dependencies are created to make in order to determine whether you need to
# Reconstruction of a target object. For example, when a head after the documents have been altered, make it through dependencies generated recompiled with the
# Line 111 is actually $$ i $ ($ I) mean. Where $ i is the value of the preceding sentence shell variables.
# The results are then added to the pretreated tmp_make temporary file, and then copying the temporary file into the new file Makefile.
110 sed '/ \ # \ # \ # Dependencies / q' <Makefile> tmp_make
111 (For i in init / * c;. Do echo -n "init /"; $ (CPP) -M $$ i; done) >> tmp_make
112 cp tmp_make Makefile
113 (Cd fs; make dep) # For the Makefile in the fs / directory also do the same process.
114 (Cd kernel; make dep)
115 (Cd mm; make dep)
116117 ### Dependencies:
118 init / main.o: init / main.c include / unistd.h include / sys / stat.h \
119 include / sys / types.h include / sys / times.h include / sys / utsname.h \
120 include / utime.h include / time.h include / linux / tty.h include / termios.h \
121 include / linux / sched.h include / linux / head.h include / linux / fs.h \
122 include / linux / mm.h include / signal.h include / asm / system.h include / asm / io.h \
123 include / stddef.h include / stdarg.h include / fcntl.h
--43--
2.10 linux / Makefile file
makefile File is make Utilities configuration file. Make The main purpose utility that can automatically determine a large-scale program contains many source files
which files need to be recompiled. makefile The use of complicated, but here according to the above
makefile File to make some brief. For more information, refer to GNU make manual.
In order to use make Program, you need to makefile File to tell make What to do work. usually, makefile File tells make How to compile and link a file.
When it clear that, makefile You can also tell make Run various commands (for example, as a cleanup operation to delete some files).
make The execution process is divided into two distinct phases. In the first phase, it reads all makefile File and contains
makefile Files, records all the variables and their values, explicit or implicit rules, and to construct a panorama all audiences of its prerequisites. During the second phase, make On
the use of the internal configuration of the target to determine which objects need to be rebuilt, and the use of appropriate rules to operate.
when make When recompiling the program, each modified C Code files must be recompiled. If a file has been modified over the head, then in order to ensure
proper, each containing the header file C Code program will be recompiled. Each compilation operations generate a source file corresponding to the target ( object file) .
Finally, if any source file is compiled, then all object files compiled either just finished or was it compiled must be connected together to create a new executable file.
simple makefile File contains a number of rules that have the following form:
command( command)
...
...
Wherein 'target' object is usually the name of a program file generated; for example, an executable file or object file. The goal may be to take the activities of names, such
as' clear '(' clean ') . 'Prerequisite' is one or more file names is used to generate a target input conditions. Usually dependent on a target several files. The 'command' is make You
need to perform. A rule may have multiple commands, each command on its own line. Please note that you need to type a tab character before each command line! This is where
If a prerequisite is found through directory search in another directory, this command does not change the rules; they will be implemented as scheduled. Therefore, you must
carefully set the command so that the command can make Find prerequisites directory prerequisites found. This needs to be done through the use of automatic variable. A process
according automatic variables are variables that can be automatically replaced in the particular case on the command line. Automatic variables are based on the value of the target
object and its prerequisites set before command execution. E.g, '$ ^' The value represents the rules all the prerequisites, including the name of the directory they are located; '$ <' Values
represent a first rule prerequisite; ' $ @ ' Indicate that the target; and there are some automatic variables not mentioned here.
Sometimes, they are often prerequisites include the header file, and these header files and do not want to explain in the command. At this point automatic variables '$ <' It is
-c $ CC (CFLAGS) $ <-o $ @
one of them '$ <' Will be replaced automatically foo.c While $ @ will be replaced foo.o
in order to make Can use idioms to update a target object, you can not specify a command, write a rule with no command or do not write the rules. at this time make The
program will be judged according to type (suffix program) source file which implicit rules to use.
Suffix rules for make Program defines the old-fashioned method of implicit rules. (Now the rules have not been replaced by the use of
--44--
2.10 linux / Makefile file
More generic clearer pattern matching rules). The following example is a dual suffix rules. Double suffix rule is defined by a pair of suffixes: source and destination suffix suffix.
Corresponding implicit prerequisite to obtain a replacement after the suffix by using the source file name suffix. Therefore, at this time the following '$ <' Value is *. c file name. The
positive article make The meaning of the rule is to *. c Programs compiled *. s Code.
. cs:
$ (CC) $ (CFLAGS) \
- nostdinc -Iinclude -S -o $ *. s $ <
Typically having a command belonging prerequisites rules, and for generating a target change at any preconditions ( target) file. However, the rules specify a command for
the target does not necessarily have the prerequisites. For example, the target ' clean ' Related containing deleted ( delete)
Rules command does not need to have prerequisites. In this case, a rule explains how and when to remake certain files, but these files are target-specific rules. make According
prerequisite to execute the command to create or update the target. A rule can also explain how and when to perform an operation.
One makefile File may also contain other characters in addition to the rules, but a simple makefile File only needs to contain the appropriate rules. Rules might seem
much more complex than the template shown above, but basically conforms.
makefile The last generation of file dependencies are used to make make To determine whether you need to rebuild a target object. For example, when a head after the
documents have been altered, make On the adoption of these dependencies, recompile associated with the header files for all *. c file.
as86 with ld86 By Bruce Evans Write Intel 8086 Assembler and linker. It is a completely 8086 The assembler, but it can be 386 Processor
preparation 32 Bit code. Linux Use it only to create 16 Bit boot sector
(Bootsector) Code and setup Binary code execution. The syntax of the compiler and GNU The syntax of the assembler is not compatible, but similar to Intel Assembly language
Bruce Evans Yes minix operating system 32 Bit version of the main compilers, and he Linux Founder Linus Torvalds He is a good friend. Linus Himself from Bruce Evans I
learned a lot about UNIX Class knowledge of the operating system, minix The inadequacies of the operating system are also two good friends with each other to explore the results
obtained, which inspired Linus in Intel 386 Develop a new concept of the architecture of the operating system, Linux Operating system and the birth Bruce Evans Also he has a
close relationship.
For the source code and the compiler may be from the connector FTP server ftp.funet.fi On or from my website ( www.oldlinux.org)
On the download.
as [-03agjuw] [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] src
The default settings (default values except for the following, another option is off by default or absent; if a flag is not explicitly stated, there will be no output):
--45--
2.10 linux / Makefile file
- N later followed module name (file name substituted into the target source file);
- o generate the target file, followed by the target file name;
The default settings (default values except for the following, other or no option is off by default):
- 03 32-bit output;
outfile a.out format output;
- 0 head structure 16 generates a magic number of bits, and the use of subdirectories i86 -lx option;
- 3 generates a 32-bit header structure of the magic number, and the use of the i386 subdirectory -lx option;
System.map file
System.map Kernel symbol table file used to store information. The symbol table is a list of all symbols and their corresponding addresses. With each kernel compilation, it
will generate a new corresponding System.map file. When the kernel running error by System.map Parsing symbol table file, a variable name can be found corresponds to an
use System.map Symbol table file, in the kernel or the relevant procedural error, you can get the information we more easily identifiable. Sample symbol table shown
below:
c03441a0 B dmi_broken
c03441a4 B is_sony_vaio_laptop c03441c0 b
dmi_ident c0344200 b pci_bios_present
c0344204 b pirq_table
As can be seen the name dmi_broken The variable in the kernel address c03441a0 Place.
System.map Located use its software (such as the kernel logging daemon klogd) Able to find a place. At system startup, if not as a parameter in
the form of klogd Given System.map The position, klogd You will search in three places
System.map . as followed:
/boot/System.map
/System.map
/usr/src/linux/System.map
--46--
2.11 Summary
Although the kernel itself does not actually use System.map , But other procedures, such as klogd , lsof , ps As well as many other software, like
dosemu You need to have a correct System.map file. With this file, you can find these programs in accordance with a known memory address corresponding to the name of the
This chapter provides an overview of Linux Early kernel mode of the operating system and architecture. Gives Linux 0.11 The directory structure in the form of the kernel
source code, and introduces the basic functions and hierarchy of each code file in a subdirectory in detail. Then introduced in RedHat 9 Under the build system Linux 0.11 When
the kernel, the code needs to be modified in place. Finally, from Linux Under the main kernel directory makefile File start, start the kernel source code comments.
--47--
3.1 Overview
3.1 Outline
This chapter describes boot / Three assembly code files in a directory, see the list 3-1 Fig. As I mentioned in the previous chapter, although these three files
are assembler, but used two syntax. bootsect.s with setup.s Using approximate Intel The assembly language syntax is required Intel 8086 Assembler and linker as86 with
ld86 ,and head.s Then use GNU Assembler format, and runs in protected mode, with GNU of as Compiled. This is a AT & T The syntax of the assembly language
program.
The main reason both compilers is due to Intel x86 Processor family is concerned, GNU The compiler supports only i386 And later out CPU . Generation to run the
File name length (bytes) last modified time (GMT) bootsect.s 5052 bytes
In addition to reading the code you need to know some general 8086 Assembler language other than knowledge, but also on the use of Intel 80X86 Microprocessor PC Architecture
and machine 8038632 Principles of Programming at the bit protected mode some understanding. So before you start to read the source code can probably look at the appendix
concerning PC Programming and control unit hardware interface 8038632 Programming protected mode, then the code when reading the detailed description own merits appendix
Here to explain the total Linux The operating system starts the main part of the implementation process. when PC After power is turned on, 80x86 Structure
CPU Automatically enters real mode, and from the address 0xFFFF0 Start the automatic execution of the program code, the address is usually ROM-BIOS In the address. PC Machine
BIOS The execution of some detection systems, and the physical address 0 At the beginning of the interrupt vector initialization. Thereafter, it will start the first sector of the device
(the disk boot sector, 512 Bytes) read into memory absolute address 0x7C00 Place, and jump to this place. Usually a floppy boot device or hard drive. Described here is very
simple, but it is enough to understand the kernel initialization process of the work.
Linux The best part is the front 8086 Written in assembly language ( boot / bootsect.s) , It will be run by BIOS Read into memory absolute address 0x7C00 (31KB) Place,
when it is executed will be moved to its own absolute address 0x90000 (576KB) At the start and after the device 2kB
Byte code ( boot / setup.s) Read into memory 0x90200 At other portions of the kernel ( system Module) were read into the address
0x10000 At the beginning, because at that time system Does not exceed the length of the module 0x80000 Byte size (i.e. 512KB ), So it will not cover the 0x90000 At the beginning
of bootsect with setup Module. Behind setup The program will system Moves to the beginning of the memory modules, so system Address code module that is equal to the actual
physical address of the kernel code to facilitate operation of and data. Map 3-1 Clearly shows Linux These programs or modules in memory location dynamically at system startup.
--49--
3.3 bootsect.s program
FIG image location of each program. During the system loads the message " Loading ... " . Control then passed to boot / setup.s The code, which is another real-mode assembly
language program.
bootsect.s program
setup.s program
0xA0000
system module
0x90200
0x90000
system program module head.s
0x10000
0x7c00
0x0000
12345 6
Map 3-1 When the position of the boot and where the core is moved in the position memory
Some characteristics of the initiator and part identifies the host vga The type of card. If necessary, it will ask the user to select the display mode for the console. Then the
entire system from address 0x10000 Move to 0x0000 , The protected mode and jumps to the remainder of the system (in 0x0000 Office). All this time 32 Setting the start bit operating
mode is completed: IDT , GDT as well as LDT Loaded, processors and coprocessors have been confirmed, pagination work also set up; final call init / main.c middle main () program.
Source code for the above-described operation is boot / head.S In, this may be the most know-how throughout the kernel code. Note If you make a mistake in any of the foregoing
step, the computer will deadlock. Before the operating system is not yet fully operational process can not go wrong.
Why not put the system module is loaded directly into a physical address 0x0000 At the beginning and to the setup The program then move it? This is because setup The
beginning of the program code are also needed ROM BIOS Some parameters interrupt calls to get the machine (eg graphics card mode, hard disk parameter tables, etc.). when BIOS
A physical size is placed at the beginning of the memory is initialized 0x400 byte( 1Kb) The interrupt vector table, so need to use finished BIOS After the interrupt calls to this area
overwritten.
bootsect.s Disk boot block code that resides on the first sector of the disk (boot sector, 0 A track (cylinder), 0 Head first 1 Sectors). in PC Powered machine ROM BIOS After
self-test, boot sector from BIOS Loaded into memory 0x7C00 Place, then move yourself into memory 0x90000 Place. The main role of this procedure is to first setup Module (from
the setup.s Compiled) is loaded from disk to memory, followed by bootsect Back position ( 0x90200 ), Then use BIOS Interrupt 0x13 Take a currently active disk parameter table of
--50--
3.3 bootsect.s program
Number, and then displayed on the screen. " Loading system ... " String. In addition to system Modules are loaded from disk into memory 0x10000 Place to start. Then determining
the root file system device number, if not specified, it is determined based on the number of sectors per track of the disc stored in the disc guide type and kind (YES 1.44MA Offer?
) And save it to the device number root_dev ( The guide block 0x508 Address), and finally to the long jump setup Beginning of the program ( 0x90200 )carried out setup program.
1!
2 ! SYS_SIZE is the number of clicks (16 bytes) to be loaded.
3 ! 0x3000 is 0x30000 bytes = 196kB, more than enough for current
4 ! Versions of linux
! SYS_SIZE is the number of sections to be loaded (16 bytes Section 1). 0x3000 total of
! 0x30000 bytes = 196 kB (1024 bytes 1KB In terms of dollars, then it should be 192KB), the current version of the space is sufficient.
5!
6 SYSSIZE = 0x3000 ! Refers to the size of the compiled module connection system. See the list of the first 92 2.1. ! Here is one of
7!
8! bootsect.s (C) 1991 Linus Torvalds
9!
10 ! Bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves
11 ! Iself out of the way to address 0x90000, and jumps there.
12 !
13 ! It then loads 'setup' directly after itself (0x90200), and the system
14 ! At 0x10000, using BIOS interrupts.
15 !
16 ! NOTE! Currently system is at most 8 * 65536 bytes long. This should be no
17 ! Problem, even in the future. I want to keep it simple. This 512 kB
18 ! Kernel size should be enough, especially as this does not contain the
19 ! Buffer cache as in minix
20 !
twenty one ! The loader has been made as simple as possible, and continuos
twenty two ! Read errors will result in a unbreakable loop. Reboot by hand. It
twenty three ! Loads pretty fast by getting whole sectors at a time whenever possible.
!
! The following is a translation of the text in front of these:!
! It will then use BIOS interrupt 'setup' loaded directly into their back (0x90200) (576.5k),! And loaded into the
system address 0x10000. !
! Note! The current core system is limited to a maximum length (8 * 65536) (512k) bytes, even! Future this should be no
problem. I want to keep it simple. Such a maximum core length should 512k! Sufficient, especially as there is no buffer
contained in the cache as minix. !
! Loader has been simple enough to do, so continue reading error will result in an endless loop. Only manual restart. ! Whenever possible, once
twenty four
--51--
3.3 bootsect.s program
25 ! .Globl begtext, begdata, begbss, endtext, enddata, endbss defines six global identifier;
26 .text ! Text segment;
27 begtext:
28 .data ! Data segment;
29 begdata:
30 .bss ! Uninitialized data segment (Block Started by Symbol);
31 begbss:
32 .text ! Text segment;
3334 SETUPLEN = 4
!! Nr of setup-sectors the number of sectors setup program
(setup-sectors) value;
35 BOOTSEG = 0x07c0 !! Original address of boot-sector bootsect original address (the address is a
36 INITSEG = 0x9000 !! We move boot here - out of the way to move bootsect
here - to avoid;
37 SETUPSEG = 0x9020 ! Setup starts here setup program from
here!;
38 SYSSEG = 0x1000 !.! System loaded at 0x10000 (65536) system module is loaded
into 0x10000 (64 kB) at;
39 ENDSEG = SYSSEG + SYSSIZE ! Where to stop loading stop segment
address loaded!;
4041 ! ROOT_DEV:
0x000 - same type of floppy as boot.
! Root file system floppy disk device, the same equipment and the guide;
43 ROOT_DEV = 0x306 ! Specify the root file system device is the second hard disk first partition. This is old-fashioned hard disk Linux naming, meaning specific values
are as follows!:
! Master device number = device number * 256 + minor number (i.e. dev_no = (major << 8) + minor) (major
number:! Memory 1-, 2- disk, hard 3-, 4-ttyx, 5 -tty, 6- parallel port, 7- non-named pipe) 0x300 - / dev / hd0 -
representative of the first hard disk;!! 0x301 - / dev / hd1 - first partition of a disk; ...!
! 0x309 - / dev / hd9 - 2nd 4th partition plate;! From the linux kernel version 0.95 has been used
with the current method of the same name.
4445 entry start
! Tell the linker program, program execution begins at start label.
46 start: ! Line 47--56 role itself (the bootsect) segment from the current position 0x07c0 (31k)! Moved to 0x9000
(576k), the total of 256 words (512 bytes), then jumps to! Go moving the reference code place, that the
50 mov es, ax
51 mov cx, # 256 ! Mobile word count value = 256;
--52--
3.3 bootsect.s program
56 jmpi go, INITSEG ! Indirect jump. Here INITSEG pointed to jump to the segment address. ! From the bottom, CPU
57 go: mov ax, cs ! The ds, es and ss are set to the segment (0x9000) located after the mobile code.
58 mov ds, ax ! Because the program has a stack operation (push, pop, call), the stack must be set.
59 mov es, ax
60 ! Put stack at 0x9ff00. ! Sp point stack pointer 0x9ff00: at (i.e. 0x9000 0xff00)
61 mov ss, ax
62 mov sp, # 0xFF00 ! Arbitrary value >> 512
! Since the code segment moved up, so to reset the position of the stack segment. ! SP 512 is
much greater than just point offset (i.e., address 0x90200)! Can. Because the setup program also
placed from the beginning address 0x90200,! Setup program at a time of about four sectors, thus
! Note es have been set up. (When moving the code segment object is pointing es address 0x9000).
6667 load_setup:
! Line 68--77 use BIOS interrupt INT 0x13 is the use of the setup module from the second disk sector! 0x90200 start
reading at the beginning, a total of four sectors read. If the read error, the reset driver, and! Retry, no escape route. INT
! Ah = 0x02 - disk sector read into memory; al = number of sectors to be read; ch = number of tracks (cylinders) and the lower 8 bits;
cl = the start sector (bits 0-5), the track numbers! high 2 (6-7);! dh = head number;
! Take the disk drive parameters, in particular the number of sectors per track. ! Take the disk drive
parameters INT 0x13 call format and return the following information:! Ah = 0x08
dl = drive number (if the hard disk will have a set of 7).
! returned messages:
--53--
3.3 bootsect.s program
9394
mov ah, # 0x03 ! Read cursor pos
95 xor bh, bh ! Read the cursor position.
96 int 0x10
9798
mov cx, # 24 ! A total of 24 characters.
105 ! We want to load the system (at 0x10000)! Now on the system module is loaded into 0x10000 (64k) at.
106107
mov ax, # SYSSEG
108 mov es, ax ! Segment of 0x010000 ! Es = segment address of the storage system.
109 call read_it ! Read on the system disk module, es for input parameters.
110 call kill_motor ! Switch off the drive motor, so that you can know the status of the drive.
113 ! Defined (! = 0), nothing is done and the given device is used.
114 ! Otherwise, either / dev / PS0 (2,28) or / dev / at0 (2,8), depending
115 ! On the number of sectors that the BIOS reports currently.
! Since then, we have to check what the root file system device (referred to as the root device) use. If you have specified device (! = 0)! To direct a given
device. Otherwise, it needs to be based on the number of sectors per track BIOS reporting! OK in the end use / dev / PS0 (2,28) or / dev / at0 (2,8).
125 je root_defined ! If it is equal, then the ax is to guide the device number of the drive.
--54--
3.3 bootsect.s program
out, whenever possible, data on the entire track every load. ! Input: es - start memory address segment value (usually 0x1000)
! Test input segment value. Read data from the disc must be stored at the beginning of the boundary is located 64KB memory address, otherwise enter an infinite loop. ! Clear bx register, used
to indicate the start position of the current segment and storing data.
read following the data read continues. Otherwise, exit the subroutine returns.
! Start offset position based on the sector number of the current track has not been read, and the byte data segment is calculated if all unread to read the sector, the
! The total number of bytes read whether it will exceed 64KB limit the length of the segment. If more than, the number of bytes up to the read (64KB - inner section
--55--
3.3 bootsect.s program
162 seg cs
163 mov ax, sectors ! Take sectors per track.
164 sub ax, sread ! Subtracting the current track has read the number of sectors.
165 mov cx, ax ! Cx = ax = current track is not the number of sectors to read.
168 jnc ok2_read ! If there is no more than 64KB bytes, then jump to ok2_read Branch.
169 je ok2_read
170 xor ax, ax ! If more than 64KB plus read all the unread sector on the track, the calculation
171 sub ax, bx ! At this time, up to the number of read bytes (64KB - read offset inner section), and then converted
173 ok2_read:
174 call read_track
175 mov cx, ax ! Cx = number of sectors that have been read operations.
176 add ax, sread ! Current number of sectors on the track that has been read.
177 seg cs
178 cmp ax, sectors ! If there are sectors on a track currently unread, jump to the ok3_read.
179 jne ok3_read
! On data (head No. 1) read the next track of the head face. If you have finished, you read the next track.
182 jne ok4_read ! If the head is 0, 1 data sector is read again the head face.
183 inc track ! Otherwise read the next track.
184 ok4_read:
185 mov head, ax ! Save the current head number.
186 xor ax, ax ! Clear the current track has read the number of sectors.
187 ok3_read:
188 mov sread, ax ! Save the current track has read the number of sectors.
189 shl cx, # 9 ! Read the last number of sectors * 512 bytes.
190 add bx, cx ! Adjustments within the current data segment starting position.
191 jnc rp_read ! If the boundary value is less than 64KB, then jump to rp_read (156 lines), the data read continues. ! Otherwise adjust the
current section, read the next piece of data for the preparation.
196 jmp rp_read ! Jump to rp_read (156 lines), the continue reading data.
197
! Currently specified read start sector on the track and the number of sectors required to read data es: bx beginning. See the next line 67 to read BIOS disk interrupt! Int 0x13, ah =
Description 2.
198 read_track:
199 push ax
200 push bx
201 push cx
202 push dx
203 mov dx, track ! Take the current track number.
204 mov cx, sread ! Take the current read sector number on the track.
--56--
3.3 bootsect.s program
233 kill_motor:
234 push dx
235 mov dx, # 0x3f2 ! Floppy drive port control card, write-only.
236 mov al, # 0 ! A drive off the FDC, disable the DMA and interrupt requests, off the motor.
237 outb ! The contents of the output to the al dx to the specified port.
238 pop dx
239 ret
240241 sectors:
242 . word 0 ! Floppy disk to store the number of sectors per track of the current boot.
250 root_dev:
251 . word ROOT_DEV ! Here storage device number where the root file system (init / main.c will
use).
252 boot_flag:
253 . word 0xAA55 ! Hard disk to a valid ID.
256 endtext:
--57--
3.4 setup.s program
257 .data
258 enddata:
259 .bss
260 endbss:
Correct bootsect.s Illustration and description of this procedure, you can search on the Internet at large amounts of data. among them Alessandro Rubini
And by me with the translation. " Linux Kernel source code roaming "article ( http://oldlinux.org/Linux.old/docs/) Compare kernel boot process is described in detail in detail, a good
reference. Because this program is in 386 Running real mode, and therefore relatively easy to be understood. If the reading is still difficult at this time, it is recommended that you
first go over again 80x86 Compilation of relevant knowledge and hardware (can be found in Ref. [ 1] with[ 16] ), Then continue reading this book.
For the latest development Linux Kernel modifications of this procedure is small, it remained with 0.11 Version looks like.
setup The main role of the program is to use ROM BIOS Interrupt read machine system data, and saves the data to 0x90000 Starting position (overwritten bootsect The
place where the program), the parameters achieved and the memory location reserved table below 3 - 1 Fig. These parameters will be used by the kernel procedures, for example,
0x90000 2 Cursor position The column number ( 0x00- Far left), line number ( 0x00- Topmost)
0x90002 2 Number of extended memory System from 1M Extended memory numbers starting with ( KB ).
0x90008 2 ??
0x9000A 1 Display memory Display memory ( 0x00-64k, 0x01-128k, 0x02-192k, 0x03 = 256k)
...
0x90080 16 Hard disk parameter table The first 1 A hard disk parameter table
0x90090 16 Hard disk parameter table The first 2 Hard disk parameter table (if not, then cleared)
0x901FC 2 No root device Where the root file system device number ( bootsec.s Set)
then setup The program will system Modules from 0x10000-0x8ffff (At that time that the kernel module system system The length does not exceed the value: 512KB ) Moved
down to the absolute address of the block of memory 0x00000 Place. Next, loading Interrupt Descriptor Table Register ( idtr) And a global descriptor table register ( gdtr) Open A20 Address
lines, reset the two interrupt control chip 8259A The hardware interrupt number reset
0x20 - 0x2f . The last set CPU Control Register CR0 (Also known as machine status word) to enter 32 Bit protected mode and jump to is located system The front section of the
In order to allow head.s in 32 Run, this program temporarily installed in the interrupt descriptor table the protected mode ( idt ) And the global descriptor
--58--
3.4 setup.s program
Table ( gdt ), And gdt Set in the current data segment descriptors and descriptor kernel code segments. In the following head.s Resets these descriptor tables necessary
kernel program.
Now, according to CPU Addressing modes in real mode and protected mode, a comparative method will be briefly described 32 The main features of the bit
protected-mode operating mechanism, in order to easily understand the procedures in this section. Gradually be described in detail in the following sections.
In real mode, the main memory address addressing a segment and an offset value is used, the segment value is stored in the segment registers (e.g. ds ), And the maximum
length of the segment is fixed 64KB . The segment offset address stored in the register for addressing any one (e.g. si ). Thus, according to the value of a segment register and an
offset register, can be calculated memory address actually points, see Fig. 3-2 (a) Fig.
In the protected mode operating mode, the segment registers are no longer stored in the address segment base address, but an index of an item in the segment descriptor
table. The base address specified by the index value of segment descriptor entry contains the addressed memory segment required, other access level values and the maximum
length of the segment information section. Addressable memory location specified by the entry segment descriptor segment base address value and the offset value combination,
the maximum length of the segment is also specified by the descriptor. Seen, and compared to the real mode addressing, segment register value index into a segment descriptor,
the concept of an offset value in the original or real mode. Thus, addressing a memory address in the protected mode requires a multiple than the real mode procedures, i.e.
required descriptor table. This is because access to the information needs of a memory segment in protected mode more, a 16 Bit segment registers fit so much content. Is shown
register register
variable
64kb esi
ds si
ds
Descriptor Table
gdtr
Under (a) real mode addressing. Under (b) protected mode addressing.
Map 3-2 Comparison of the real mode and protected mode addressing mode
Thus, before entering the protected mode, you must be set up to use the descriptor table, for example, a global descriptor table gdt . Then use the command lgdt The base
address of the descriptor table informed CPU ( gdt Base address table is stored gdtr register). Then protected mode flag is set to enter the machine status word 32 Bit protected
mode of operation.
1!
2! setup.s (C) 1991 Linus Torvalds
3!
4 ! Setup.s is responsible for getting the system data from the BIOS,
5 ! And putting them into the appropriate places in system memory.
6 ! Both setup.s and system has been loaded by the bootblock.
7!
--59--
3.4 setup.s program
8 ! This code asks the bios for memory / disk / other parameters, and
9 ! Puts them in a "safe" place: 0x90000-0x901FF, ie where the
10 ! Boot-block used to be. It is then up to the protected mode
11 ! System to read them from there before the area is overwritten
12 ! For buffer-blocks.
!
! Setup.s responsible for getting data from the system BIOS, and put the appropriate place in the data system memory. ! Setup.s case has
been loaded by the system and bootsect boot block into memory. !
! The code asks bios on memory / disk / other parameters, and these parameters into a "safe" place:!
0x90000-0x901FF, also formerly bootsect block of code once in place, then covered in bumper! before the
system is read out of protected mode.
13 !
1415 ! NOTE! These had better be the same as in bootsect.s!
25 begdata:
26 .bss
27 begbss:
28 .text
2930 entry start
31 start:
3233 ! Ok, the read went well so we get current cursor position and save it for
34 ! Posterity.
! Ok, the whole disk read process is normal, the cursor position will now be saved for future use.
3536
mov ax, # INITSEG ! This is done in bootsect already, but ...! Ds will be set to #INITSEG (0x9000). This
has been bootsect program! Set too, but now is the setup program, Linus felt the
need to re-! Set it.
37 mov ds, ax
38 mov ah, # 0x03 ! Read cursor pos
! BIOS interrupt 0x10 read cursor function number of ah = 0x03 Input:! Bh =
page number
! Returns: ch = scanning start line, cl = end of the scan lines, dh = line number (0x00 is
39 xor bh, bh
40 int 0x10 ! Save it in known place, con_init fetches
41 mov [0], dx ! It from 0x90000.
! A few words to say at the cursor position information stored at 0x90000, console! Will take time to
initialize.
42
--60--
3.4 setup.s program
43 ! Get memory size (extended mem, kB)! Take the following three expanded memory size values (KB).
! Is calling interrupt 0x15, function number ah = 0x88
! Return: ax = starting from at 0x100000 (1M) extended memory size (KB). ! CF if the
error is set, ax = error code.
4445
mov ah, # 0x88
46 int 0x15
47 mov [2], ax ! 0x90002 extended memory present value at (1 word).
4849 ! Get video-card data:
! Below this card for taking the current display mode. ! Call BIOS interrupt 0x10, function returns the number ah = 0x0f:! Ah =
number of characters in the column, al = display mode, bh = the currently displayed page. ! 0x90004 (1 word) holds the current
5051
mov ah, # 0x0f
52 int 0x10
53 mov [4], bx ! Bh = display page
54 mov [6], ax ! Al = video mode, ah = window width
5556 ! Check for EGA / VGA and some config parameters! Check display (EGA / VGA) and taking parameters.
! Call BIOS interrupt 0x10, additional function selection - take way messaging
number:! Ah = 0x12, bl = 0x10 return: bh = display status!!
! (0x00 - 64k, 0x01 - 128k, 0x02 - 192k, 0x03 = 256k) cx = Carter display parameters
(see description after the program)!.
5758
mov ah, # 0x12
59 mov bl, # 0x10
60 int 0x10
61 mov [8], ax ! 0x90008 = ??
62 mov [10], bx ! 0x9000A = display memory installed, 0x9000B = display state (color / monochrome)
! The first address of the first one turned out to be the hard disk parameter table interrupt vector value of 0x41! The second hard disk!
Parameter table immediately after the first one table, the interrupt vector to the value of 0x46 This also points to a second hard disk! Parameter
! Following two BIOS parameter table copying a program related to two hard disk at a first storage 0x90080! Disk table,
6667
mov ax, # 0x0000
68 mov ds, ax
69 lds ! Si, [4 * 0x41] 0x41 takes the value of the interrupt vector, i.e. ds hd0 address parameter table: si
74 rep
75 movsb
76
--61--
3.4 setup.s program
! BIOS interrupt calls using the 0x13 take the disk type function. ! Function
number ah = 0x15;
! Input: dl = drive number (0x8X a hard disk: 0x80 refers to the first hard disk, the second hard disk 0x81) Output:! Ah = type code; 00
- this is not disk, CF is set; 01 - floppy drive, no change-line support;!
02 - is a floppy (or other mobile devices), there are change-line support; 03 - is a hard disk.
9091
mov ax, # 0x01500
92 mov dl, # 0x81
93 int 0x13
94 jc no_disk1
95 cmp ah, # 3 ! Is it hard? (Type = 3?).
96 je is_disk1
97 no_disk1:
98 mov ax, # INITSEG ! 2nd hard disk does not exist, then the first two hard disks table is cleared.
99 mov es, ax
100 mov di, # 0x0090
101 mov cx, # 0x10
102 mov ax, # 0x00
103 rep
104 stosb
105 is_disk1:
106107 ! Now we want to move to protected mode ...! Now we have to enter the protected mode in a ...
108109
cli ! No interrupts allowed!! Not allowed at this interruption.
110111 ! First we move the system to it's rightful place
exceed the maximum length of 0x80000 (512k), i.e. it does not exceed the end memory address 0x90000,! Bootsect they will move to their starting place
0x90000, and the setup is loaded behind it. ! Uses the following program is then moved to the entire system modules 0x00000 position, i.e. from the
0x10000 to 0x8ffff! Memory blocks (512K), the lower end piece to move the position 0x10000 (64K) to the memory.
112
113 mov ax, # 0x0000
114 cld ! 'Direction' = 0, movs moves forward
115 do_move:
116 mov es, ax ! Destination segment es:! Di destination address (initially 0x0000: 0x0)
117 add ax, # 0x1000
118 cmp ax, # 0x9000 !'Ve 64k of code from 0x8000 segment started moving finished?
--62--
3.4 setup.s program
119 jz end_move
120 mov ds, ax ! Source segment ds:! Si source address (initially 0x1000: 0x0)
121 sub di, di
122 sub si, si
123 mov cx, # 0x8000 ! Mobile 0x8000 words (64K bytes).
124 rep
125 movsw
126 jmp do_move
127 128 ! Then we load the segment descriptors
explain in detail in the appendix or after a brief review of the list. Only here for an overview. ! In protected mode before running, we need to set that you need
to use the descriptor table. It should set global! Descriptor tables and interrupt descriptor table. !
! LIDT instructions for loading an interrupt descriptor table (IDT) register, whose operand is 6 bytes, the descriptor table is 0-1 byte length value (bytes);! Is 2-5 bytes
Description the linear 32-bit descriptor table base address (the first address), see the following form! instructions 219-220 and row lines 223-224. Interrupt each entry (8
bytes) pointed out that information when the interrupt occurs! Need to call the code descriptor table, and interrupt vector is somewhat similar, but contain more information. !
! LGDT instructions for loading Global Descriptor Table (GDT) register, which is the same as the operand of the instruction format lidt. Global Descriptor! Each descriptor entry (8
bytes) of the table describes the information in the protected mode code and data segments (blocks). Including segments! Maximum length (16), the linear segment base address
(32), the privilege level of the segment, whether the segment flag in memory, as well as read and write permissions! Some other protected mode operation. See behind the
205-216 line. !
131 mov ax, # SETUPSEG ! Right, forgot this at first. Did not work :-)
132 mov ds, ax ! Ds point to this program (setup) segment.
line 218). 2 bytes long before idt limit table, Table 4 bytes idt! Located base address.
! The above operation is very simple, and now we turn to A20. For a description of the signal line A20 see the program list. ! On a number of ports and the order relates to, a
keyboard interface may be described with reference to the kernel / chr_drv / keyboard.S program.
137
138 call empty_8042 ! Waits for input buffer is empty.
140 out # 0x64, al ! P2 port 8042. 1 bit for the port P2 strobe line A20. ! Data to be written to
0x60 mouth.
141 call empty_8042 ! Waiting for input buffer is empty, to see whether the command is accepted.
142 mov al, # 0xDF ! A20 ON! Parameter selection through address line A20.
145 146 ! Well, that went ok, I hope. Now we have to reprogram the interrupts :-(
--63--
3.4 setup.s program
153
154 mov al, # 0x11 ! Initialization sequence
! 0x11 represents the initialization command start, is ICW1 command word, represent the edges! Edge
trigger, even multi-chip 8259, the last to be sent ICW4 command word.
155 out # 0x20, al ! Send it to 8259A-1! 8259A sent to the master chip.
! Defined below two machine code word is directly represented by the relative jump instruction, from the prolonged action. ! 0xEB directly near jump instruction opcode with a
value of relative displacement bytes. Accordingly branch range is -127 to 127. The CPU! This relative displacement value to the EIP register to form a new valid address. At
this time, an EIP points to the next instruction to be executed. ! Number of CPU clock cycles spent executing is 7-10. 0x00eb represents a jump instruction value is 0, so it
directly! Next instruction is executed. These instructions may provide a total delay time of the CPU clock cycles 14-20. In a corresponding not illustrated as86! Instruction
mnemonics, thus directly using the Linus setup.s and some machine code assembler to represent such instructions. Further,! Number of clock cycles per a NOP is three, and
therefore the delay to achieve the same effect requires 6-7 NOP instructions.
156 . word 0x00eb, 0x00eb ! Jmp $ + 2, jmp $ + 2 ! '$' Indicates the address of the current instruction,
157 out # 0xA0, al ! And to 8259A-2 ! Then sent to the 8259A from the chip.
167 . word 0x00eb, 0x00eb ! See instructions after the code list.
180 181 ! Well, that certainly was not fun :-(. Hopefully it works, and we do not
182 ! Need no steenking BIOS anyway (except for the initial loading :-).
183 ! The BIOS-routine wants lots of unnecessary data, and it's less
--64--
3.4 setup.s program
BIOS routine requires a lot of unnecessary data, and it's not at all disappointed. That was the "real" !! programmers do.
190
! Here is set to enter the 32-bit protected mode. First load machine status word (lmsw-Load Machine Status Word), also known as! Control registers CR0, bit 0 set to 1
191 mov ax, # 0x0001 ! Protected mode (PE) bit! Protected mode bit (PE).
192 lmsw ax ! This is it!! So load machine status word!
193 jmpi 0,8 ! Jmp offset 0 of segment 8 (cs)! Skip to paragraph 8 cs, 0 offset.
! We have moved to a system module 0x00000 place to start, so here is offset address 0. Section herein! 8 has a value in the protected mode segment selector, and
for selecting and descriptor table descriptor table entry and the privilege level required. ! Segment selector is 16 bits (2 bytes); privilege level represented by bits 0-3
0-1 requested, linux operating system uses only two: 0 (system) and 3 (user level)! ; 2 bits for selecting a global descriptor table (0) or a local descriptor table (1);! bit
3-15 is the index of the descriptor table entry, select the first several descriptors indicated. Therefore, the segment selector! 8 (0b0000,0000,0000,1000) indicating a
request privilege level 0, using the first term in the global descriptor table, the indicated! 0 is the base address of the code (see row 209), so here instruction will jump
194 195 ! This routine checks that the keyboard command queue is empty
! Only when the input buffer is empty (Status Register Bit 2 = 0) can be a write command.
198 empty_8042:
199 . word 0x00eb, 0x00eb ! This is the two machine code jump instruction (jump to the next one), is equivalent to the operation delay time and space.
200 in al, # 0x64 ! 8042 status port! Reading AT keyboard controller status register.
201 test al, # 2 ! Is input buffer full?! Test position 2, the input buffer is full?
202 jnz empty_8042 ! Yes - loop
203 ret
204 205 gdt:! described at the beginning of the global descriptor table. A plurality of descriptor table descriptor is 8 bytes long consisting of items.
! Here are three descriptor entries. Item 1 useless (line 206), but must exist. Item 2 is a system code segment! Descriptor (lines 208-211),
item 3 is a system data descriptor (lines 213-216). Each descriptor specifically! Meaning Description see list later.
--65--
3.4 setup.s program
223 . word 0x800 ! Gdt limit = 2048, 256 GDT entries! 2k byte length of the global table, each of 8
bytes as a descriptor entry! Table so the CCP 256 may have.
227 endtext:
228 .data
229 enddata:
230 .bss
231 endbss:
In order to obtain the basic parameters of the machine, this program repeatedly calls BIOS Interrupt, and has been involved with some of the operations of the hardware
port. The following briefly describes the procedure used to BIOS Interrupt calls, and A20 Reasons address line problems were explained on the last-mentioned Intel 32 Bit protected
mode problem.
in setup.s After the execution, the system module system It is moved to a physical address 0x0000 At the beginning, and from 0x90000 The storage system at some basic
data
Temporary global descriptor table
module setup.s
(Gdt)
0x90200
system parameters The original program is
main.c program
head.s program
0x00000
Map 3-3 setup.s After completion of the program memory schematic procedure
--66--
3.4 setup.s program
In this case there are three temporary global descriptor table, the first one ( NULL ) Without the other two are the code segment and data segment descriptors. They point to
the start of the system module, i.e. the physical address 0x0000 Place. So that when setup.s The last instruction is executed ' jmp 0,8 ' (First 193 When the line), it will jump head.s At
the beginning of the program to continue execution. This instruction is' 8' Segment selector is used to specify a desired item descriptors used herein means gdt The code segment. ' 0
Here procedures used in the above description ROM BIOS Video interrupt several sub-function calls.
Video Status:
0x00 - Color mode (the video hardware I / O Port base address 0x3DX );
bh
0x01 - Monochrome mode (the video hardware I / O Port base address 0x3BX ); NOTE: wherein the
settings:
cl
0x00 MDA / HGC ;
--67--
3.4 setup.s program
3.4.3.3 The basic hard disk parameter table ( " INT 0x41 ")
Interrupt vector table, int 0x41 Interrupt vector location ( 4 * 0x41 = 0x0000: 0x0104 ) Not interrupt program address is stored, but the first hard disk basic parameters of
the table. for 100% Compatible BIOS , Here kept the first address array of hard disk parameter table
F000h: E401h . The second hard disk parameter table base address stored in the entry int 0x46 Interrupt vector at the position.
0x03 word The write current begins to decrease cylinder (only PC XT Use, the other for 0)
0x05 word wpcom Before beginning to write pre-compensation cylinder number (multiply 4 )
0x07 byte maximum ECC The burst length (only XT Use, the other for 0 )
Unused
0x08 byte ctl Place 3 If the number of heads greater than 8 The home 1
Place 4 Unused ( 0)
Place 5 If the number of cylinders + 1 FIG bad area at the manufacturer, then set 1
0x09 byte Standard timeout value (only XT Use, the other for 0 )
0x0A byte Formatting timeout value (only XT Use, the other for 0 )
0x0B byte Drive timeout value detector (only XT Use, the other for 0 )
1981 year 8 month, IBM The company first introduced the personal computer IBM PC in use CPU Yes Intel 8088 . In this microcomputer the address line only 20 root( A0 -
A19) . At the time memory RAM Only a few hundred KB Or less 1MB Time, 20 Address lines sufficient to address the memory. Its highest address can be addressed 0xffff: 0xffff , That
is 0x10ffef . For beyond 0x100000 (1MB) The default addressing address to encircle 0x0ffef . when IBM Company 1985 Was introduced AT Machine when using Intel 80286 CPU ,have
twenty four Address lines, the maximum addressable 16MB And with a 8088 Fully compatible real-mode operation mode. However, in the address value exceeds 1MB
When it does not like 8088 Achieved as address for addressing surround. But then there are already some programs that use this mechanism to work around the
address. In order to achieve full compatibility, IBM It invented a switch used to enable or disable 0x100000 Address bit. Because at the time 8042 Just idle port pin on the
keyboard controller (output port P2 Pin P21 ), So we use the pin as the address bit control AND gate. The signal to be known A20 . If it is zero, then the bit 20 And the
Because when the machine is started, the default condition, A20 Address lines is prohibited, so the operating system must use the appropriate method to open it. However,
due to a variety of different compatible chip sets used to do this but it is very troublesome. Thus typically select several control methods.
Correct A20 Common methods of controlling the signal line is provided by the keyboard controller port value. here setup.s program( 138-144
Row) that the use of the typical control. For some other compatible PC can also be used for other ways to do A20 Control line.
--68--
3.4 setup.s program
Some operating systems will A20 And prohibiting the opening part of the standard in the conversion process is performed between a real mode and a protected mode of
operation. Because of the speed controller keyboard is very slow, so you can not use the keyboard controller A20 Line to operate. For this reason the introduction of a
A20 Fast door options ( Fast Gate A20) It uses I / O port 0x92 To deal with A20 A signal line, avoiding the use of slow keyboard controller operation. For free system can
only use the keyboard controller 0x92 Control port, but that port may also be compatible with other devices (such as a graphics chip) on a computer used, resulting in
system errors.
Another way is by reading 0xee Port to open A20 The signal line, the port will write ban A20 A signal line.
8259A A programmable interrupt controller chip, each piece can manage 8 Interrupt sources. By cascading multiple sheet management can constitute up 64 System
interrupt vectors. in PC / AT Series compatible, the use of the two 8259A Chip, a total of management 15 Level interrupt vectors. Which is shown schematically in Figure cascaded 3-4
Fig. From which the chips INT Pin is connected to the main chip IR2 Pin on. the Lord 8259A Chip is the port address 0x20 From chip 0xA0 .
Address 0x20-0x3f A0
CS
CAS2-0
Address 0xA0-0xbf A0
CS
Under the control of the bus controller, the chip may be in a programmed state and an operating state. Programming status is CPU use IN or OUT Instructions 8259A Chip
initial programming state. Once the initial programming, i.e. chips into operation, this device has to respond to the interrupt request by the external apparatus at any time ( IRQ0 -
IRQ15 ). By interrupting the arbitration select the chip will select the current highest priority interrupt request as an interrupt service objects, and by CPU Pin INT Notice CPU The
arrival of external interrupt requests, CPU After the response, the data bus from the chip D7-D0 The current service object programmed interrupt number sent, CPU Thus obtaining
the corresponding interrupt vector values, and execute the interrupt service routine.
in Linux Kernel interrupt number, the hardware interrupt signal from the corresponding int 32 ( 0x20 ) Started ( int 0 - int 31 For
CPU Trap interrupt), that is the interrupt number range int32 - int 47 .
Intel CPU Generally it can operate in two modes, i.e., real address mode and protected mode. Early Intel CPU ( 8088/8086 ) Only work in real mode, you can
only run a single task at a time. for Intel 80386 More chip can also run 32 Under-bit protected mode. In protected mode can support multi-tasking; support 4G Physical
--69--
3.4 setup.s program
While running in protected mode mechanism is understanding Linux An important basis for the kernel, but due to limited space, a brief introduction of their works can
reference the appendix. But still recommended for beginners can be listed on the books after the book, make a careful study. To really understand setup.s The following
procedures and head.s Role of a program, at least first understand the segment selector, and descriptor 80x86 The page table addressing mechanism.
Intel 80386 CPU Have 4 Register control data structure used to locate the segment memory management:
LDTR ( Local Descriptor Table Register ) Local descriptor table register; These registers descriptor table to point GDT with LDT A detailed
IDTR ( Interrupt Descriptor Table Register ) Interrupt Descriptor Table Register; interrupt vector points to this register process (handler) Table ( IDT ) Entry
point. Processing all interrupt entry address information is stored in the descriptor table entry.
Intel 80386 Total control register 4 One, named CR0 , CR1 , CR2 , CR3 . These registers can only be adopted by the system program MOV Instruction
31 twenty three 15 7 0
Reserved
CR1
Reserved
P Reserved E T E M P
G Reserved T S M P E CR0
Control register CR0 Containing the entire system control flags that control or indicating the operating state or condition of the entire system. among them:
PE - Protected Mode open position ( Protection Enable , Bit 0 ). If this bit set, it will cause the processor to start running in protected mode.
MP - Coprocessor existence flag ( Math Present , Bit 1 ). For control WAIT Function instruction to run with the co-processing.
EM - Simulation Control ( Emulation , Bit 2 ). Indicates whether the need for emulation coprocessor.
TS - Task switching ( Task Switch , Bit 3 ). Whenever a task switch processor will set this bit and the test bit coprocessor instructions explained
before.
ET - Extension type ( Extention Type , Bit 4 ). This bit indicates the type of co-processor system contained (YES 80287
still is 80387 ).
PG - Paging operations ( Paging , Bit 31 ). This bit indicates whether the page tables using the linear address into a physical address. See 10 Chapter description of the
CR2 For PG When set page process abnormal operation. CPU Linear address that caused the error will be stored in the register.
CR3 Also in PG When the flag is set to function. This register is CPU Designated page table directory of the current task running used.
--70--
3.5 head.s program
head.s After the program is compiled, it can be connected system The beginning of the front part of the module, which is why called the head ( head)
The reason the program. From here, the kernel is completely run in protected mode. heads.s Previous assembler syntax is different, using the AT & T The assembly language
format, and requires the use GNU of gas with gld2 Compile connections. Therefore, please note the direction of the code are assigned from left to right.
This program is actually an absolute address in memory 0 At the place to start. The function of this program is relatively simple. First, each data segment register is loaded,
reset the interrupt descriptor table idt A total of 256 Item, and each entry point to a dummy only reported error interrupt routine. Then reset the global descriptor table gdt .
Subsequently physical addresses 0 versus 1M SUMMARY compared at the beginning of the detection A20 Whether the address line has really turned on (if not open, it is higher
than in access 1Mb When physical memory address CPU Actual only access ( IP MOD 1Mb ) Content at the address), if detected, they discovered not turned on, then enter an infinite
loop. The program then test PC Machine is comprising a math coprocessor chip ( 80287 , 80387 Or compatible chips), and the control register CR0 Setting the corresponding flag bit.
Then set the paging mechanism to handle memory management, page directory table on the absolute physical address 0 At the beginning (which is also the physical memory
location of the program, this program would therefore be overwritten), placed immediately behind the addressable co 16MB Memory 4 Page table, and set their entries respectively.
Finally return instruction previously placed in the stack / init / main.c Entry address of the program pops up, to run main () program.
1/*
2 * Linux / boot / head.s
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
* Note !!! 32 boot code from the beginning of the absolute address 0x00000000, here also is where the page directory will exist,
2 In the current Linux operating systems, gas and gld, respectively, have been renamed as and ld.
--71--
3.5 head.s program
# Each register name must begin with '%', eax ax represents a 32-bit register.
# Note again !!! here already in the 32-bit mode of operation, so there's not a $ 0x10 0x10 to address each load
# Segment register, it is now in fact, is an offset value in a global descriptor table, or more correctly, is described in a descriptor table entry
# The selectors. For a description of selectors under setup.s See description in the row 193. Here the meaning is requesting $ 0x10
# Privilege level 0 (bits 0-1 = 0), select the global descriptor table (bit 2 = 0), the selection list item 2 (bits 3-15 = 2). It just means that
# Descriptor entry to the data table. (See specific numerical descriptor 212, 213 in front of the line setup.s)
# The following is the meaning of the code: Set ds, es, fs, gs in the selector is configured setup.s data segment (global descriptor table
# The item 2) = 0x10, and the stack is placed in the array region stack_start user_stack point, and then use this program
# New interrupt descriptor table and a global table section described later defined. The new global segment description table and the initial content are substantially setup.s
# Like, only modified into a long segment limit from 16MB 8MB. stack_start defined in kernel / sched.c, 69 rows. It is the point
# An array of pointers to the end of the long user_stack.
19 mov% ax,% ds
20 mov% ax,% es
twenty one mov% ax,% fs
twenty two mov% ax,% gs
twenty three lss _stack_start,% esp # It represents _stack_start ss: esp, set the system stack.
# stack_start defined in kernel / sched.c, 69 rows.
twenty four call setup_idt # Call to set the interrupt descriptor table subroutine.
30 mov% ax,% gs # The code segment register CS had been reloaded in the setup_gdt.
# Since the section of indefinite length into a segment descriptor provided from the Program 16MB 8MB setup.s program (see lines 208-216 setup.s
# And later in the program lines 235-236), so here again performed for all segment register load operation is necessary.
# Further, by using the observation bochs track, if the CS does not loaded again performed, then the executed code segment to the CS 26 rows are not visible
# Section of indefinite length or 8MB. It would appear to be reloaded CS, but in the actual test results show that CS machine has been loaded before.
# A value, and then look at memory address 0x100000 (1M) is whether at this value. If you have been the same, then it has been
# Compare it, that is an infinite loop, crash. A20 represents the address strobe line is not, the result can not use the kernel memory above 1M.
* Note! In the following program, the 486 16-bit should be set to check for write protection in Supervisor mode,
* Since then "verify_area ()" call is not required. 486, you may also want to NE (# 5) is set to
* Error math coprocessor use int 16.
*/
# The following program (43-65) for checking whether there is a math coprocessor chip. The method is a modification of the control register CR0, in
# Performing a coprocessor instruction under the assumption that the presence of the coprocessor, if an error occurs, then it indicates absence of the coprocessor chip,
# You need to set the bit coprocessor emulator EM (bit 2) CR0 is, and there is a flag MP (bit 1) to reset the coprocessor.
--72--
3.5 head.s program
* We rely on the correctness of the ET mark to detect the presence or absence of 287/387.
*/
54 check_x87:
55 fninit
56 fstsw% ax
57 cmpb $ 0,% al
58 je 1f / * No coprocessor: have to set bits * /
59 movl% cr0,% eax # If there is a forward jump to number 1, or rewrite cr0.
60 xorl $ 6,% eax / * Reset MP, set EM * /
61 movl% eax,% cr0
62 ret
63 .align 2 # Here the meaning of ".align 2" refers to the storage boundary alignment adjustment. "2" indicates the adjustments to the address of the last 2 bits are zero,
68 * Setup_idt
69 *
70 * Sets up a idt with 256 entries pointing to
71 * Ignore_int, interrupt gates. It then loads
72 * Idt. Everything that wants to install itself
73 * In the idt-table may do so themselves. Interrupts
74 * Are enabled elsewhere, when we can be relatively
75 * Sure everything is ok. This routine will be over-
76 * Written by the page tables.
77 * / / *
*
* Idt interrupt descriptor table 256 provided with entries, and an interrupt point ignore_int door. Then load interruption
* Descriptor Table Register (with lidt instruction). Really practical to install the door after the break. When we think of all the other places
* Then turn interrupt normal. This subroutine will be overwritten page table.
*/
# Interrupt descriptor table entry is 8 bytes, though, but in a different format in the global table, referred to as gate descriptor
# (Gate Descriptor). 0-1,6-7 its byte offset, byte selectors 2-3, 4-5 bytes are some flags.
78 setup_idt:
79 lea ignore_int,% edx # Ignore_int effective address (offset) value register edx
80 movl $ 0x00080000,% eax # The selector 0x0008 into the upper 16 bits of eax.
81 movw% dx,% ax / * Selector = 0x0008 = cs * /
# Low shift value 16 into the lower 16 bits of eax. At this point eax contains
--73--
3.5 head.s program
93 ret
9495 / *
96 * Setup_gdt
97 *
98 * This routines sets up a new gdt and loads it.
99 * Only two entries are currently built, the same
100 * Ones that were built in init.s. The routine
101 * Is VERY complicated at two whole lines, so this
102 * Rather long comment is certainly needed :-).
103 * This routine will beoverwritten by the page tables.
104 * / / *
* This subroutine is provided a new global descriptor table GDT, and load. At this point only creates two entries with the former
* The same surface. The subroutine only two lines, "very" complex, so of course take so long to annotate ☺ .
* This subroutine will be overwritten page table.
*/
105 setup_gdt:
106 lgdt gdt_descr # Load Global Descriptor Table Register (content has been set, see lines 234-238).
107 ret
108109 / *
110 * I put the kernel page tables right after the page directory,
111 * Using 4 of them to span 16 Mb of physical memory. People with
112 * More than 16MB will have to expand this.
113 * /
/ * Linus kernel memory page tables placed directly after the page directory, the use of four tables addressed 16 Mb of physical memory.
# Normal users or users using the super (U / S bit 2), with or without modification (if dirty) (D 6 bits) and the like; bits 12-31 are the entry
114 .org 0x1000 # Starts at offset 0x1000 is a first page table (offset 0 will be stored at the beginning of the page table directory).
115 pg0:
116117 .org 0x2000
118 pg1:
119
--74--
3.5 head.s program
124 pg3:
125 126 .org 0x5000
# Defined below memory block starting at offset 0x5000.
127 / *
128 * Tmp_floppy_area is used by the floppy-driver when DMA can not
129 * Reach to a buffer-block. It needs to be aligned, so that it is not
130 * On a 64kB border.
131 * /
/ * When the DMA (direct memory access) can not access the buffer block, memory block following tmp_floppy_area
* Available on the floppy disk driver. Its address needs to adjust the alignment, so as not to cross the border 64kB.
*/
132 _tmp_floppy_area:
133 . fill 1024,1,0 # 1024 Total retention, each 1 byte, the value 0 is filled.
134
# Below these stack operation (pushl) used to call /init/main.c program and return preparation.
# The first three values should be 0 stack are envp, argv argc pointer and value, the main () is not used.
# Push operation line 139 is an analog of the first return address stack operation invoked main.c program, if
# When main.c program really quit, it will return to the label L6 continue execution at here, that is an endless loop.
# 140 rows main.c address onto the stack, so that, in the set page process (setup_paging) after the end of
# Performing 'ret' main.c program will address popped off the stack when the return instruction, and to execute the program went main.c.
135 after_page_tables:
136 pushl $ 0 # These are the parameters to main :-)
137 pushl $ 0 # These are the parameters (refer to init / main.c) calls the main program.
138 pushl $ 0 # Wherein the '$' symbol indicates that this is an immediate operand.
147 int_msg:
148 . asciz "Unknown interrupt \ n \ r" # Definition string "Unknown interrupt (carriage return)."
149 .align 2 # 4-byte aligned memory address mode.
150 ignore_int:
151 pushl% eax
152 pushl% ecx
153 pushl% edx
154 push% ds # Please note here! ! ds, es, fs, gs, although other 16-bit registers, but the stack
# In the stack 32 it will still form, i.e., take 4 bytes of stack space.
155 push% es
156 push% fs
157 movl $ 0x10,% eax # Segment selector is set (make ds, es, fs gdt point data segment table).
158 mov% ax,% ds
159 mov% ax,% es
160 mov% ax,% fs
161 pushl $ int_msg # The call printk function parameters pointer (address) stack.
--75--
3.5 head.s program
174 * Setup_paging
175 *
176 * This routine sets up paging by setting the page bit
177 * In cr0. The page tables are set up, identity-mapping
178 * The first 16MB. The pager assumes that no illegal
179 * Addresses are produced (ie> 4Mb on a 4Mb machine).
180 *
181 * NOTE! Although all physical memory should be identity
182 * Mapped by this routine, only the kernel page functions
183 * Use the> 1Mb addresses directly. All "normal" functions
184 * Use just the lower 1Mb, or the local data space, which
185 * Will be mapped to some other place - mm keeps track of
186 * That.
187 *
188 * For those with more memory than 16 Mb - tough luck I've.
189 * Not got it, why should you :-) The source is here. Change
190 * It (Seriously -.. It should not be too difficult Mostly
191 * Change some constants etc. I left it at 16Mb, as my machine
192 * Even can not be extended past that (ok, but it was cheap :-)
193 * I've tried to show which constants to change by having
194 * Some kind of marker at them (search for "16Mb"), but I
195 * Will not guarantee that's all :-()
196 * / / *
* This subroutine cr0 by setting a flag in the control register (PG 31 bits) to start the paging processing functions on the memory,
* And set the contents of each page table entries to map the identity prior to 16 MB of physical memory. Pager assumes no illegal
* Address mapping (i.e., the memory address is greater than 4Mb provided on the machine only 4Mb).
* note! Despite all the physical address should be the identity map of the routine, but only the kernel page management functions can
* Directly> 1Mb of address. All "normal" function uses the address space just below 1Mb, or using local data
* Space, address space will be mapped to some other place to go - mm (memory management program) will manage these things.
* For those guys have more than 16Mb of memory - so lucky, I have not, why do you have ☺ . In the code
* Here, modify it now. (In fact, this is not too difficult. Usually only modify some constants. I set it
* To 16Mb, because my machine again how expansion can not even exceed this limit (of course, my machine is very cheap ☺ ).
* I have to give the place needs to be changed by setting certain flag (search for "16Mb"), but I can not guarantee for these
* Change on the line).
*/
# In the physical memory address 0x0 storage at the beginning of a page directory table and four page table. Page directory table is common to all processes in the system, and
# Here four page table is part of the kernel only. For the new process, the system will apply the page stored in its main memory page table area.
--76--
3.5 head.s program
# As the structure and the structure of the page table entry page directory entry, a 4 bytes. See the description in the row 113 above.
# Each content is: the physical memory page address + sign (here was 7) the current item is mapped.
# The method used is the last item fill by reverse order from the last page of the table. Last entry in a page table page table
# Position 1023 * 4 = 4092. Therefore, the position of the last page of the last item is $ pg3 + 4092.
207 movl $ pg3 + 4092,% edi # Edi last item on the last page.
208 movl $ 0xfff007,% eax / * 16Mb - 4096 + 7 (r / w user, p) * /
# Finally, an address corresponding to the physical memory pages are 0xfff000,
213 xorl% eax,% eax / * Pg_dir is at 0x0000 * / # page directory table at 0x0000.
214 movl% eax,% cr3 / * Cr3 - page directory start * /
# The startup process using paging (PG cr0 the flag, 31 bits)
215 movl% cr0,% eax
216 orl $ 0x80000000,% eax # Add PG flag.
217 movl% eax,% cr0 / * Set paging (PG) bit * /
218 ret / * This also flushes prefetch-queue * /
# After changing the paging process flag transfer instruction requires a refresh instruction prefetch queue, here is the return instruction ret.
# Another function of the return instruction is the address of the main program pop the stack, and the program starts running /init/main.c.
221 .word 0
222 idt_descr: # The next two lines is 6-byte instruction operand lidt: length, base address.
223 . word 256 * 8-1 # idt contains 256 entries
224 . long _idt
225 .align 2
226 .word 0
227 gdt_descr: # The next two lines is 6-byte instruction operand lgdt: length, base address.
228 . word 256 * 8-1 # so does gdt (not that that's any # Not note.
229 . long _gdt # magic number, but it works for me: ^)
230231
. align 3 # 8-byte memory address boundary-aligned manner.
232 _idt: . fill 256,8,0 # idt is uninitialized # 256 items, each 8-byte, fill zero.
--77--
3.5 head.s program
233
# Global table. The first four entries are empty (no), code segment, the data segment descriptors, descriptor system, wherein
# Linux system descriptor no use for it. Back with space for 252 for placing the created task
# Local descriptors (the LDT) and the corresponding task state segment TSS descriptor.
# (0-nul, 1-cs, 2-ds, 3-sys, 4-TSS0, 5-LDT0, 6-TSS1, 7-LDT1, 8-TSS2 etc ...)
234 _gdt: . quad 0x0000000000000000 / * NULL descriptor * /
235 . quad 0x00c09a0000000fff / * 16Mb * / # 0x08, the maximum length of the kernel code segment 16M.
236 . quad 0x00c0920000000fff / * 16Mb * / # 0x10, the maximum length of the kernel data section 16M.
head.s After the implementation of the program, it has officially completed the setup memory page directory and page tables, and re-set the actual use of the kernel
interrupt descriptor table idt And a global descriptor table gdt . It also opened up for the floppy driver 1KB Byte buffer. at this time system
system module
head.s floppy part of the code
The key to understanding this process is to really understand Intel 386 32 Bit protected mode operation mechanism, but also continue to read the rest of the following
procedures are necessary. In order to 8086 CPU compatible, 80x86 Protected mode is more complex to be treated. when CPU When operating in protected mode, it is the real mode
segment address as the protected mode descriptor pointers, this period is stored in the register offset value is a descriptor in the descriptor table. And the base address of the
current descriptor table is stored in the descriptor table register, a global descriptor table register as gdtr , Interrupt Descriptor Table Register door idtr , Loading these registers need
CPU When real mode operating mode, segment registers used to place a memory segment address (such as 0x9000 ), But this time in the segment be addressed 64KB Memory.
But when protected mode operating mode, when an address value is placed in the segment register in the memory is not specified, but rather a descriptor entry in a descriptor
table offset with respect to one of the base address of the descriptor table . at this 8 The length of the 'side' and the segment base address of the segment, and other features
described bit byte segment descriptor contains the linear address. Thus at this time the addressed memory location is coupled with the current code segment base pointer is
performed eip Value. Of course, this time addressed actual physical memory address, the need
--78--
3.5 head.s program
To page through the memory management mechanism in order to get treatment after transformation. in short, 32 Memory addressing in need Guaige Wan-bit protected mode, after
The use of different aspect, the descriptor table is divided into three types: the Global Descriptor Table ( GDT ), Interrupt Descriptor Table ( IDT ) And Local Descriptor Table
( LDT ). when CPU Running in protected mode, a time GDT with IDT Only one each, respectively, by the register GDTR
with IDTR Specify their table base. Local table can have 0-8191 One, which is the base address of the current LDTR Contents of the register specify, using
GDT In a descriptor load, i.e. LDT Also by the GDT Descriptor specified. But at a time it is also only one of which is considered active.
Generally for each task (process) using a LDT . At runtime, the program can use GDT
8 Byte descriptor. Each descriptor entry but the format and GDT Different, wherein the offset value is stored by a corresponding interrupt process ( 0-1 , 6-7
Bytes), which segment selector value ( 2-3 Byte) and flag ( 4-5 byte).
Map 3-7 Yes Linux In the schematic kernel memory descriptor table is used. Figure each task GDT Descriptor occupies two entries. GDT Table LDT0 Descriptor
entry is the first task (process) the local descriptor table descriptor, TSS0 The first task is a task state segment ( TSS ) Descriptor. Each LDT It contains three
descriptors, without first, second task code segment descriptor, the third task data and stack segment descriptor. when DS Segment register is a first task of
the data segment selector, DS: ESI The data in a data segment refers to the task.
segments
data item
(NULL)
LDTR register
GDTR register CS
00000000
--79--
3.6 Summary
In the boot loader bootsect.s will setup.s Code and system Module is loaded into memory, and are themselves and setup.s Code into physical memory 0x90000 with 0x90200
After, the implementation of the right to put the setup program. among them system The header contains a module head.s Code.
setup The main role of the program is to use ROM BIOS The interrupt routine to get some basic parameters of the machine, and save 0x90000
Memory block beginning, the program for later use. Same time system Move down to the physical address of the module 0x00000 At the beginning, so, system
middle head.s Code in the 0x00000 At the beginning of the. Then load the base address of the descriptor table descriptor table register, is performed 32
Running in protected mode ready. Next, the interrupt control hardware reset, and finally by setting the machine control register CR0
And jump to system Module head.s The code at the beginning of the CPU enter 32 Run-bit protected mode.
Head.s The main role of the code is to initialize the preliminary interrupt descriptor table 256 Item gate descriptor, checks A20 Whether the address line has been opened,
if the test system contains a math coprocessor. Then initialize memory page table of contents, prepare work for the paged memory management. Jump to last system Initialization
The main content is described in detail in the next chapter init / main.c Function and role of the program.
--80--
4.1 Overview
4.1 Outline
In the source code of the kernel init / Only one directory main.c file. After performing system boot / Directory head.s Program will be executed after the right to main.c . The
program is not long, but it includes all the work of the kernel initialization. Therefore, when the program needs to read the code with reference to a number of other initialization
part of the program. If we can fully understand all the procedures invoked here, then after reading this chapter you should Linux Kernel have a general understanding.
From the beginning of this chapter, we will be in contact with a large number of C Program code, so the reader has some of the best C Knowledge of the language. The best
one reference book or Brian W. Kernighan with Dennis M. Ritchie Edited " C Programming Language ", the fifth chapter of the book to understand about pointers and arrays, can be
In comments C When the language program, in order to be distinguished from any original program notes, we use the '//' as the start comment statements. Translation
original comments about the use of its mark as a comment. For the header files included in the program (*. h ), Meaning a schematic for explanation purposes only, specific details
main.c Firstly, the previous program setup.s Root file system device number of system parameters and program achieved some memory global variables. These variables
indicate the memory capacity of the main memory starting address of the memory, the system has a high-speed buffer memory and an end address. If you define a virtual disk ( RAMDISK
), The main memory will be reduced appropriately. The entire memory image is shown in Figure 4-1 Fig.
FIG, also part of the cache memory and is deducted ROM BIOS Occupied part. Local disk buffer cache for temporarily storing data blocks and other devices to 1K ( 1024 )
Byte of a data block unit. The main memory area of memory by the memory management module mm
Manage distribution through the paging mechanism to 4K A byte memory page units. Kernel can access the data cache in freedom, but need mm You can use to
Then, the kernel hardware initialization all aspects. It comprises a trap-door, block, character and equipment tty Including artificial settings
--81--
4.2 main.c program
The first task ( task 0 ). After all initialization is complete after setting the interrupt enable flag to enable interrupts, main () Switch to the task 0 Run. In reading these initialization
routine, it is best to follow the procedures to be invoked in-depth look into it, if it could not stand up, temporarily put off, continue to look at the next initialization call. After some
After the completion of the initialization entire kernel, the kernel will perform handover to the right of the user mode (task 0 ), That CPU From 0 Switch to the privileged
class first 3 Privilege level. at this time main.c The main program on the work of the task 0 in. The system then processes the first call to create a function fork () Create a run for init
() The child process. The whole system initialization process shown in Figure 4-2 Fig.
Functional division and allocation cycle to load the root file system Process 2
Process n
Create a process 1 (init) Create a child process Setting the standard IO terminal
Idle execution pause () Wait for the process to exit the Execute shell
The program first to use the system to determine how to allocate physical memory, then calls kernel initialization function of each part separately for memory management,
interrupt handling, block and character devices, process management as well as hard and floppy disk hardware initialization process. After completion of these operations, the
various parts of the system having been in the running state. Since then the program themselves "manual" to the task 0 (process 0 ) Running, and use fork ()
Calls for the first time create a process 1 ( init process). in init The process proceeds with the application environment initialization and execution shell Login procedure. The original
process 0 Scheduling will be performed when the system is idle, then the task 0 Execution only pause () System call, and it will call the dispatch function.
in init Process, if the terminal environment is established, it will then generate a child process (process 2 ), Used to run shell program/ bin / sh . If the child process exits, the
parent process into an infinite loop, continues to generate child processes, and perform once again in this child process shell program
Since the process of creating a new process is fully replicated by way of the parent process code and data segments are implemented, so for the first time fork ()
Creating a new process init When, in order to ensure that the new process does not process the user mode stack 0 The extra information required process 0 Do not use the
user-mode stack before creating the first new process, that required task 0 Do not call the function. Thus, in main.c The main program moves to the task 0 After the execution, the
task 0 The code fork () It can not be called a functional form. The method is implemented using a program gcc Built-in function to perform this form of system calls. See the following
By declare an inline (inline) function, the code can make gcc integrated function to the calling code. This will increase the speed of code execution, because eliminating the
overhead of a function call. In addition, if any of the actual argument is a constant, then the value is known at compile time these may not need to make all the code inline functions
are included and make the code has also been simplified.
--82--
4.2 main.c program
In addition, the task 0 middle pause () Also you need to use the function inline form definition. If the dispatcher the first implementation of the newly created process
init Then pause () The use of function calls will not have any problems. However, the kernel scheduler execution of the parent process (process 0 ) And the child process
init The order is random, creating a init There may be the first scheduling process 0 carried out. therefore pause () We must also use macros to achieve.
for Linux , All tasks are run in user mode, including many system applications, such as shell Procedures, network subsystem programs. Kernel source code lib / Library files
in a directory that is dedicated to providing support functions for the newly created process here.
1/*
2 * Linux / init / main.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #define __LIBRARY__ // definition of the variable is defined to include inline assembly code in unistd.h information.
8 #include <unistd.h> default directory // * .h header files that include /, then the code would not explicitly specify the location.
// if not the UNIX standard header file, you need to specify the directory where, and enclosed in double quotes. // Standard symbolic constants and
the type of file. Symbols and constants defined type, and affirms that the various functions. // If the definition of __LIBRARY__, it also contains the
system call number and inline assembly code syscall0 () and so on.
9 #include <time.h> // Time Type header. The most important definition of the function prototype tm structure and some of the relevant time.
1011 / *
twenty two * /
/*
* We need following these embedded statements - created from the kernel space process (forking) will result in replication (COPY ON WRITE) when not write !!!
* Until the implementation of a execve call. This may cause problems for the stack. The method of treatment is to keep the main after () call fork () use
* Any stack. And therefore can not have function calls - meaning fork also use the embedded code, otherwise we are in () exit from the fork
* Actually only need to pause and fork to use inline to ensure that the main () does not mess up the stack, but we also
* It defines a number of other functions.
*/
// This program will be moved to the user mode (switching to the task 0) after the implementation of fork (), thus avoiding duplication problems in kernel space to write.
// After performing moveto_user_mode (), this program as a task 0 is running. The task is all sub 0 // creates the parent of the process. When creating the first
sub-process, task 0 stack will be copied. It is therefore desirable not to have any main.c run operations on the stack when the task at 0 // environment, so as not to
mess up the stack, so it will not mess up the stack all child processes.
--83--
4.2 main.c program
entry. Article statement is actually int fork () system call to create a process. // syscall0 name of the last parameter 0 means no, 1 means a parameter. See include
twenty four static inline _syscall0 (Int, pause ) // int pause () system call: Pause the process of execution until // receive
a signal.
25 static inline _syscall1 (Int, setup, void *, BIOS) // int setup (void * BIOS) system call, only for
// linux initialization (only to be called in this program).
26 static inline _syscall0 (Int, sync ) // int sync () system call: update the file system.
2728 #include <linux / tty.h>
// tty header file, which defines tty_io, aspects of the serial communication parameters constant.
29 #include <linux / sched.h> // scheduler header file, which defines the task_struct task structure, a first initial tasks
// The data. There are some in the form of a macro definition of the relevant descriptor parameters set and get the // embedded
30 #include <linux / head.h> // head header file defines a simple structure segment descriptors, and several selectors constants.
31 #include <asm / system.h> // system header files. In the form of macro defines a number // description of the setting or modifier /
32 #include <asm / io.h> // io header files. Macro assembler embedding function defined in the form io of port operation.
35 #include <stdarg.h> // standard parameter header. In the form of macro variables defined parameter list. Mainly explained - a
// type (va_list) and three macros (va_start, va_arg and va_end), vsprintf, // vprintf, vfprintf.
36 #include <unistd.h>
37 #include <fcntl.h> // control file header. Operable control descriptor file and constants defined symbols.
38 #include <sys / types.h> // type of header files. System defines the basic data types.
51 extern long rd_init (Long mem_start, int length); // virtual disk initialization (kernel / blk_drv / ramdisk.c, 52)
52 extern long kernel_mktime (Struct tm * tm ); // computing system boot time (seconds).
53 extern long startup_time ; // kernel boot time (boot time) (seconds).
5455 / *
--84--
4.2 main.c program
63 * Yeah, yeah, it's ugly, but I can not find how to do this correctly
64 * And this seems to work. I anybody has more info on the real-time
65 * Clock I'd be interested. Most of this was trial and error, and some
66 * Bios-listing reading. Urghh.
67 * /
/*
* Yes ah, yes ah, following this program very bad, but I do not know how to implement correctly, and if it can run. If there is
* For more information about real-time clock, then I'm interested. These are temptations out, and read some bios program, Oh!
*/
6869 #define CMOS_READ (Addr) ({\
// This macro reads the CMOS real-time clock information.
70 outb_p (0x80 | addr, 0x70); \ // 0x70 is a write port number, 0x80 | addr is the CMOS memory address to be read.
74 #define BCD_TO_BIN (Val) ((val) = ((val) & 15) + ((val) >> 4) * 10)
75
// This subroutine takes CMOS clock and sets the boot time startup_time (seconds). See behind the CMOS memory list.
then re-read all values. Thus the core can be controlled with CMOS timing error in 1 second.
80 do {
81 time .tm_sec = CMOS_READ (0); // current time value in seconds (both BCD code value).
--85--
4.2 main.c program
/ * This is indeed void, and right. The startup procedure (head.s) is so assumed in * / // see head.s few lines
of code line program 136 begins.
106 / *
107 * Interrupts are still disabled. Do necessary setups, then
108 * Enable them
109 * /
/*
* At this point the interrupt is still prohibited, done after the necessary settings to turn it on.
*/
// the following code to save:
// Number ROOT_DEV root device; cache end address buffer_memory_end; // number of machines memory
memory_end; main memory starting address main_memory_start;
110 ROOT_DEV = ORIG_ROOT_DEV ; // ROOT_DEV defined in fs / super.c, 29 lines.
111 drive_info = DRIVE_INFO ; // copy the hard disk parameter table at 0x90080.
112 memory_end = (1 << 20) + ( EXT_MEM_K << 10); // Size = 1Mb memory bytes + extended memory (k) * 1024 bytes.
113 memory_end & = 0xfffff000; // Ignore less than 4Kb (1 pages) amount of memory.
114 if ( memory_end > 16 * 1024 * 1024) // If the memory than 16Mb, 16Mb press count.
115 memory_end = 16 * 1024 * 1024;
116 if ( memory_end > 12 * 1024 * 1024) // If memory> 12Mb, the end of the buffer is set = 4Mb
initialized. At this time, main memory will be reduced. See kernel / blk_drv / ramdisk.c.
134 hd_init (); // initialize hard disk. (Kernel / blk_drv / hd.c, 343)
135 floppy_init (); // initialize the floppy drive. (Kernel / blk_drv / floppy.c, 457)
136 sti (); // initialize all the work is done, enable interrupts.
// The following process parameters set by the stack, using the interrupt return instruction 0 start task execution.
137 move_to_user_mode (); // user mode execution to the next. (Include / asm / system.h, line 1)
138 if (! fork ()) { / * We count on this going ok * /
139 init (); // execute in the new child process (task 1).
140 }
// The following code starts to run as a task to zero.
141 / *
142 * NOTE !! For any other task 'pause ()' would mean we have to get a
143 * Signal to awaken, but task0 is the sole exception (see 'schedule ()')
144 * As task 0 gets activated at every idle moment (when no other tasks
145 * Can run). For task0 'pause ()' just means we go check if some other
--86--
4.2 main.c program
scheduling function will find the system 0 as long as no other tasks can be run without depending on the status of the task // 0.
// generates and outputs the formatted information to the standard output device stdout (1), where on the screen display means. Parameter '* fmt' // specified
output format employed, see various standard C language books. The routine is just one example of how to use vsprintf. // This program uses vsprintf () printbuf
formatted string in a buffer, and () // output the contents of the buffer to the standard equipment write (1 - stdout). vsprintf () function to achieve see kernel /
vsprintf.c.
152 {
153 va_list args;
154 int i;
155
156 va_start (Args, fmt);
157 write (1, printbuf , I = vsprintf ( printbuf , Fmt, args));
158 va_end (Args);
159 return i;
160 }
161 162 static char * argv_rc [] = { "/ bin / sh ", NULL };
// string array parameter when calling the program.
163 static char * envp_rc [] = { " HOME = / ", NULL }; // calling environment string array for executing a program.
sub-process task 0 // 1st created. It first of the first program (shell) will be executed // initialize the environment, and then load the program and execute it.
macro function is defined on the line 25, the corresponding function is sys_setup (), the kernel / blk_drv / hd.c, 71 rows.
// Since this is the first operation to open the file, the file handle number (file descriptor) generated must be 0. The handle is a UNIX-like operating systems // default
console standard input handle stdin. Here it is opened to read and write in order to replicate // generate standard output (write) handles stdout and stderr output handle
stderr.
--87--
4.2 main.c program
175 (Void) dup (0); // copy handle, the handle is generated No. 2 - stderr standard error output device.
// The following buffers and the number of blocks the print total number of bytes, 1024 bytes per block and the number of bytes of free memory area of main memory.
number pid of the child process is returned. So 180-184 sentence is the content of the child process execution. The child closes a handle // 0 (stdin), read-only open the / etc
/ rc file using the execve () function to process itself to replace / bin / sh // program (i.e., shell programs), and then execute / bin / sh program. Brought environment variables
and parameters are given by argv_rc and envp_rc // array. About execve () See fs / exec.c program, 182 line.
// function _exit () error code when the exit 1-- unlicensed operation; 2 - file or directory does not exist.
is the role of three child processes to wait for the end of the parent process. & I is located in a position to return status information. If wait () // return value is not equal to the number of child
186 if (pid> 0)
187 while (pid! = wait (& I))
188 / * Nothing * /; / * Air circulation * /
// If you perform here, on the implementation of the newly created child process has been stopped or terminated. The following loop first and then create a child process, // if error,
the "Create initialization program a child process failed" message and continue. For the child process created by the close of the previous // have also left handle (stdin, stdout,
stderr), to create a new session and set process group number, and then open // / dev / tty0 as stdin again, and copied to stdout and stderr. Execution Systems interpreter / bin / sh
again. But this time the implementation of environmental parameters and an array of the chosen alternative // set (see above lines 165-167). Then the parent process to run again
wait () to wait. // if the child has stopped the execution, on the standard output error message "child process pid to stop the run, return code is i", and then go on ... // continue to
207 }
208 _exit (0); / * NOTE! _Exit, not exit () * / / * Note! Is _exit (), not the exit () * /
// _exit () and exit () are used to terminate a normal function. But _exit () system call directly is a sys_exit, and exit () // is often a function common function library. It
will first perform some cleanup operations, such as call termination handler executes each, close the
--88--
4.2 main.c program
PC Machine CMOS ( complementary metal oxide semiconductor Complementary metal oxide semiconductor) memory is actually powered by a battery 64 or 128 byte RAM Memory
block is part of the system clock of the chip. Some machines have bigger memory capacity.
That 64 Byte CMOS Originally IBM PC-XT Format for saving on the machine clock and date information, is stored in BCD code. Because this information only to 14 Bytes, the
remaining bytes are used to store the number of system configuration data.
CMOS The address space is in addition to the basic address space. Thus does not include executable code. It requires the use of the port
70h, 71h use IN with OUT Instructions to access. In order to read the specified byte offset position, first need to use OUT To port 70h Transmitting specified byte offset value, then IN
This program (lines 70 ) Address of the byte to be read or on a 80h Value is not necessary. Since that time CMOS Memory capacity has not been exceeded 128
Bytes, or 80h The operation is of no effect. The reason why there is such an operation because it was Linus Lack of hand CMOS Aspects of the information, CMOS Clock
and date are offset out his experiments gradually, perhaps he or offset in the experiment on 80h Just made all the right result (and also modify other places), so he
will have a code that this step unnecessary operations. But from 1.0 After release, the operation can be removed (see 1.0 Version of the kernel
drivers / block / hd.c The first 42 Row from the Code). table 4-1 Yes CMOS A profile memory information.
0x00 The current second value (real time clock) 0x11 Retention
0x04 Current hour value (real time clock) 0x15 Base memory (low byte)
0x06 The current day of the week (real time clock) 0x17 Extended Memory (low byte)
0x07 Today's date (real time clock) of the month 0x18 Extended memory (high byte)
0x09 Current year (real time clock) 0x2e Checksum (low byte)
0x0b RTC Status Register B 0x30 1Mb More extended memory (low byte)
0x0c RTC Status Register C 0x31 1Mb More extended memory (high byte)
0x0d RTC Status Register D 0x32 In which the value of the current century
fork It is a system call function. The system calls duplicate the existing process, and create an original process (referred to as the parent process) is almost exactly the
same as a new entry, and execute the same code in the process table, but the new process (referred to herein as the child) It has its own data space and environmental
parameters.
--89--
4.2 main.c program
In the parent process, call fork () Returns the child process identification number PID While in the child fork () Will be returned 0 Value, so, although at this time or in the
same execute a program, but has begun to diverge, each perform their own part of the code. in case fork () Call fails, it will return less than 0 Value. Such as schematic 4-3 Fig.
pid = 0
New process
pid! = 0
The original process pid = fork () The original process
init That program is fork () Return value of a call to distinguish and execute different code segments. The code of the above 179 with 194 Row and the child process is to
determine the sub-execution start process of code block (use execve () System calls other programs are executed here sh ), The
186 with 202 Line is a block of code executed by the parent process.
In the first 2 Chapter we said, the program is an executable file, and the process ( process ) Is an instance of the program execution. In the kernel, each process uses
a different positive integer greater than zero is identified, called the process ID number pid (Porcess ID) . And through a process fork () Call creates one or more child
processes that can form a process group. For example, in the following shell
Each of these commands: cat , grep with more We all belong to a group process.
Process group is a collection of one or more processes. The process is similar, each process has a unique set of process group ID gid ( Group ID ). Process Group gid It is a
positive integer. Each process has a process called group leader, the head of the process is its process ID pid Equal to the process group gid Process. A process by calling setpgid () To
participate in the process of an existing group or create a new process group. The concept of group process has many uses, but the most common is that we send forward the
implementation of the program on the terminal station termination signal (usually by Ctrl-C Key combination), and to terminate all processes throughout the process group. For
example, if we sent a signal to the pipeline termination command, the command three simultaneously terminated.
The session period ( Session , Otherwise known as a session) is a collection of one or more process group. Normally, all programs executed after the user logs belong to a
session period, while their login shell It is the first session of process ( Session leader ). When we Log ( logout Time), we all belong to this session of the process will be terminated.
Function is used to create a new session period. Typically, this function is called by the environment initialization procedure, see next section describes. Figure relationship
--90--
4.3 Environmental initialization
group process
Process
Process
Processes
Processes
SESSION
Process Group
Map 4-4 The relationship between processes, process groups and sessions of
After kernel system initialization is complete, the system also need to perform further initialization work environment based on the specific configuration, in order to really
have some work environments have a common system. In the previous section 183 Rows and 200 Row, init () Function directly started the command interpreter ( shell program)/ bin /
sh , But is not the case in actual systems available. In order to deal with and many people have logged onto the system at the same time the ability to use the system, the system is
usually in here or a similar location, program execution environment initialization system init.c And this program will be based on system / etc / Directory configuration settings file,
create a child process for each terminal device in the system supported a terminal and run the initial setup program in the child process agetty (Collectively, getty program), getty The
program will be displayed on the terminal user login prompt information. " login: . "When a user types a user name later, getty Replace to perform login program. login Program verified
by the user to enter a password after the final call shell Program, and enter shell Interactive working interface. The implementation of the relationship between them Figure 4-5 Fig.
process 1 init
fork ()
agetty
exec ()
login
exec ()
shell
Although these procedures ( init, getty, login, shell ) Does not belong to the core areas, but this effect several programs have some basic understanding of why the kernel
init The main task of the process is based on / etc / rc Set information file, in which the execution command, then according to / etc / inittab Information in the file, login is
allowed for each terminal device using fork () Create a child process, and transported in each sub-process in the newly created
--91--
4.4 Summary
Row agetty 3 ( getty )program. and init Process is called wait () , Wait for the child to enter the end state. Every time it's the end of a child process exits, it will be based on wait () return pid
No. know which child process corresponding to the terminal end, so it will then create a new child process to the corresponding terminal equipment, and re-execute the child
process agetty program. In this way, each of the terminal devices are always allowed to have a corresponding process for its pending.
Under normal operation, init determine agetty We are working with to allow users to log in and receive orphan processes. Isolated processes are those processes whose
fathers process has been completed; in Linux All processes must belong to a single process tree trees, so isolated process must be charged. When the system is closed, init Responsible
for killing all other processes, unmounting all filesystems and stopping the processor work, and it is configured to do any work.
getty The main task of the program is to set the terminal type, attributes, procedures and line speed. It opens and initializes a tty Port, display a message, and waits for the
user to type a user name. The program can only be executed by the superuser. In general, if / etc / issue Text file exists, getty Which will first display the text information, and then
displays the login prompt (for example: plinux login: ), Read the user's login name, type, and execution login program.
login Program is mainly used to require the user to enter a password to log. The user name entered by the user, it is from the password file passwd Acquired the
corresponding user entries, and then call getpass () To show "Password:" Message, read the user types the password, and then use the encryption algorithm type the password is
encrypted, and the password file in the user entry pw_passwd Compare field. If the user types the password several times are invalid, login The program will error code 1 Exit
execution, represents the logon process fails. At this point the parent process (process init )of wait () It will return the exit process pid And therefore creates a child process again
according to the information recorded and perform again for the terminal device in the sub-process agetty Procedure, the process is repeated.
If the user types the password is correct, login It will put the current working directory ( Currend Work Directory ) To modify the password file specified in the user's initial
working directory. And the access to the user terminal equipment modified to read / write and write groups, group setting process
ID . Then initialize the environment variable information using the information obtained, for example, home directory ( HOME = ),in use shell program( SHELL = ), username( USER = with
LOGNAME = ) And default path sequence program execution system ( PATH = ). Then the display / etc / motd file( message-of-the-day Text information) in, and check whether the user
and displays information messages. At last login Program to change the logged in user ID And execute the password file that the user specified in item shell Programs such as bash or
csh Wait.
If the password file / etc / passwd In the user does not specify which items shell Program, the system will use the default / bin / sh program. If the password file does not
specify the user's home directory for the user, then the system will use the default root directory /. related login
Some description of the process execution options and special access restrictions, see Linux System online manual pages ( man 8 login ).
shell Program is a complex command-line interpreter, the program is executed when the user logs in when the system interact. It is the place where users interact with the
computer operation. It gets the information entered by the user, and then execute the command. To the user at the terminal can be shell Interact directly input, you can also use shell
During the logon process login Begin execution shell When brought parameter argv [0] The first character is '-' Indicates that the shell Log in as a shell It is executed. At this
point the shell Program will be based on the character, and the login process to perform some appropriate action. log in shell It will be the first from / etc / profile And file. profile File
(if present) reads and executes the command. If you enter shell When set up ENV
Environment variables, or log in shell of. profile File set up this variable, shell The next step will be to read and execute commands from the file named variable. Therefore, the
user should command each time you log on to be executed. profile File, and put each run shell Command must be executed on ENV Variable specified file. Set up ENV Methods
environment variable is the following statement in your home directory. profile File.
for 0.11 Edition kernel code analysis apparent from the above, the root file system is a MINIX File system, and wherein the document comprises long / etc / rc , / bin
/ sh , / dev / * As well as some of the directory / etc / , / dev / , / bin / , / home / , / home / root / Can form a
--92--
4.4 Summary
From here, to read the following chapters can be main.c Program as a main line, do not need to read in order of chapters. If readers do not understand the mechanisms of
memory paging management, it is recommended to first read the first 10 Chapter contents of memory management.
In order to smoothly understand the following chapters, the author strongly hope that readers this time to review again 32 Mechanism-bit protected mode operation,
carefully read these descriptions provided in the appendix or reference Intel 80x86 About the books, the operating mechanism protected mode completely clear, then continue
reading.
If you successfully read here by order of the chapters, so you Linux System kernel initialization process should already have a general understanding. But you may also
ask the question: "After generating a series of processes, time-sharing system is how to run these processes or how to schedule these processes to run it, ie 'wheel' is how it turn
up??" . The answer is simple: the kernel is through the implementation of sched.c
Program scheduling function schedule () with system_call.s The timing clock interrupt process _ timer_interrupt To operate. Each core set 10 Ms issue a clock interrupt, and interrupt
the process by calling do_timer () Function checks all processes of the current state of implementation of the process to determine the next step.
For the process during execution due to a lack of resources and want to temporarily use a temporary need wait for a while, it will pass in a system call
sleep_on () Class function indirectly call schedule () Function, CPU The right to use voluntarily handed over to another process to use. As the system will run next process which is
entirely schedule () And priority decisions based on the current status of all processes. For the process has been runnable state, when the clock interrupt process determine the time
slice it running has been used up, it will in do_timer () Performing a switching operation process, the process CPU Use rights will be unwillingly deprived give another process to use.
Scheduling Functions schedule () And the clock interrupt process that is one of the themes of the next chapter.
--93--
5.1 Overview
5.1 Outline
linux / kernel / Directory includes a total of 10 More C And language files 2 An assembly language file and a kernel Compiled files in the configuration file management Makefile
. See the list 5-1 Fig. Wherein three subdirectories code comments will be carried out in subsequent sections. This chapter 13 Code file comments. First we have the general
overall introduction to the basic functions of all programs in order to start this 12 Files and functions implemented cross call between them have a general understanding of the
Code files in that directory from the functions can be divided into three categories, one is hardware (abnormal) interrupt handler files, one is the system call service handler
file, the other is the process of scheduling and other common functions file, see Figure 1.5 . We are now the basis of this classification, a more detailed explanation from the function
to achieve.
--95--
5.2 Overall Functional Description
Including two code files: asm.s with traps.c file. asm.s Assembly language used to implement most of the hardware interrupt processing caused by abnormal. and traps.c
Program is to achieve a asm.s Interrupt processing call c function. Several other hardware interrupt handler file system_call.s with mm / page.s Implemented.
Before the user program (process) control to the interrupt handler, CPU The first will be at least 12 Stack information byte is pressed into the interrupt handler. This situation
is a long call (subroutine call inter-segment) Compare alike. CPU Will return code segment selector and the offset value of the address onto the stack. Another comparison between
the segment calls is much like the place 80386 The information on the stack is pressed into the object code, rather than the interrupt stack code. Thus, when an interrupt occurs, the
kernel-mode stack and the object code. In addition, CPU It is always the flag register EFLAGS The contents of the stack. If the priority level changes, such as changing from
CPU Will be the original stack segment and stack pointer value pushed onto the stack code in the interrupt routine. For the contents of the stack having priority change is shown in
Former SS Former SS
CS CS
code
Map 5-1 The contents of the stack when the interrupt occurs
asm.s Mainly related to the code file Intel Reserved Interrupt int0 - int16 The deal, the rest reserved interrupts int17-int31 by Intel The company reserved for future
expansion of use. Each corresponding to the interrupt controller chip IRQ dispatched int32-int47 of 16 A processing program treats in various hardware (e.g., a clock, a keyboard, a
floppy disk, a math co-processor, a hard disk, etc.) initialization procedure. Linux System call interrupts int128 (0x80)
The process will be in kernel / system_call.s Given. DETAILED DESCRIPTION see definition of each interrupt one after the other information in the code comments.
As some of the abnormalities caused by interrupted, CPU Internally generate an error code onto the stack (abort int 8 with int10 - int 14 ), See Figure 5-1 (b) Shown, while
other interrupts, but not with the error code (e.g., zero error and a boundary check error, etc.), and therefore,
asm.s The program will deal with all interrupts and processed separately according to whether they carry the error code. But the process flow remains the same.
--96--
5.2 Overall Functional Description
kernel code segment selector value Note 1: The kernel code selector is
Pop stack error code and then interrupt address is used as the parameter C
Interrupt return
Map 5-2 Hardware interrupt abnormal (fault, trap) caused by the treatment process
Linux The application calls the kernel function is interrupted by a call int 0x80 Conducted, register eax Put the call in number. Therefore, the interrupt is called, the system
call. Implement system calls related documents including system_call.s , fork.c , signal.c , sys.c with exit.c
file.
system_call.s Role of a program similar to the hardware interrupt processing asm.s The role of the program, in addition to the clock interrupt and hard disk, floppy disk
interrupt processing. and fork.c with signal.c One function is similar traps.c The role of the program, the system provides interrupt call C
Handler. fork.c Program provides two C Handler: find_empty_process () with copy_process () . signal.c The program also provides a processing function related to
process signals do_signal () , Is called the system call interrupt processing. It also includes 4 System calls sys_xxx () function.
sys.c with exit.c Program implements a number of other sys_xxx () System call function. These ones sys_xxx () Handler functions are required to call the appropriate system
call, and some are using assembly language, such as sys_execve () ; While others with C Language (for example,
We can be understood in terms of simple naming convention of these functions: usually ' do_ ' The beginning of the interrupt processing call C Function, either the
system call processing functions common to either a system call exclusive; and to ' sys_ ' System call functions that begin with is a dedicated system call handler specified.
E.g, do_signal () Function basically is a function of all system calls to be executed, and do_hd () , do_execve () It is a dedicated system calls C Handler.
schedule.c Program includes kernel calls the most frequent schedule () , sleep_on () with wakeup () Function, the kernel is the core of the scheduler, for performing the
process execution state of the handover or change process. mktime.c Program includes only a kernel function of time mktime () ,only at init / main.c It was called once. panic.c Contains
a panic () Function to display an error message when an error occurs and the kernel is running down. printk.c with vsprintf.c Kernel program information display support, to achieve
--97--
5.3 Makefile file
5.3.1. Features
Compile linux / kernel / Under the program make Configuration file, not including the three subdirectories. The format of the file with the composition of the first chapter list
1.2 Basically the same, while reading can refer to the list 1.2 The relevant comments.
1#
2 # Makefile for the FREAX-kernel.
3#
4 # Note! Dependencies are done automagically by 'make dep', which also
5 # Removes any old dependencies. DO NOT put your own dependencies here
6 # Unless it's something special (ie not a .c file).
7#
# FREAX kernel Makefile file.
#
# note! Dependency is performed by the 'make dep' automatically, which will automatically remove the original dependency information. Do not put your own
# Dependency information on here, unless it is (that is not a message .c file) special file.
# (Linux first name FREAX, the name was later changed to Linux ftp.funet.fi administrator)
89 AR
= Gar # GNU binary file processing program for creating, modifying and extracting files from the archive.
10 AS = Gas # GNU assembler.
11 LD = Gld # The GNU linker.
12 LDFLAGS = -s -x # connection program all the parameters, -s omitted all symbols output file information. -x Delete all local symbols.
# The frame pointers; -fcombine-regs merge register, reduce the use of register class; -finline-functions all Jane
# Single short code embedded function calls the program; -mstring-insns Linus own filling optimization options, will no longer use;
# - nostdinc -I ../ include not using the default path contains the file, and use this specified directory (../include).
16 CPP = Gcc -E -nostdinc -I ../ include
# C pre-processing options. -E C only run pre-treatment, pre-treatment and the results for all of the specified program is output to the standard output C
# Refers gcc CFLAGS using the specified options compiled C code is compiled without stops (-S), thereby generating
# C each corresponding to the input file assembler code file. Assembler default file name is generated by the original file name C
# Remove .c and .s suffix plus. -o represented followed by the name of the output file. Of which $ *. S (or $ @ ) is automatic target variable,
--98--
5.3 Makefile file
35 clean:
36 rm -f core * .o * .a tmp_make keyboard.s
37 for i in * .c; do rm -f `basename $$ i .c`.s; done
38 (Cd chr_drv; make clean) # Enter chr_drv / directory; the implementation of clean rule in the Makefile directory.
39 (Cd blk_drv; make clean)
40 (Cd math; make clean)
41
# Here was the objective or rules for checking dependencies between files. Methods as below:
# Sed string editing program for the Makefile (where that is their own) for processing, the output is deleted Makefile
# File all lines subsequent lines '### Dependencies' (below line 51 from the beginning), and generates tmp_make
# Temporary files (action line 43). Gcc then performs a preprocessing operation on each file in the C kernel / directory.
# - M flag tells the preprocessor output description of the rules relating to each target file, and make compliance with these rules syntax.
# For each source file, the output of preprocessor make a rule, the result is a certain form of the corresponding source file
# File name plus its dependencies - lists all the header files included in the source file. The pretreatment results are added to the temporary
# Tmp_make file, and then copy the temporary file into a new file Makefile.
42 dep:
43 sed '/ \ # \ # \ # Dependencies / q' <Makefile> tmp_make
44 (For i in * .c; do echo -n `echo $$ i | sed '.. S, \ c, \ s,'` ""; \
45 $ (CPP) -M $$ i; done) >> tmp_make
46 cp tmp_make Makefile
47 (Cd chr_drv; make dep) # For the Makefile in chr_drv / directory also do the same process.
48 (Cd blk_drv; make dep)
4950 ### Dependencies:
--99--
5.4 asm.s program
asm.s Assembly program includes most CPU The underlying code is detected fault exception processing, including a math coprocessor ( FPU ) Exception handling. The
program and kernel / traps.c The program has a close relationship. The main approach of the program is to call in the corresponding interrupt handler C Function that displays the
When reading this code with reference to FIG. 5-3 The stack would be helpful to change a schematic view, FIG Each row represents 4 Bytes. Before starting the program,
the stack pointer esp It refers to a column in the interrupt return address (Figure esp0 Office). When that will be called C function
do_divide_error () Or other C After the function address stack, the pointer position is esp1 At this time through the exchange instruction, the address of the function is placed eax Register,
and the original eax The value is saved on the stack. After some registers onto the stack, the stack pointer position esp2 Place. When the official call do_divide_error () Previously,
the program will begin at esp0 The value of the stack pointer onto the stack, put esp3 At, and pop the stack before an interrupt return pointer register by adding 8 I went back to esp2
Place.
- 100 -
5.4 asm.s program
Ss esp Ss esp
cs eip C cs eip
interrupt return address
function address esp0 error_code (eax) C esp0
(EAX) esp1 function addresses esp1
ebx (EBX)
ecx ecx
edx edx
44 ebp 44 ebp
ds ds
es fs es fs
(A) there is no error interrupt call number is love (B) interrupting the wrong number calls pushed onto the stack
Formal call do_divide_error () Before the error code and esp0 The reason is to stack as calls C function
Therefore, in this C Function you can print out the error number and position error. The remaining error exception process program processing procedure described herein
is substantially similar.
1/*
2 * Linux / kernel / asm.s
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
--101--
5.4 asm.s program
11 * The fpu must be properly saved / resored. This has not been tested.
12 * / / *
* asm.s program including most hardware failures (or error) for a bottom-level code. Page exceptions are generated by the memory management program
* mm treatment, it is not here. This program also handles (hope so) fpu due TS- position caused by abnormal,
* Because fpu must correctly save / restore process, which has not been tested.
*/
13
# This code files mainly related to Intel reserved interrupts int0 - int16 treatment of (int17-int31 reserved for future use).
# Here are some statements global function name, its prototype described in traps.c.
14 .globl _divide_error, _debug, _nmi, _int3, _overflow, _bounds, _invalid_op
15 .globl _double_fault, _coprocessor_segment_overrun
16 .globl _invalid_TSS, _segment_not_present, _stack_segment
17 .globl _general_protection, _coprocessor_error, _irq13, _reserved
18
# int0 - (code following meanings see Fig. 5.3 (a)).
# The following error is zero (divide_error) processing code. Label '_divide_error' is actually a C-language function
# Number divide_error () after the name of the compiled module generated corresponding. '_Do_divide_error' function in traps.c.
19 _divide_error:
20 pushl $ _do_divide_error # First, the address of the function that will be called the stack. This program error number is zero.
twenty one no_error_code: # Here is the deal with no error number at the entrance, see line 55 below and the like.
twenty two xchgl% eax, (% esp) # _do_divide_error address eax, eax be exchanged stack.
twenty three pushl% ebx
twenty four pushl% ecx
25 pushl% edx
26 pushl% edi
27 pushl% esi
28 pushl% ebp
29 push% ds # ! ! After the 16-bit segment register stack have 4 bytes.
30 push% es
31 push% fs
32 pushl $ 0 # "Error code" # The error code on the stack.
33 lea 44 (% esp),% edx # Take the original call return address stack pointer location, and pushed onto the stack.
34 pushl% edx
35 movl $ 0x10,% edx # Kernel code data segment selector.
36 mov% dx,% ds
37 mov% dx,% es
38 mov% dx,% fs # '*' Sign indicates the downward Call operand is absolutely nothing to do with the program pointer PC.
--102--
5.4 asm.s program
53 _debug:
54 pushl $ _do_int3 # _do_debug C function pointer stack. Or less the same.
55 jmp no_error_code
56
# int2 - unshielded interrupt calls the entry point.
57 _nmi:
58 pushl $ _do_nmi
59 jmp no_error_code
60
# int3 - with _debug.
61 _int3:
62 pushl $ _do_int3
63 jmp no_error_code
64
# int4 - overflow error interrupt entry point.
65 _overflow:
66 pushl $ _do_overflow
67 jmp no_error_code
68
# int5 - boundary checking error interrupt entry point.
69 _bounds:
70 pushl $ _do_bounds
71 jmp no_error_code
72
# int6 - invalid entry point operation command error interrupts.
73 _invalid_op:
74 pushl $ _do_invalid_op
75 jmp no_error_code
76
# int9 - coprocessor segment exceeds the error interrupt entry point.
77 _coprocessor_segment_overrun:
78 pushl $ _do_coprocessor_segment_overrun
79 jmp no_error_code
80
# int15 - Reserved.
81 _reserved:
82 pushl $ _do_reserved
83 jmp no_error_code
84
# int45 - (= 0x20 + 13) math coprocessor (Coprocessor) issued an interrupt.
# When the coprocessor executing an operator IRQ13 interrupt signal is issued to inform the CPU operation is completed.
85 _irq13:
86 pushl% eax
87 xorb% al,% al # 80387 when performing calculations, CPU execution wait for the completion of its operation.
88 outb% al, $ 0xF0 # By writing 0xF0 port, the interrupt will eliminate BUSY signal a continuation of the CPU, and re
# 80387 processor activation request extension pin PEREQ. The main purpose is to ensure that
# Before proceeding with any instruction 80387, and respond to this interrupt.
89 movb $ 0x20,% al
90 outb% al, $ 0x20 # Control chip sends the EOI (End Of Interrupt) signal 8259 to the main interrupt.
--103--
5.4 asm.s program
95 jmp _coprocessor_error # _coprocessor_error original of this document has now been put
# (Kernel / system_call.s, 131)
96
# The following interrupt when you call the wrong number will be pushed onto the stack after interrupt return address, and therefore also need to return the error number pops up.
# int8 - double error conditions. (The following code meanings see FIG. 5.3 (b)).
97 _double_fault:
98 pushl $ _do_double_fault # C function onto the stack address.
99 error_code:
100 xchgl% eax, 4 (% esp) # error code <->% eax, eax original value is saved on the stack.
101 xchgl% ebx, (% esp) # & Function <->% ebx, ebx original value is saved on the stack.
102 pushl% ecx
103 pushl% edx
104 pushl% edi
105 pushl% esi
106 pushl% ebp
107 push% ds
108 push% es
109 push% fs
110 pushl% eax # Error code # Error number stack.
111 lea 44 (% esp),% eax # Offset # The program returns the value of the stack pointer location address stack.
118 addl $ 8,% esp # Position of the stack pointer points to re-stack placed fs content.
119 pop% fs
120 pop% es
121 pop% ds
122 popl% ebp
123 popl% esi
124 popl% edi
125 popl% edx
126 popl% ecx
127 popl% ebx
128 popl% eax
129 iret
130
# int10 - Invalid Task State Segment (TSS).
131 _invalid_TSS:
132 pushl $ _do_invalid_TSS
133 jmp error_code
134
# int11 - segment does not exist.
135 _segment_not_present:
136 pushl $ _do_segment_not_present
137 jmp error_code
138
# int12 - stack segment error.
139 _stack_segment:
140 pushl $ _do_stack_segment
141 jmp error_code
--104--
5.4 asm.s program
142
# int13 - General Protection error.
143 _general_protection:
144 pushl $ _do_general_protection
145 jmp error_code
146
# int7 - device does not exist (_device_not_available) in (kernel / system_call.s, 148)
# int14 - page fault (_page_fault) in (mm / page.s, 14)
# int16 - Coprocessor Error (_coprocessor_error) in (kernel / system_call.s, 131)
# Clock interrupt int 0x20 (_timer_interrupt) in (kernel / system_call.s, 176)
# System call int 0x80 (_system_call) in (kernel / system_call.s, 80)
Here are Intel Reserved Description interrupt vector specific meaning, see Table 5-1 Fig.
0 Devide error malfunction SIGFPE Generated when the operation of division by zero.
1 Debug Trap When SIGTRAP when performing the step debugging program, the flag register
3 Breakpoint trap SIGTRAP int3 generated by the breakpoint instruction with the same debug process.
5 Bounds check malfunction When outside the effective address causes SIGSEGV addressing.
7 Device not available malfunction SIGSEGV device does not exist, it means coprocessor. In both cases will occur in the
Interrupt: (a) CPU encounters a turn and instruction set, and when the EM. In this
case, the instruction that caused the processing program should simulate exception.
(B) MP and TS are set when the state, CPU encounters a turn back or WAIT
instruction. In this case, the processing program to be updated when necessary, the
overrun
10 Invalid TSS malfunction SIGSEGV TSS found invalid the CPU switches.
11 Segment not present malfunction SIGBUS Description segment identifier is not under.
12 Stack segment malfunction SIGBUS Address does not exist or stack segment beyond the stack segment.
13 General protection malfunction SIGSEGV caused by the operation does not meet the 80386 protection mechanism (privilege level) of.
15 Reserved 16
Coprocessor error malfunction SIGFPE Error signals issued due to the coprocessor issue.
--105--
5.5 traps.c program
traps.c Procedures will include some level code to handle exceptions fault (hardware break) asm.s In the corresponding call C function. Debugging information for
displaying error and error location numbers. one of them die () General function for displaying detailed error information in the interrupt processing, the code of the last initialization
function trap_init () In front init / main.c Are called for a hardware interrupt vector exception handling (the trap door) is initialized and set to allow the interrupt request incoming
1/*
2 * Linux / kernel / traps.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
8 * 'Traps.c' handles hardware traps and faults after we have saved some
9 * State in 'asm.s'. Currently mostly a debugging-aid, will be extended
10 * To mainly kill the offending process (probably by giving it a signal,
11 * But possibly by killing it outright if necessary).
12 * /
/*
* After saving the program in some state asm.s, the present program handles hardware faults and traps. Mainly for debugging purposes,
* After the expansion process was used to kill the damaged (mostly by sending a signal, but also directly kill if necessary).
*/
13 #include <string.h> // string header file. Mainly defines the built-in functions related to operation of the string.
16 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
17 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
18 #include <asm / system.h> // system header files. Set or modify the defined descriptors / interrupt gate or the like embedded macro assembler.
19 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
20 #include <asm / io.h> // input / output header file. Defined hardware port I / O macro assembler statements.
twenty one
// The following statement defines three embedded assembler macro statement function. See the list of embedded compilation of basic grammar or appendix. // Get a byte at address
// parentheses, with a combination of statements (statement braces) may be used as the expression, where the last value of its output is __res.
--106--
5.5 traps.c program
39 int do_exit (Long code); // exit program processing. (Kernel / exit.c, 102)
4041 void page_exception (Void);
// pages abnormal. Actually page_fault (mm / page.s, 14)
42
// The following defines the interrupt handler prototype code (kernel / asm.s or system_call.s) in.
43 void divide_error (Void); // int0 (kernel / asm.s, 19).
44 void debug (Void); // int1 (kernel / asm.s, 53).
45 void nmi (Void); // int2 (kernel / asm.s, 57).
46 void int3 (Void); // int3 (kernel / asm.s, 61).
47 void overflow (Void); // int4 (kernel / asm.s, 65).
48 void bounds (Void); // int5 (kernel / asm.s, 69).
49 void invalid_op (Void); // int6 (kernel / asm.s, 73).
50 void device_not_available (Void); // int7 (kernel / system_call.s, 148).
51 void double_fault (Void); // int8 (kernel / asm.s, 97).
52 void coprocessor_segment_overrun (Void); // int9 (kernel / asm.s, 77).
53 void invalid_TSS (Void); // int10 (kernel / asm.s, 131).
54 void segment_not_present (Void); // int11 (kernel / asm.s, 135).
55 void stack_segment (Void); // int12 (kernel / asm.s, 139).
56 void general_protection (Void); // int13 (kernel / asm.s, 143).
57 void page_fault (Void); // int14 (mm / page.s, 14).
58 void coprocessor_error (Void); // int16 (kernel / system_call.s, 131).
59 void reserved (Void); // int15 (kernel / asm.s, 81).
60 void parallel_interrupt (Void); // int39 (kernel / system_call.s, 280).
61 void irq13 (Void); // int45 coprocessor interrupt processing (kernel / asm.s, 85).
62
// This subroutine is used to print the name of the error interrupt, the length of the error number, EIP calling program, EFLAGS, ESP, fs segment register values, // segment base
address, segment, process ID pid, task number, 10 words section script. If the stack in the user data segment, // print the contents of the stack 16 further bytes.
--107--
5.5 traps.c program
93 {
94 die ( ' general protection ", esp, error_code);
95 }
9697 void do_divide_error (Long esp, long error_code)
98 {
99 die ( ' divide error ", esp, error_code);
100 }
101102 void do_int3 (Long * esp, long error_code,
120 {
121 die ( ' nmi ", esp, error_code);
122 }
123 124 void do_debug (Long esp, long error_code)
125 {
126 die ( ' debug ", esp, error_code);
127 }
--108--
5.5 traps.c program
130 {
131 die ( ' overflow ", esp, error_code);
132 }
133 134 void do_bounds (Long esp, long error_code)
135 {
136 die ( ' bounds ", esp, error_code);
137 }
138139 void do_invalid_op (Long esp, long error_code)
140 {
141 die ( ' invalid operand ", esp, error_code);
142 }
143 144 void do_device_not_available (Long esp, long error_code)
145 {
146 die ( ' device not available ", esp, error_code);
147 }
148 149 void do_coprocessor_segment_overrun (Long esp, long error_code)
150 {
151 die ( ' coprocessor segment overrun ", esp, error_code);
152 }
153 154 void do_invalid_TSS (Long esp, long error_code)
155 {
156 die ( ' invalid TSS ", esp, error_code);
157 }
158 159 void do_segment_not_present (Long esp, long error_code)
160 {
161 die ( ' segment not present ", esp, error_code);
162 }
163 164 void do_stack_segment (Long esp, long error_code)
165 {
166 die ( ' stack segment ", esp, error_code);
167 }
168 169 void do_coprocessor_error (Long esp, long error_code)
170 {
171 if ( last_task_used_math ! = current )
172 return;
173 die ( ' coprocessor error ", esp, error_code);
174 }
175 176 void do_reserved (Long esp, long error_code)
177 {
178 die ( ' reserved (15,17-47) error ", esp, error_code);
179 }
180
--109--
5.5 traps.c program
// Here is an exception (trap) interrupt program initialization routine. Set their interrupt call gate (interrupt vector). The main difference // set_trap_gate () and
set_system_gate () is that the former is set to the privilege level 0, which is 3. So // breakpoint trap interrupt int3, overflow interrupt overflow and boundary error
interrupt bounds can be generated by any program. // These two functions are embedded assembler macro (include / asm / system.h, line 36, line 39).
This section is the first contact to the source program in the kernel C Language embedded assembly code. Since we usually C Preparation process language program
generally will not use the embedded assembler, so here it is necessary to conduct a brief description of its basic format, a detailed description can be found in GNU gcc Manual [ 5] The
first 4 Chapter content ( Extensions to the C Language Family ), Or see reference [ 20]
The basic format with input and output parameters for the embedded assembly:
: Output register
: Input Register
--110--
5.5 traps.c program
Wherein, "compilation of statements" is where you write the assembler instruction; "output register" this indicates when executing the embedded assembly, which registers
for storing the output data. Here, these registers respectively correspond to a C Language expression or a memory address; "input register" represents an input value at the start of
assembly code execution, the register number specified here should be stored, and they correspond to the one C Variable or constant values. Here we use examples to illustrate
Here we present the previous code first twenty two Lines starting with a piece of code as an example to explain in detail, in order to see this code we have been
02 ({\
03 register char __res; \
10 __res;})
This 10 It defines a line of code embedded assembly language macro function. Usually compiled the most convenient way is to put them in the statement within a macro.
Combination with parentheses, statements (statement braces) may be used as the expression, wherein the last variable __ res (First 10
Because the macro statement is necessary to define on one line, hence the use of the backslash '\' connect these statements in a row. This macro definition will be replaced
to the location where the macro name is referenced in the program. The first 1 Line defines the name of the macro, that macro function name get_seg_byte (seg, addr) . The first 3 Line
defines a variable register __ res . The first 4 __ on line asm__ It represents the beginning of the embedded assembler statements. From 4 To row 7 Row 4 article AT & T Compilation of
statements format.
The first 8 Output register row that is, the meaning of the phrase after the end of the run code eax Value represents a register in a __ res
Variables, as an output value of this function, "= a " middle" a " Loading code is called, "=" indicates that this is the output register. The first 9 The bank said in this code starts running
seg Put eax Register, "" indicates the output of the same positions above the same register. and(*( addr))
It represents a memory address offset value. In order to use the address value in the above assembler statements embedded assembler output and input registers predetermined
uniform sequentially numbered sequentially from top to bottom from left to right sequence from the output register "% 0 " Start, were recorded as% 0 ,% 1 , …%9 . Thus, the output of the
register number is% 0 (There is only one output register), the first part of the input register ( "" ( seg)) The number is% 1 Then part number is% 2 . The above first 6 % On line 2 Which
Now let's study 4-7 Role of the code on the line. The first sentence fs The contents of the stack segment register; the second sentence eax The value assigned to segment fs
Segment register; is the third sentence fs: (* (addr)) Bytes into the designated al Register. When executing the compiled statements, output register eax Value will be placed __ res As
the macro function (block structure expression) return value. Very simple, is not it?
Through the above analysis, we know the name of the macro seg On behalf of a specified memory segment value, while addr It indicates a memory address offset amount.
Until now, we should be clear that the function of this program, right! The macro function is a function to take a byte from the memory address specified segment and an offset value.
02 "Rep \ n \ t"
03 "Stol"
--111--
5.5 traps.c program
04 : / * No output register * /
1-3 This is usually three lines of assembler statements for clear direction, repeats the stored value. The first 4 This line illustrates the embedded assembler
output register is not used. The first 5 Meaning the line is: will count-1 The value is loaded into ecx Register (loaded code " c " ), fill_value Loaded into eax in, dest Put edi in.
Why should gcc Compiler to do such a load register values, and not let ourselves do it? because gcc As it can be some register allocation optimization. E.g fill_value Value
may have been eax in. If you are in a loop in it, gcc They may remain in operation throughout the cycle eax , So that you can use less of each cycle in a
movl Statements.
The last line of action is to tell gcc The values of these registers has changed. Very strange, right? However, in gcc Know what you do to get these registers after, this is
indeed capable of gcc Optimizing operational help. table 5-2 It is something you might use the register to load the code and specific meaning.
b Use register ebx o And using the memory address offset value may be added
The following examples are not to let yourself which variables specify which registers, but let gcc Choose for you.
03 : "0" (x));
The first sentence of assembly statement leal (r1, r2,4), r3 Statement indicates r1 + r2 * 4 r3 . This example can be very quickly x Multiply 5 . among them
"0%", "% 1" Refers to gcc Automatically register allocation. Here"% 1" Represents the input value x To put in the register, "% 0 " It represents the output value register. Before the
output of the register number is equal to the code must be added. If the input code register is 0 Or is empty, then use the same corresponding output register. So, if gcc will r Appointed
--112--
5.6 system_call.s program
Note: While executing code, if you do not want the statement to be compiled gcc Optimization and move where you need to asm Add symbol behind
In the following example with a long, if you can understand, it shows that embed assembly code for you, basically no problem. This code is from include / string.h
File removal is strncmp () Implementation of string comparison functions. It should be noted that each line in the "\ n \ t " For gcc Attractive preprocessor output list is
//// string 1 is compared with the first count characters of the string 2. // Parameters: cs - string 1, ct - 2, count
//% 0 - eax (__ res) returns the value,% 1 - edi (cs) string pointer 1,% 2 - esi (ct) string pointer 2,% 3 - ecx (count). // Returns: 1 if the
string> string 2, 1 is returned; string string 2 = 1, 0 is returned; string 1 <string 2, -1 is returned. extern inline int strncmp (Const char * cs, const
char * ct, int count ) {
"Lodsb \ n \ t" // get a string of characters ds 2: [esi] al, and esi ++.
"Scasb \ n \ t" // character string and comparing al es 1 is: [edi], and edi ++.
"Jne 3f \ n \ t" // If not equal, then jump forward to numeral 3.
"Testb %% al, %% al \ n \ t" // The characters are NULL characters?
"Jne 1b \ n" // not, then jump back to number 1, the comparison continues.
"2: \ txorl %% eax, %% eax \ n \ t" // is NULL character, eax cleared (return value).
"Jmp 4f \ n" 4 // jump to the label forward end.
"3: \ tmovl $ 1, %% eax \ n \ t" // eax in the set.
"Jl 4f \ n \ t" // If the previous comparison character string 2 <2 character string, returns an end.
"Negl %% eax \ n" // otherwise eax = -eax, returns a negative value, end.
"4:"
: "= A" (__res): "D" (cs), "S" (ct), "c" ( count ): "Si", "di", "cx");
return __res; // returns the result of the comparison.
This program is mainly for system calls ( system_call) Interrupt int 0x80 Inlet process and a signal detection process (from the code section 80
Start line), while the two systems are given underlying interface functions, respectively, sys_execve with sys_fork . Also lists the similar process coprocessor error ( int 16) The
device does not exist ( int7) The clock interrupt ( int32) , Hard disk interrupt ( int46) , Floppy disk interrupt ( int38) The interrupt handler.
For the soft interrupt ( system_call , coprocessor_error , device_not_available) , The process is basically first calls the corresponding C Handler function to prepare some of the
parameters onto the stack, then call C Treatment of the corresponding functional function, and then the process returns
--113--
5.6 system_call.s program
FIG detected signal level to the current task, a minimum value of the reset signal and the signal processing bitmap. System calls C
Language processing functions are distributed throughout linux Kernel code, the include / linux / sys.h System array of function pointers header file to match.
For hardware interrupt request signal IRQ Sent to interrupt its processing to the interrupt controller chip is the first 8259A Send end hardware interrupt control word
instruction EOI And then call the appropriate C Function handler. For the clock interrupt also signals a bitmap of the current task detection processing.
For system calls ( int 0x80) Interrupt the process, you can see it as a " interface " program. The actual processing of each system call function basically by calling the
This program when you enter, first check eax The function number is valid (within a given range), then save the registers will be used. Linux The default kernel ds,
es Data segment for the kernel, and fs Segments for user data. Followed by a jump address table ( sys_call_table ) Call the appropriate system call C function. in C After the
Next, view the status of implementation of the program of this calling process. If for the above C Function of the operating state or otherwise into the process execution state
from the other state, it has been used up or due to the time slice ( counter == 0 ), The calling process scheduling function schedule ()
( jmp _schedule ). Since the implementation of " jmp _schedule " Previously the return address ret_from_sys_call Stack, so the implementation of End schedule () After eventually
From ret_from_sys_call The label at the beginning of the code to perform some post-processing system calls. The main judge whether the current process is the initial
process 0 It will exit the system calls, interrupts return. According to another code segment or stack and used to determine whether the present call is a system call process
ordinary process, if not then the kernel process (e.g., an initial process 1 ) Or other. Content is also immediately popped off the stack exit system call interrupt. End code is used to
process a call signal calling process system. If the signal process structure bitmap indicates that the process has received the signal, the signal processing function is called do_signal
() .
Finally, the program restore register contents saved, quit the interrupt processing and returns to the calling program. If the signal will be the first time " return " Corresponding
to the signal processing function to perform, and then returns to the calling system_call program of.
--114--
5.6 system_call.s program
register stack
eax = -1
Not Ready
Job status?
Calling schedule () Y
Time slice = 0?
Y
The initial task?
Y
user program?
N
User stack?
Interrupt return
1/*
2 * Linux / kernel / system_call.s
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
--115--
5.6 system_call.s program
* system_call.s file containing the system call (system-call) the underlying processing routine. As some of the code is relatively similar, so
* It also includes a clock interrupt processing (timer-interrupt) handler. Hard disk and floppy disk interrupt handler is here.
*
* Note: The code processing signal (Signal) to identify, are identified after each clock interrupts and system calls. general
* Interrupt signal does not deal with signal recognition, because the system would cause confusion.
*
* The contents of the stack when the call returns ( 'ret_from_system_call') from the system line 19-30 see above.
*/
3233 SIG_CHLD
17 = # Defined SIG_CHLD signal (child process to stop or end).
3435 EAX
= 0x00 # Stack offset position of each register.
36 EBX = 0x04
37 ECX = 0x08
38 EDX = 0x0C
39 FS = 0x10
40 ES = 0x14
41 DS = 0x18
42 EIP = 0x1C
43 CS = 0x20
44 EFLAGS = 0x24
45 OLDESP = 0x28 # When a privilege level change.
46 OLDSS = 0x2C
47
# These are the offset values task structure (the task_struct) variables, see include / linux / sched.h, 77 line begins.
48 state =0 # these are offsets into the task-struct. # process status code
49 counter = 4 # Task running time count (decrement) (ticks), run time slice.
50 priority = 8 // Run priority number. Task starts running counter = priority, the greater the longer run.
51 signal = 12 // bitmap is a signal, each bit represents a signal, the signal value of the bit offset value = +1.
52 sigaction = 16 # MUST be 16 (= len of sigaction) // sigaction structure length must be 16 bytes. // structure array attributes performs signal offset
value, and the operation information corresponding to the signal flag to be performed.
54
--116--
5.6 system_call.s program
# The following definitions sigaction structure offsets, see include / signal.h, line 48 starts.
55 # Offsets within sigaction
56 sa_handler = 0 // handles a signal processing process (descriptor).
6263 / *
64 * Ok, I get parallel printer interrupts while using the floppy for some
65 * Strange reason. Urgel. Now I just ignore them.
66 * / / *
* Well, when you use the floppy drive I get a parallel printer interrupt, very strange. Oh, whatever it is now.
*/
# Defining the entry point.
84 push% es
85 push% fs
86 pushl% edx # Corresponding C language function call parameters ebx, ecx, edx placed in the system call.
91 mov% dx,% es
92 movl $ 0x17,% edx # fs points to local data space
93 mov% dx,% fs # fs is in the local data segment (local descriptor table descriptor data).
# Sentence following meanings operands are: call address = _sys_call_table +% eax * 4. See instructions after the list.
# Corresponding to the C program sys_call_table include / linux / sys.h in which is defined a 72 comprises
# Address array system call table C handler.
94 call _sys_call_table (,% eax, 4)
95 pushl% eax # The system call returns the value of the stack.
96 movl _current,% eax # Take the current task (process) data structure address eax.
--117--
5.6 system_call.s program
# Below 97-100 row view the current running status of the task. If not in the ready state (state is not equal to 0) went to perform scheduling program.
# If the task in the ready state, but its time slice has run out (counter = 0), but also to perform the scheduler.
97 cmpl $ 0, state (% eax) # State
98 jne reschedule
99 cmpl $ 0, counter (% eax) # Counter
100 je reschedule
# The following code performs after returning from a system call C functions, the amount of the signal recognition process.
101 ret_from_sys_call:
# First, determine whether the current task is the initial task task0, is if you do not have to process it semaphore aspects of direct return.
# _task on line 103 corresponding to the task program C [] array, corresponds to a reference direct reference task task [0].
102 movl _current,% eax # task [0] can not have signals
103 cmpl _task,% eax
104 je 3f # Forward (Forward) 3 jump to label.
# By checking the original call selector program code to determine whether the calling program is the kernel task (e.g., task 1). If it is directly
# Exit interrupt. Otherwise, for the average amount of signal processing process need be. Comparison operators choose here the average user to select whether the code segments
# Fu 0x000f (RPL = 3, the local table, the first segment (code segments)). If not, the program exits the interrupt jump.
105 cmpw $ 0x0f, CS (% esp) # was old code segment supervisor?
106 jne 3f
# If the original stack segment selector is not 0x17 (i.e., the original user is not in the stack data segment) is dropped out.
# Signal is then blocked task structure (masking) code, the signal blocking allowed bits, to obtain the minimum value of the signal value, then
# Bitmap original signal corresponding to the signal bit is reset (set to 0), the last one of the signal value as a parameter called do_signal ().
# do_signal () in (kernel / signal.c, 82), which is pushed onto the stack 13 including the parameter information.
109 movl signal (% eax),% ebx # FIG signal bit taken ebx, each one representative of one kind of signal, a total of 32 signals.
110 movl blocked (% eax),% ecx # Take obstruction (masking) signal bitmap ecx.
111 notl% ecx # Each negated.
113 bsfl% ecx,% ecx # From the low (0 bit) to start scanning the bitmap to see whether there was 1,
# If so, the reserved bit ecx offset value (i.e., the first of several 0-31).
114 je 3f # If no signal then jumps forward to exit.
115 btrl% ecx,% ebx # The reset signal (the original signal containing a bitmap EBX).
116 movl% ebx, signal (% eax) # Resave signal bitmap information current-> signal.
117 incl% ecx # The signal is adjusted to 1 starting from the number (1-32).
118 pushl% ecx # Signal values onto the stack as one of the parameters of the call do_signal.
119 call _do_signal # C function call signal processing program (kernel / signal.c, 82)
120 popl% eax # Pop-up signal value.
--118--
5.6 system_call.s program
134 push% fs
135 pushl% edx
136 pushl% ecx
137 pushl% ebx
138 pushl% eax
139 movl $ 0x10,% eax # ds, es is set to point to the kernel data segment.
145 jmp _math_error # C function performed math_error () (kernel / math / math_emulate.c, 37)
146
# # # # int7 - device does not exist or coprocessor is not present (Coprocessor not available).
# If the control register CR0 EM flag is set, then when the CPU executes a command ESC Escape will trigger the interrupt, so that
# This may be an opportunity for the interrupt handler analog ESC Escape command (line 169).
# CR0 of TS flag is set when the CPU executes a task switch. TS may be used to determine when the contents of the coprocessor (context)
# The task being performed and the CPU does not match up. When the CPU is running an escaped discovery TS instruction set, it will lead to the interruption.
# At this point you should restore the coprocessor to perform a new task state (165 lines). See (kernel / sched.c, 77) in FIG.
# The interrupt will be transferred to the final execution continues at label ret_from_sys_call (detect and process signals).
147 .align 2
148 _device_not_available:
149 push% ds
150 push% es
151 push% fs
152 pushl% edx
153 pushl% ecx
154 pushl% ebx
155 pushl% eax
156 movl $ 0x10,% eax # ds, es is set to point to the kernel data segment.
# C function do_timer (long CPL). When the call returns turn to detect and process signals.
--119--
5.6 system_call.s program
175 .align 2
176 _timer_interrupt:
177 push% ds # save ds, es and put kernel data space
178 push% es # into them.% fs is used by _system_call
179 push% fs
180 pushl% edx # we save% eax,% ecx,% edx as gcc does not
181 pushl% ecx # save those across function calls.% ebx
182 pushl% ebx # is saved as we use that in ret_sys_call
183 pushl% eax
184 movl $ 0x10,% eax # ds, es is set to point to the kernel data segment.
# 3 do_timer parameter selector is removed from the current privilege level (0 or 3) pushed onto the stack, as below.
192 movl CS (% esp),% eax
193 andl $ 3,% eax # % Eax is CPL (0 or 3, 0 = supervisor)
194 pushl% eax
# do_timer (CPL) to perform task switching, timing, etc., in kernel / shched.c, 305-line implementation.
195 call _do_timer # 'Do_timer (long CPL)' does everything from
196 addl $ 4,% esp # task switching to accounting ...
197 jmp ret_from_sys_call
198
# # # # This is sys_execve () system call. Take interrupt call program code to call the C function pointer as an argument do_execve ().
# do_execve () in the (fs / exec.c, 182).
199 .align 2
200 _sys_execve:
201 lea EIP (% esp),% eax
202 pushl% eax
203 call _do_execve
204 addl $ 4,% esp # EIP pushed onto the stack when the pressure dropped calls.
205 ret
206
# # # # sys_fork () call for creating a child process is system_call function 2. Prototype in include / linux / sys.h in.
# First call C functions find_empty_process (), to obtain a process ID pid. If the mission returns negative then the current array
# Full. Then call copy_process () replication process.
207 .align 2
208 _sys_fork:
209 call _find_empty_process # Call find_empty_process () (kernel / fork.c, 135).
210 testl% eax,% eax
211 js 1f
212 push% gs
213 pushl% esi
214 pushl% edi
215 pushl% ebp
216 pushl% eax
217 call _copy_process # Call C functions copy_process () (kernel / fork.c, 68).
218 addl $ 20,% esp # Discard all here to push content.
219 1: ret
--120--
5.6 system_call.s program
220
# # # # int 46 - (int 0x2E) hard interrupt handler, in response to a hardware interrupt request IRQ14.
# When the operation is complete or the hard disk will issue this error interrupt signal. (See kernel / blk_drv / hd.c).
# 8259A interrupt controller from the first to the end of the chip transmission hardware interrupt instruction (EOI), then the function takes a pointer variable do_hd placed in edx
# Register juxtaposed do_hd is NULL, then the function determines whether the pointer is NULL edx. If it is empty, then assign points to edx
# unexpected_hd_interrupt (), to display an error message. EOI command is then sent to the master chip 8259A, and the call edx
# Function pointer: read_intr (), write_intr () or unexpected_hd_interrupt ().
221 _hd_interrupt:
222 pushl% eax
223 pushl% ecx
224 pushl% edx
225 push% ds
226 push% es
227 push% fs
228 movl $ 0x10,% eax # ds, es set kernel data segment.
229 mov% ax,% ds
230 mov% ax,% es
231 movl $ 0x17,% eax # fs is set to a local data segment of the calling program.
# Register juxtaposed do_floppy is NULL, then the function determines whether the pointer is NULL eax. Such as empty, then assign points to eax
# unexpected_floppy_interrupt (), to display an error message. Then call the function eax points: rw_interrupt,
# seek_interrupt, recal_interrupt, reset_interrupt or unexpected_floppy_interrupt.
252 _floppy_interrupt:
253 pushl% eax
254 pushl% ecx
255 pushl% edx
256 push% ds
257 push% es
--121--
5.6 system_call.s program
258 push% fs
259 movl $ 0x10,% eax # ds, es set kernel data segment.
260 mov% ax,% ds
261 mov% ax,% es
262 movl $ 0x17,% eax # fs is set to a local data segment of the calling program.
# Into the eax register after the pointer variable do_floppy blank.
268 testl% eax,% eax # Whether the test function pointer = NULL?
280 _parallel_interrupt:
281 pushl% eax
282 movb $ 0x20,% al
283 outb% al, $ 0x20
284 popl% eax
285 iret
Uses AT & T The assembly language syntax. 32 Regular-bit addressing format is as follows:
The calculated position addressing format is: immed32 + basepointer + indexpointer * indexscale
In the application, you do not need to write all of these fields, but immed32 with basepointer Among the must have a presence. Here are some examples.
--122--
5.7 mktime.c program
o in a 8 Recording a byte addressable array of characters specified. among them eax The record number is specified, ebx Are specified character offset address in the
record:
This is only a function of the program mktime () , Only the kernel. Calculated from 1970 year 1 month 1 day 0 When the number of seconds to play after the date of the boot,
as boot time.
1/*
2 * Linux / kernel / mktime.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #include <time.h>
// time header file that defines the data structure of the standard time tm some processing time and function prototypes.
89 / *
* Similarly, the time zone TZ first while ignoring the problem. We are just as simple as possible to deal with the problem. Best to find some public libraries
--123--
5.7 mktime.c program
// following an annual limit, it defines the number of seconds the array at the beginning of each month.
39 };
40
// This function computing power on the day after the number of seconds to play from 1 January 1970 at 0:00, as the start time.
48 res = YEAR * Year + DAY * ((Year + 1) / 4); // number of seconds elapsed time in the multi-+ 1 day each leap year
49 res + = month [ tm -> tm_mon]; // the number of seconds of time, plus the number of seconds in a year when the month.
54 res + = HOUR * tm -> tm_hour; // the number of seconds plus the time of day in the past several hours.
55 res + = MINUTE * tm -> tm_min; // the number of seconds plus time within a few minutes past the hour.
56 res + = tm -> tm_sec; // plus the number of seconds elapsed within 1 minute.
57 return res; // That is equal to the number of seconds elapsed time since 1970.
58 }
59
Basic calculation leap year is: if y Can be 4 Divisible and can not be 100 Divisible, or can be 400 Divisible, then y It is a leap
year.
--124--
5.8 sched.c program
sched.c It is the kernel function of task scheduling procedures, including the basic functions related to scheduling ( sleep_on , wakeup ,
schedule Etc.) and some simple system calls (such as getpid () ). Other Linus In order to facilitate programming, taking into account the timing of the floppy disk drive requires a
program, it will also operate several functions into a floppy disk here.
Code these basic functions, though not long, but some abstract and difficult to understand. Fortunately, There are many textbooks this explanation was very clear, so
you can refer to other books discussion of these functions. The target is focuses on textbooks, books or theory, there is nothing to talk about the ☺ . Here only the scheduling
schedule () The function first of all tasks (processes) to detect any task a wake-up signal has been. The specific method is for each task in the task
array, check alarm timer value alarm . If the task of alarm Time has expired ( alarm <jiffies),
Signal is provided at its bitmap SIGALRM Signal, then clear alarm value. jiffies Is the number of ticks of the system begin to run from the boot ( 10ms /
Tick). in sched.h Defined. If the external signal is blocked there are other signals to remove signals bit map process, and the task in interruptible sleep state ( TASK_INTERRUPTIBL
Followed by a core processing part of the scheduling function. This code is based on the time slice and priority of the process scheduling mechanism to select the task to
be performed next. It first checks the task loop array all tasks, task ready state according to each value of the remaining implementation time counter Select the maximum value of a
task, and using switch_to () To the task switching function. The ready state if the value of all the tasks are equal to zero, represents a time slice at the moment all the tasks have
been run to completion, so the priority value based on the task priority Run time slice value reset each task counter And then re-execute cycle check all task execution time slice
value.
The other two worth mentioning that the function is automatically enter sleep function sleep_on () And wake-up function wake_up () These two functions, although very short,
but better than schedule () Function difficult to understand. Here it is explained by way of illustration. general speaking, sleep_on () The main function is the function when a process
(or task) the requested resource is busy or not in memory temporarily switched out, waiting in the queue waiting for some time. It continues to run when switched back again. Way
into the queue is the use of the function tmp Contact pointer as each is waiting for the task.
Party function involves the task of the three pointer operations: * p , tmp with current * p Waiting queue head pointer, such as the file system memory
i Node i_wait Pointer, the buffer memory operation buffer_wait Pointer or the like; tmp It is a temporary pointer; current It is the current task pointer. For those changes in the pointer
memory, we can use FIG. 5-5 Schematic description. An elongated figure represents a sequence of bytes of memory.
tmp *P current
tmp *P current
When first entered the function, the queue head pointer * p It has been directed (descriptor process) waiting in the task waiting in the queue structure. Of course, at the
beginning of the implementation of the system, no waiting on the queue of waiting tasks. So the image above the original waiting task at the beginning does not exist at this time
--125--
5.8 sched.c program
* P direction NULL . By pointer operations, before calling the scheduler, the queue head pointer to the current task structure, and the function of temporary pointer tmp Pointing to
the original waiting tasks. When so by the action of the temporary pointer, in several processes waiting for the same resources and multiple calls to this function, the program
implicitly construct a waiting queue. D 5-6 We can more easily understand sleep_on () Formation waiting queue function. It is shown when inserted into the third task of the head of
the queue situation.
After insertion waiting queue, sleep_on () Function will be called schedule () Function to execute another process. When the process is awakened and re-execute executes
subsequent statements, than it is to early to enter the queue waiting for a wake-up process.
Wake manipulation functions wake_up () Waiting for the available resources of designated tasks set to the ready state. This function is a generic wakeup function. In some
cases, for example, reading data blocks on the disk, either due to waiting tasks in the queue may be to wake up, and therefore also need to be awakened pointer structure blanking
task. Thus, in the subsequent process goes to sleep but was awakened re-executed sleep_on () When, in the process you do not need to wake up.
There is also a function interruptible_sleep_on () Its structure and sleep_on () Of essentially similar, but prior to the current task scheduling is set to become an interruptible
wait state, and also need to queue on after this task is awakened if there are subsequent waiting tasks, and if so, schedule them to run. In the kernel 0.12 Start, these two functions
are combined, only the status of the task as a parameter to distinguish between the two cases.
When reading the code of this document, preferably while the reference file comprising include / kernel / sched.h Comments in the file, in order to more clearly understand
1/*
2 * Linux / kernel / sched.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
--126--
5.8 sched.c program
* Some simple system calls (such as getpid (), get a field only from the current job).
*/
13 #include <linux / sched.h> // scheduler header file. It defines the task structure task_struct, a first initial tasks
// The data. There are some in the form of a macro definition of the relevant descriptor parameters set and get the // embedded
14 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
15 #include <linux / sys.h> // header file system calls. System containing 72 C function call handler to 'sys_' beginning.
16 #include <linux / fdreg.h> // floppy header. Definitions of parameters comprises the floppy disk controller.
17 #include <asm / system.h> // system header files. Set or modify the defined descriptors / interrupt gate or the like embedded macro assembler.
18 #include <asm / io.h> // io header files. Defined hardware port I / O macro assembler statements.
19 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
2223 #define _S (Nr) (1 << ((nr) -1)) // nr signal takes a binary value of bits in the signal corresponding to the bitmap. Signal number 1-32.
33 i ++;
34 printk ( "% d (of% d) chars free in kernel stack \ n \ r ", i, j);
35 }
36
// display all tasks task number, process ID, process status and the number of free kernel stack bytes (approximately).
4950 extern int timer_interrupt (Void); // clock interrupt handler (kernel / system_call.s, 176).
51 extern int system_call (Void); // system call interrupt handler (kernel / system_call.s, 80).
5253 union task_union {
// define the tasks of the Joint (structural members and task stack array of characters program members).
54 struct task_struct task ; // because the data structure and its kernel mode stack memory a task on the same page
55 char stack [ PAGE_SIZE ]; // in it from the stack segment register ss can be obtained for the data segment selector.
56 };
// each task (process) is running in kernel mode has its own kernel mode stack. Here the definition of the task structure kernel mode stack.
--127--
5.8 sched.c program
5758 static union task_union init_task = { INIT_TASK }; Data (in sched.h) // define the initial task.
61 long startup_time = 0; // boot time. 0:: 0: 0 Number of seconds from the start time of 1970.
62 struct task_struct * current = ( init_task . task ); // this task pointers (initialized to initial tasks).
63 struct task_struct * last_task_used_math = NULL ; // pointer used coprocessor task.
6465 struct task_struct * task [ NR_TASKS ] = {& ( init_task . task )}; // define an array of task pointers.
6667 long user_stack [ PAGE_SIZE >> 2]; // Define the user stack, 4K. Pointer refers to the last item.
68
// This structure is used to set the stack ss: esp (data segment selector, pointer), see head.S, the first 23 rows.
69 struct {
70 long * a;
71 short b;
72 } Stack_start = {& user_stack [ PAGE_SIZE >> 2], 0x10};
73 / *
74 * 'Math_state_restore ()' saves the current math information in the
75 * Old math state array, and gets the new ones from the current task
76 * /
/*
* Saves the current contents of the old coprocessor coprocessor status array, and the current task coprocessor
*/
// when the task is scheduled after exchanged, the function to save the original state of the coprocessor task (context) and resume the execution state of the coprocessor scheduling
77 void math_state_restore ()
78 {
79 if ( last_task_used_math == current ) // If the task is not (on a task is the current task change is returned).
80 return; // Here the meaning of "on a mission" is the task just swapped out.
81 __asm __ ( " fwait "); // before sending the first command to send a coprocessor instruction WAIT.
86 if ( current -> used_math) { // If the current task coprocessor used, then restore its status.
--128--
5.8 sched.c program
100 * NOTE !! Task 0 is the 'idle' task, which gets called when no other
101 * Tasks can run. It can not be killed, and it can not sleep. The 'state'
102 * Information in task [0] is never used.
103 * /
/*
* 'Schedule ()' function is scheduled. This is a very good code! There is no reason to modify it, as it can be in all
* Work environment (such as being able to respond well to treatment boundaries, IO-). Only one thing is worth noting that the signal here
* Handling code.
* note! ! 0 task is idle ( 'idle') mission, only when no other tasks can run call it. It can not be killed
* Dead, I can not sleep. 0 task status information in a 'state' is never used.
*/
104 void schedule (Void)
105 {
106 int i, next, c;
107 struct task_struct ** p; // pointer to a structure pointer tasks.
108109 / * Check alarm, wake up any interruptible tasks that have got a signal * /
/ * Detection alarm (the alarm timer value process), wake-up interrupt tasks have been any signal * /
110
// array of tasks from the last task starts detection alarm.
111 for (p = & LAST_TASK ; P> & FIRST_TASK ; --P)
112 if (* p) {
// If the task by setting the timing value Alarm, and has expired (alarm <jiffies), then in the bitmap is set SIGALRM signal, ie // SIGALARM signal transmission tasks.
Then clear alarm. The default action of this signal is to terminate the process. // jiffies is the number of ticks from system boot since the beginning of (10ms / tick).
& (* P) -> blocked) 'for ignoring signals is blocked, but can not be blocked SIGKILL and SIGSTOP.
117 if (((* p) -> signal & ~ ( _BLOCKABLE & (* P) -> blocked)) &&
118 (* P) -> state == TASK_INTERRUPTIBLE )
119 (* P) -> state = TASK_RUNNING ; // set ready (executable) state.
120 }
121 122 / * This is the scheduler proper: * /
123
124 while (1) {
125 c = -1;
126 next = 0;
127 i = NR_TASKS ;
128 p = & task [ NR_TASKS ];
// This code also starts a loop processing task from the last task of the array, the groove array and skip-free task. // comparing each ready state task counter
(decrement task of running time tick count) value, which value is large, the running time is not long, next to // point to which the task number.
--129--
5.8 sched.c program
// If the comparison result obtained with a counter value greater than 0, the loop is exited 124 line starting, switching tasks (line 141).
the counter = counter / 2 + priority. Here the calculation does not consider the status of the process.
always 0. Therefore, the scheduling function to perform the task 0 when the system is idle. The Task execution 0 // pause () system calls only, and will call this function.
141 switch_to (Next); // switch to the next task number for the task, and run it.
142 }
143
//// pause () system call. Convert the current status of the task to be interrupted wait state, and re-scheduling. // The system call will cause the process to sleep until a
signal is received. This signal is used to terminate the process or the process calls // capture a signal function. Only when a signal is captured, the capture and signal
processing function returns, PAUSE () will return. // At this pause () Returns the value should be -1, and errno is set to EINTR. There is also not fully realized (until
version 0.95).
awakened. This function provides the synchronization mechanism between the process and the interrupt handler. // function arguments * p placed queue head
161 current -> state = TASK_UNINTERRUPTIBLE ; // set the current task uninterruptible wait state.
162 schedule (); // reschedule.
// Only when the task waiting to be awakened, the scheduler just returned here, it means that the process has been explicitly awakened. // Now that everyone is waiting for the same
resources, so when resources are available, it is necessary to wake up all waiting for the resource process. // call the function nesting, nesting will wake up all waiting for the resource
process.
163 if (tmp) // If there are tasks waiting in the front, it can also be set to a ready state (wake up).
--130--
5.8 sched.c program
170
171 if (! p)
172 return;
173 if ( current == & ( init_task . task ))
174 panic ( ' task [0] trying to sleep ");
175 tmp = * p;
176 * P = current ;
177 repeat: current -> state = TASK_INTERRUPTIBLE ;
178 schedule ();
// If there are tasks waiting in the waiting queue, and the queue head pointer is pointing to the current task when the task is not, then the waiting task is set to the ready state //
run and re-executes the scheduler. * P when the pointer points to the current task is not, indicates the current task is put into the // queue, another new task is inserted into the
waiting queue, therefore, should also all other tasks waiting to be set Operating status.
erased. Of course, also need to delete the statement on the 192 line.
183 * P = NULL ;
184 if (tmp)
185 tmp-> state = 0;
186 }
187
// wake specified task * p.
188 void wake_up (Struct task_struct ** p)
189 {
190 if (p && * p) {
191 (** p). state = 0; // set ready (operable) state.
192 * P = NULL ;
193 }
194 }
195 196 /
*
197 * OK, here are some floppy things that should not be in the kernel
198 * Proper. They are here because the floppy needs a timer, and this
199 * Was the easiest way of doing it.
200 * /
/*
* Well, from here is some information about subroutine floppy disk, this should not be placed in the main part of the kernel. Put them here
* Because the floppy needs a clock, and on here is the most convenient way.
*/
// code for this process is a timing floppy lines 201-262. Before reading this code, please look at the instructions later in the chapter about the block
device driver diskette // (floppy.c). A floppy disk or to read a block device driver code in the run. // time unit wherein: 1 tick = 1/100 sec.
// the following storage array pointer to start the process to wait for the floppy motor to normal speed. 0-3 floppy array index corresponding AD.
201 static struct task_struct * wait_motor [4] = { NULL , NULL , NULL , NULL };
// The following granduncle were stored ticks each floppy motor needed to start. Default program start time is 50 ticks (0.5 seconds).
follows: Bits 7-4 @: DA control the startup drive motor. 1-- Start; 0 - off.
--131--
5.8 sched.c program
// Bit 3: 1 - allows DMA and interrupt requests; 0 - Disabling DMA and interrupt requests. // Bit 2: 1 -
boot diskette controller; 0 - reset the floppy disk controller. // bits 1-0: 00--11 for selecting a control
floppy AD.
204 unsigned char current_DOR = 0x0C; // set the initial value here is: allow DMA and interrupt requests, started FDC.
205
// specify the floppy drive to start the waiting time required for the normal operation state. //
211 if (nr> 3)
212 panic ( ' floppy_on: nr> 3 "); // The system has up to four floppy drive.
// first pre-set specified time (100 seconds) floppy nr need to go through before stalling. Then take the current value of the register DOR // mask in a temporary
213 moff_timer [Nr] = 10000; / * 100 s = very big :-) * / // Stop duration.
214 cli (); / * Use floppy_off to turn it off * /
215 mask | = current_DOR ;
// If no floppy drive is selected, the other first reset select bit floppy, then set selection bits specify the floppy drive.
216 if (! selected ) {
217 mask & = 0xFC;
218 mask | = nr;
219 }
// if the current value of the motor with the requirements of the different digital output register, the output ports to the new FDC digital value (mask), and if the requirements of the motor to start //
not yet started, the set value of the corresponding timer is started floppy (HZ / 2 = 0.5 seconds, or 50 ticks). // if already started, and then set the timing to start the two ticks, satisfy the following
do_floppy_timer () after decreasing in the first determination requirements. // the timing required to perform this code. Thereafter the digital output register updating the current variable
current_DOR.
230 }
231
// waits for a specified period of time required to start the motor floppy drive, and then return.
// Set the floppy specified motor starting speed normally required to delay and wait for sleep. In the timer interrupt process will determine the delay value has been declining // set
here. When the delay expires, it will wake up the waiting process here.
235 while ( ticks_to_floppy_on (Nr)) // If the motor actuation timing has not arrived yet, the current process has been set
236 sleep_on (Nr + wait_motor ); // is not interrupted sleep and wait for the motor to run into the queue.
237 sti (); // open the interruption.
238 }
239
// set the floppy motor is stopped to close the corresponding timer (3 seconds).
// Without the use of the function explicitly close the specified floppy motor, the motor will be shut down after the open 100 seconds.
--132--
5.8 sched.c program
the system through a tick (10ms) will be called every time the motor is turned on at any time to update or stop timer //'s value. If one of the timing to stop the motor, the motor
257 current_DOR & = ~ Mask; // reset respective motor start bit, and
259 } Else
260 moff_timer [I] -; // motor stall countdown timer.
261 }
262 }
263 264 #define TIME_REQUESTS 64
// can have up to 64 timer list (64 tasks).
265
// timer list structure and timer arrays.
266 static struct timer_list {
267 long jiffies ; // timer ticks.
268 void (* fn) (); // timer handler.
269 struct timer_list * Next; // next timer.
270 } timer_list [ TIME_REQUESTS ], * next_timer = NULL ;
271
// add a timer. Input parameter values for the designated timing (ticks) and the appropriate handler pointer. // floppy disk driver
(floppy.c) performed by using the function to activate or deactivate the delay operation of the motor. // jiffies - ticks in terms of 10
--133--
5.8 sched.c program
of the first term has expired can be. [[?? This program does not seem thoughtful. If the newly inserted timer values // <original header when a timer value, the timer value
291 while (p-> next && p-> next-> jiffies <P-> jiffies ) {
292 p-> jiffies - = p-> next-> jiffies ;
293 fn = p-> fn;
294 p-> fn = p-> next-> fn;
295 p-> next-> fn = fn;
296 jiffies = P-> jiffies ;
297 p-> jiffies = P-> next-> jiffies ;
298 p-> next-> jiffies = jiffies ;
299 p = p-> next;
300 }
301 }
302 sti ();
303 }
304
//// clock interrupt handler function C, _timer_interrupt in kernel / system_call.s in (row 176) is called. // parameter cpl is the current privilege level 0 or
3,0 represents the kernel code execution.
// for a due process execution time slice is used up, the task switching. And perform a timed update work.
305 void do_timer (Long cpl)
306 {
307 extern int beepcount ; // speaker sound time ticks (kernel / chr_drv / console.c, 697)
308 extern void sysbeepstop (Void); // close the speaker (kernel / chr_drv / console.c, 691)
309
// If the count number to the utterance, sound is turned off. (0x61 port to send commands, reset bit 0 and 1. Bit 0 counter operation control // 2
310 if ( beepcount )
311 if (! - beepcount )
312 sysbeepstop ();
313
// If the current privilege level (cpl) to 0 (the highest representation is the core program of work), then the kernel run-time stime increments; // [Linus kernel
program referred to as super user (supervisor) program, see system_call .s, English comments] on line 193 // If cpl> 0, it means that the user program is usually
314 if (cpl)
315 current -> utime ++;
316 else
317 current -> stime ++;
318
// If a user timer is present, then the value of the list of the first timer is decremented by one. If equal to 0, // call the corresponding processing program and the processing
319 if ( next_timer ) { // next_timer a timer list head pointer (see line 270).
320 next_timer -> jiffies -;
--134--
5.8 sched.c program
// If the parameter seconds> 0, then set the new value and return to the original timing time value. Otherwise it returns 0.
--135--
5.8 sched.c program
367
// get the group number gid.
405 lldt (0); // local descriptor table loaded into the local descriptor table register.
// Note! ! GDT is loaded in the corresponding descriptor LDT selector to ldtr. Only clear to load this time, after loading new tasks // LDT, TSS is based on
--136--
5.8 sched.c program
408 outb ( LATCH >> 8, 0x40); / * MSB * / // timer value of the high byte.
// set the clock interrupt handler handler (setting the clock interrupt gate).
For access to programming 4 Ports, respectively corresponding to one or more registers. for 1.2M There are a number of floppy disk controller port.
Digital output port (port number control) is a 8 Bit register which controls the drive motor is turned on, the drive selection, start / reset FDC As well as enable / disable DMA
FDC The status register is a main 8 Bit register is used to reflect the floppy disk controller FDC And a floppy disk drive FDD The basic state. Typically, CPU to FDC Before
sending a command or from FDC Before obtaining the operation result, the master must read the status register bits, to discriminate the current FDC Data register is ready and
FDC A plurality of registers corresponding to the data port (write only type parameter register and the command register, read-only result register), but any one time, only
one appears in the data port register 0x3f5 . When accessing the write-only register, the main state control DIO Direction bit must be 0 ( CPU FDC ), And vice versa when the read
access type register. When reading the results only in FDC After reading the results considered busy, usually resulting data Up 7 Bytes.
The floppy disk controller can accept a total of 15 Command. Each command through three stages: the command phase, implementation phase and the results stage.
Command stage CPU to FDC Send command byte and parameter bytes. The first byte of each command byte is always the command (command code). Thereafter followed 0--8 Byte
parameters.
The implementation phase is FDC Perform the operation specified command. In the implementation phase CPU That without intervention, usually through FDC It issues an
interrupt request to know the end of the command execution. in case CPU dispatched FDC Command is transmitted data, FDC You can interrupt or DMA Conducted. Interrupt each
transfer 1 byte. DMA Way in DMA Controller Management, FDC Transmitting data to and from memory until all of the data transferred. at this time DMA Controller will signal the
transfer byte count termination FDC Finally, the FDC Issues an interrupt request signal inform CPU The implementation phase is completed.
The result is a stage CPU Read FDC Data register return value, to thereby obtain FDC The results of the command execution. Return result data length 0--7 byte. For data
command does not return results, should the FDC Interrupt Status command transmission detecting operation state is obtained.
--137--
5.9 signal.c program
signal.c All procedures involving the kernel functions relating to signal processing. in UNIX System, the signal is a "software interrupt" mechanism. There are many more
complex procedures will be used to signal. Signaling mechanism provides a method for processing asynchronous events. For example, a user at the terminal keyboard type ctrl-C Key
combination to terminate execution of a program. This operation will produce a SIGINT ( SIGnal INTerrupt ) Signal, and is sent to the process currently executing in the foreground;
when a process is provided when an alarm clock expires, the system will send a process to SIGALRM Signal; hardware when an exception occurs, the system will send the
appropriate signal to the process being performed. In addition, a process can send a signal to another process. For example, kill () Function to send the child process to terminate the
The signal processing mechanism at an early UNIX Systems already have, but those early UNIX Signal processing kernel method is not so reliable. Signal may be lost,
but also in dealing with critical area code signal process is sometimes difficult to close a specified later
POSIX It provides a reliable method for processing a signal. To maintain compatibility, or this program provides two methods of processing signals.
Usually an unsigned long integer ( 32 Bit position) represents the various signals. So up to represent 32 Different signals. Excerpts Linux Kernel, defined twenty two Different
signals. among them 20 Kinds of signals are POSIX.1 All signals specified in the standard, additional 2 Species are Linux Dedicated signal: SIGUNUSED (Undefined) and SIGSTKFLT
(Stack error), the former means the system can not currently support all other signal types. This twenty two Specific names and definitions of types of signals may signal a list of
For the process, when a signal is received, it may be composed of three different process or operation mode.
1. Ignore the signal. Most signals can be ignored process. But there are two signals can not afford to ignore: SIGKILL with SIGSTOP . Can not
The reason being ignored is to provide a method for determining the super-user to terminate or stop any processes specified. Further, if the signal is ignored certain
hardware exception is generated (e.g., 0 In addition), the act or state of the process may become the unknowable.
2. Capture the signal. To do this, we must first tell the kernel to call our custom signal when the specified signal generation
Handler. In this handler, we can do anything, of course, can not do anything, play the same role in ignoring the signal. An example of a custom signal
processing function to capture the signal is: if we some temporary files created during program execution, then we can define a function to capture SIGTERM (Terminate
execution) signal and do some work to clean up temporary files in the function. SIGTERM Signal is kill The default command signal sent.
3. Default action. Each kernel signals to provide a default action. Usually these default action is to terminate the process of execution. Ginseng
This procedure gives a blocking signal is provided and the process of obtaining the code (mask) system calls sys_ssetmask () with sys_sgetmask () The signal processing
system calls sys_singal () (I.e., conventional signal processing functions signal () ), System operations modify the process when it receives a specific signal taken calls sys_sigaction
() ( Both reliable signal processing function sigaction ()) And interrupt functions in the system call handler for processing signals do_signal () . For the operation of the signal
transmission signal as a function send_sig () And notifies the parent process functions tell_father () It was included in another program ( exit.c )in. Name prefix program sig They are
signal () with sigaction () More similar function, signal changes are the original handler ( handler, Or handler called). but signal ()
It is the way the core operation of the conventional signal processing, in some special time may result in loss of signal.
in include / signal.h The first header 55 Row, signal () Function prototype is declared as follows:
This one signal () Function with two parameters. Need to capture a specified signal signr ; Another new signal processing function pointer (new signal handler) void (*
handler) (int) . New signal handler is a function having no return value and a pointer to an integer parameter, the integer parameter when a specified signal generating passed to
the kernel handler. signal () Function returns the original signal processing
--138--
5.9 signal.c program
Handle, the handle returned is also a non-return value and having a function pointer integer parameter. And it is performed after once invoked, the signal handler will be reset to
in include / signal.h File (first 45 Since the line), the default handler SIG_DFL And ignored handler SIG_IGN It is defined as:
Respectively represent no return value of function pointers, and signal () The same requirements as a function of the second parameter. Pointer values are 0 with 1 . Logically, these
two pointer value is a function of the actual value of the address of the program impossible. Thus, in signal () The function can be two special pointer value to determine whether to
use the default or ignore the signal handler to signal processing (of course SIGTERM with SIGSTOP Can not be ignored). See the list below for the first program 94-98 Processing
lines.
When a program is executed, the system will be provided in a manner to process all signals SIG_DFL or SIG_IGN . In addition, when the program
fork () When a child process, the child process will inherit the parent process of signal processing (signal mask). Thus the parent of the set signal processing mode and equally
In order to continuously capture a specified signal, signal () Examples of commonly used manner following functions.
main () {
signal (SIGINT, sig_handler); // main program set up your own signal handler.
. . .
}
signal () Function unreliable because when the signal has occurred into the signal processing functions in their own setting, but once again before re-set your own
handler, it is possible this time there is another signal generator. But this time the system has been set to default values handler. Therefore, it may cause loss of signal.
sigaction () Function uses sigaction Data structure to hold the information specified signal, which is a reliable mechanism for signal processing core, which allows us to
easily view or modify the specified signal handler. This function is signal () A superset of the function. This function
int sigaction (int sig, struct sigaction * act, struct sigaction * oldact);
Where the parameter sig We need to view or modify the signal that the signal handler, the latter two parameters are sigaction Pointer to a structure. When parameter act Pointer
not NULL When you can act Modify the behavior of the information specified signal structure. when oldact Is not empty, the kernel will return the original signal information is
48 struct sigaction {
49 void (* sa_handler) (int); // signal handler.
50 sigset_t sa_mask; // mask signal, a signal can block the specified set.
51 int sa_flags; // signal option flags.
52 void (* sa_restorer) (void); // signal recovery function pointer (internal system).
53 };
--139--
5.9 signal.c program
When the modification of a signal processing method, if the handler sa_handler Not the default handler SIG_DFL Or ignore handler SIG_IGN , Then sa_handler Handler
can be invoked before, sa_mask Field specifies a set of signals to process the signal mask bitmap needs to be added to. If the signal handler returns, the system will return to
the process of the original signal mask bitmap. So that when a signal handler is called, we can block some signals specify. When the signal handler is invoked, the new bitmap
mask signal automatically the transmitted signal to include a current blocking continues to send the signal. During the process so we can ensure a specified signal blocking
without them lost with a signal until the process is completed. In addition, but on many occasions during a blocking signal is usually kept only one of its examples, that when
unblocking blocked for more of the same signal will once again call the signal handler. After we changed a signal handler, unless changed again, or else has been using the
signal () Function will revert to its default handler after the end of a signal handler.
sigaction Structure sa_flags Other options for specifying processing of the signals, the definition of these options, see
sigaction The last field in the structure and sys_signal () Function parameters restorer It is a function pointer. When compiled by the linker Libc Library provides for
user-mode stack to clean up after the signal handler, and restores the system call is stored in eax The return value, see details below.
do_signal () Function is a kernel system calls ( int 0x80) The interrupt handler to signal preprocessor. When each call to process the system call, if the process signal has
been received, then the function will be the handler (i.e., corresponding to the signal processing function) signal into the user program stack. In this way, the current system will be
executed after the call returns immediately signal the end of the handle of the program, and then continue to execute the user program, see Figure 5-7 Fig.
in do_signal () Before the function parameters of the signal processing program into the user stack, will extend down the first user program stack pointer longs Longword
(see procedure below 106 Line), and then the insertion of the relevant parameters wherein, referring to FIG. 5-8 Fig. due to
do_signal () Function from 104 The line of code begins more difficult to understand, here we will be described in detail.
When the user invokes the system call just enter the kernel, the kernel mode stack of the process will be made CPU FIG Autopush 5-8 Contents shown in, namely: user
program SS with ESP And the next instruction in the user program execution point position CS with EIP . Call functions processed the specified system and is ready to call do_signal
() When (ie, system_call.s program 118 After the line), the contents of kernel mode stack see 5-9 As shown in the left. therefore do_signal () Parameter is the content of the stack in
--140--
5.9 signal.c program
Former SS
kernel
Original mode
ESP
Press-fitting direction
EFLAGS
CS EIP
long
Original ss
kernel
Original mode
esp
eflags
old_eip eflags
User program edx ecx eax (call
cs eip
ds [blocked] signal
ecx ebx
Press-fitting direction
eax
signal
The signal processing
signr
Map 5-9 do_signal () Function modifies the specific user mode stack of the process
The default handler two signals processed ( SIG_IGN with SIG_DFL After), if the user-defined signal processing (signal handler sa_handler ), From 104 Line
from do_signal () Begin to handle user-defined into the user mode stack. It returns the first kernel mode Central user program execution stack pointer points eip Save
sa_handler , I.e. so that the kernel mode FIG stack eip direction sa_handler . Next, by storing kernel mode "original esp "minus longs Value, the user-mode stack extends
downwardly 7 or 8 Long word space. Finally, the copy number of the register contents on the kernel stack into this space, see on the right in FIG.
Total to the user mode stack placed 7 To 8 Values, we are now well placed to explain why the meaning of these values these values.
old_eip That is, the return address of the original user program is in the kernel stack eip Before being replaced to a signal handler address retained.
eflags , edx with ecx The original value before the user program in system call, basically calling parameters of the system call, after the system call returns still need to restore these
register values of the user program. eax The return value is stored in the system call. If the signal processing also allows the receipt itself is also stored on the stack has blocked
the process code blocked . The next one is the signal signr value.
--141--
5.9 signal.c program
The last one is a pointer to a function of signal activity recovery sa_restorer . This recovery function is not set by the user, as defined in the user signal () It provides a signal
only when the function value signr And a signal handler handler .
Here is SIGINT A simple example of a signal provided from the signal handler definition of the default, press Ctrl-C Key combination will produce SIGINT signal.
# include <signal.h>
# include <stdio.h>
# include <unistd.h>
int main () {
(Void) signal (SIGINT, handler); // Set the user defined SIGINT signal handler.
while (1) {
printf ( "Signal test \ n."); sleep (1);
// wait one second.
}}
Wherein the signal processing function handler () Will signal SIGINT It is called to perform the event. The first function outputs a message, will then SIGINT Set to the
default signal processing signal handler. Therefore, in the second press Ctrl-C Key combination, SIG_DFL The program will end run.
Then sa_restorer This function is coming from? In fact, it is provided by the library functions in Libc Function library has its function, is defined as follows:
. globl ____sig_restore
. globl ____masksig_restore
# If not blocked, use the restorer function ____sig_restore:
popl% eax
popl% ecx
popl% edx popfl
ret
--142--
5.9 signal.c program
The main role of this function is to signal processing procedure after the recovery after the return value and the user program execution system call number register
contents, and clear signal value as a signal processing program parameters signr . When the compiler user-defined signal processing procedure, the compiler will function into the
user program. This function is responsible for cleaning up the signal handler after the implementation of the recovery program user register values and the system call returns a
value, it does not seem to run through the signal handler, but returned directly from the system call.
Finally, explain the process execution. in do_signel () After the execution, system_call.s Will put kernel mode processes eip All of the following values popped off the stack. In
the implementation of the iret After instruction, CPU It will be the kernel mode stack cs: eip , eflags as well as ss: esp Pop, back to the user mode to execute the program. due to eip Directing
signal has been replaced with a handle, and therefore, will perform at the moment that is a user-defined signal processing procedure immediately. In the signal processing program
executed, by ret instruction, CPU We will hand over control to sa_restorer He points to restore the program to execute. and sa_restorer User mode program to do some clean-up
stack, i.e. skip signal value on the stack signr And the return value of the system call eax And register ecx , edx And a flag register eflags . After a full recovery and system calls each
register CPU status. Finally, sa_restorer of ret Instruction pops the original user program eip (Ie on the stack old_eip ), Returned to the execution of the user program.
1/*
2 * Linux / kernel / signal.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
8 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
9 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
1213 volatile void do_exit (Int error_code); // previous qualifier volatile ask the compiler not to optimize them.
14
// get the current task bitmap mask signal (mask).
15 int sys_sgetmask ()
16 {
17 return current -> blocked;
18 }
19
// Set new mask bit signal in FIG. SIGKILL can not be shielded. The return value is the original signal mask bitmap.
--143--
5.9 signal.c program
3132
verify_area (To, sizeof (struct sigaction )); // memory to verify the adequacy of the.
33 for (i = 0; i <sizeof (struct sigaction ); I ++) {
34 put_fs_byte (* From, to); // copy to fs segment. Typically user data segment.
may be SIG_DFL (default handler) or SIG_IGN (ignored). // Parameter signum - specified signal; handler - specified handle; restorer - recovery function pointer, the function
provided by the Libc // library. For recovering the original values of several registers and the system returns // called when the value of the system call returns, the system as if no
call signal processing program executed directly returned to the user after the program as a signal processing program. // function returns a handle to the original signal.
57 tmp.sa_restorer = (void (*) (void)) restorer; // save the resume processing function pointer.
58 handler = (long) current -> sigaction [Signum-1] .sa_handler;
59 current -> sigaction [Signum-1] = tmp;
60 return handler;
61 }
62
// sigaction () system call. Change the course of the operation upon receipt of a signal. signum is in addition to any // SIGKILL signal. [If the new operation (action)
is not empty] new operation is installed. If oldaction pointer is not null, then the operation of the original to be retained // oldaction. Returns 0 on success, -1
otherwise.
--144--
5.9 signal.c program
94 if (sa_handler == 1)
95 return;
96 if (! sa_handler) {
97 if (signr == SIGCHLD )
98 return;
99 else
100 do_exit (1 << (signr-1)); // Why bitmap to signal parameters? No reason!? ☺
// this should be do_exit (1 << (signr)).
101 }
// If the signal handler is used only once, then the handle blank (which has been stored in the signal handler sa_handler pointer).
parameters and call the original procedure returns a pointer and flag register value onto the stack //. Therefore, in this system call interrupt (0x80) will be executed first user's
signal handler program when the user returns to the program, and then continue // execution of the user program.
// user code pointer points to the system calls the signal handler eip.
104 * (& Eip) = sa_handler;
// If the signal handler to allow their own signal is received, it is also necessary to process the blocking code on the stack. // Note that the results
--145--
5.9 signal.c program
// and check the memory usage (for example, if the memory is allocated new super-sector pages, etc.).
Process signal is a simple message for the communication between processes, usually a reference value in the following table, and does not carry any other information.
For example, when a child process terminates or ends, it will have a numbered 17 of SIGCHILD A signal is sent to the parent process to notify the parent about the current status
A handle on how to process the received signal, there are two approaches: First, do not deal with the process of the program, at which point the signal will be processed
by the corresponding default signal handler system; second approach is to use their own process The signal processing program for processing a signal.
(Hangup) When you no longer generates the core control signal terminal, or when you close Xterm Or
off modem . Since the terminal does not control daemon, which are commonly used SIGUP The need (Abort) Off control terminal or process.
1 SIGHUP
to issue a signal to reread its configuration file.
(Interrupt) From a terminal keyboard. The driver will usually terminal and ^ C
2 SIGINT (Abort) Terminate the program.
Binding.
3 SIGQUIT (Quit) From a terminal keyboard. The driver will usually end with ^ \ binding. ( Dump) And generating program is terminated
dump core file.
(Illegal Instruction) Program error or to perform an illegal operation instruction. (Dump) And generating program is terminated
4 SIGILL
dump core file.
8 SIGFPE (Floating Point Exception) Floating-point exception. (Dump) And generating program is terminated
--146--
5.10 exit.c program
(Kill) Program is terminated. This signal can not be caught or ignored. Want to immediately
9 SIGKILL terminate a process, it sends a signal 9 . Note that the program will not have any opportunity to do (Abort) Program is terminated.
cleanup work.
10 SIGUSR1 (User defined Signal 1) User-defined signal. (Abort) The process is terminated.
(Segmentation Violation) When the program is invalid memory references will produce this signal. (Dump) And generating program is terminated
11 SIGSEGV
For example: No mapping memory addressed; unlicensed memory addressing. dump core file.
12 SIGUSR2 (User defined Signal 2) Reserved for user program IPC Or other purposes. ( Abort) The process is terminated.
(Pipe) When the program writes to a pipe socket or the absence of the signal generated by the
13 SIGPIPE (Abort) The process is terminated.
reader.
(Alarm) The signal will be called in the user alarm A delay system call set number of seconds after.
14 SIGALRM (Abort) The process is terminated.
This signal is used to determine the system call timeout.
(Terminate) Kindly claim for a program termination. it is kill The default signal. versus SIGKILL Different,
15 SIGTERM the signal can be captured, so that we can do cleanup work before decommissioning. (Abort) The process is terminated.
16 SIGSTKFLT (Stack fault on coprocessor) Coprocessor stack error. (Abort) The process is terminated.
(Child) Parent issue. Stop or terminate child process. You can change its meaning for other (Ignore) Child process to stop or end.
17 SIGCHLD
purposes.
(Continue) The resulting signal is SIGSTOP Stopped process to resume operation. It can be (Continue) The implementation of the
18 SIGCONT
captured. recovery process.
19 SIGSTOP (Stop) Stop the process of running. This signal can not be caught or ignored. (Stop) To stop the process running.
(Terminal Stop) Stop key sequence to the terminal. This signal can be captured or ignored.
20 SIGTSTP (Stop) To stop the process running.
(TTY Input on Background) Background process attempts to read data from a terminal no longer be
twenty one SIGTTIN controlled, at which point the process will be stopped until you receive (Stop) To stop the process running.
(TTY Output on Background) Background process attempting to output data to a terminal no longer
twenty two SIGTTOU be controlled, at which point the process will be stopped until you receive (Stop) To stop the process running.
The program describes the process (task) termination and deal with matters exit. The main course included the release of the session (process group) to terminate the
program and exit handlers and kill the process, terminate the process, the process hangs and other system calls. Also includes the process of signal transmission function
send_sig () And notifies the parent process child process termination function tell_father () .
Function to release process release () The main data structure according to the specified task (task descriptors) pointer, delete the specified task process pointer in the
array, the release of the relevant kernel memory pages and immediately let rescheduled to run the task.
Process group termination function kill_session () Hang up the process by sending a signal to the current process a session with the same number of processes. System
calls sys_kill () Used to send any signal to the specified process. According to the parameters pid (Process ID number) of different values,
--147--
5.10 exit.c program
The system call sends a signal to a different process or process group. Notes program already lists the various handling different situations.
Program exit handler do_exit () In the system call interrupt handler is invoked. It will first release of code and data segments occupied by the current process of memory
pages, and then send a signal to the child process termination SIGCHLD . Then close all open files in the current process, the release of the terminal equipment, the coprocessor, the
process if the current process is the process group leader, need to terminate all the processes. Then the current process is set to rigid state, set an exit code, and sends the parent
process child process termination signal. Finally, let the kernel rescheduled to run the task.
System calls waitpid () To suspend the current process until pid Specified child process exits (terminate) signal or receive to terminate the process, or the need to call a
signal handler (signal handler). in case pid Within the meaning of the child process has long been out (become a so-called zombie processes), then this call will return immediately.
All the resources used by the child process will be released. The specific operation function must also be different according to their processing parameters. See related
1/*
2 * Linux / kernel / exit.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #include <errno.h>
// error number header files. The system comprises various error number. (Linus from the introduction of minix)
8 #include <signal.h> // signal header files. Defined symbolic constant signal, the signal structure and the operation function prototype signal.
9 #include <sys / wait.h> // wait for the call header. The system defined call wait () and waitpid () and constants related symbols.
1011 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
12 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
13 #include <linux / tty.h> // tty header file, which defines tty_io, aspects of the serial communication parameters constant.
14 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
// Parameter p is a pointer to a data structure of the task. This function is called sys_kill () and sys_waitpid () in the later. // pointer array scanning task list task [] to find
the specified task. If found, the first task of emptying the trough, then release the task // data structure occupied by the memory page, and finally performs scheduling
function and exit immediately on return. If the specified task corresponding entry is not found in the task array // table, the kernel panic ☺ .
26 if ( task [I] == p) {
27 task [I] = NULL ; // blank entry and release of the tasks related to memory pages.
--148--
5.10 exit.c program
31 }
32 panic ( ' trying to release non-existent task "); // If there is a specified task crashes.
33 }
34
//// send a signal (sig) to the specified task (* p), rights for priv. //
Parameters: sig - signal value; //
p -- Specified pointer tasks;
// priv - flag forces to send signals. I.e., no need to consider the process of user attributes or levels but can transmit signals as claimed. // This function first determines
the correctness of the parameters, and then determining condition is satisfied. If the condition is sent to the specified process signal sig // and exit, otherwise unlicensed error number.
35 static inline int send_sig (Long sig, struct task_struct * P, int priv)
36 {
// If the signal is not correct or is empty task pointer error exit.
// process the concept of a session refer to the instructions in Chapter 4 about the process and group sessions.
49
// scan task pointer array, for all tasks (Tasks other than 0), if the session number which is equal to // the session number of the current session process on the signal it sends
53 }
54 }
5556 / *
*/
//// system call kill () can be used to send any signal to any process or process group, and not just kill the process ☺ . // parameter pid is
the process number; sig is the signal to send. // If the value of pid> 0, the signal is sent to process ID is pid process. // If all processes
pid = 0, then the process of signal will be sent to the current process group. // If pid = -1, then signal sig will be sent to all processes
except the first process. // If all processes pid <-1, the signal sig -pid sent to the process group. // If the signal sig is 0, no signal is sent,
but still error checking. If successful, 0 is returned.
--149--
5.10 exit.c program
// This function scan task array table, and sends a signal sig to the process satisfies the condition specified based on the value of the pid. If pid equals 0, // it indicates that the current
process is the process group leader, and therefore need to force sends a signal sig to all processes within the group.
68 retval = err;
69 } Else if (pid> 0) while (--p> & FIRST_TASK ) {
70 if (* p && (* p) -> pid == pid)
71 if (err = send_sig (Sig, * p, 0))
72 retval = err;
73 } Else if (pid == -1) while (--p> & FIRST_TASK )
74 if (err = send_sig (Sig, * p, 0))
75 retval = err;
76 else while (--p> & FIRST_TASK )
77 if (* p && (* p) -> pgrp == -pid)
78 if (err = send_sig (Sig, * p, 0))
79 retval = err;
80 return retval;
81 }
82
//// notifies the parent process - to send a signal SIGCHLD process pid: By default, a child process to stop or terminate. // If the parent is not found, the release of their own. But
according to POSIX.1 requirements, if the parent has first terminated, then the child should be the initial process // accommodating.
100 }
101
//// program exits handler. Sys_exit system call is invoked in line 137 at the next () method.
102 int do_exit (Long code) // code is error code.
103 {
104 int i;
- 150 -
5.10 exit.c program
105
// release the current process code and data segments share memory pages (free_page_tables () in mm / memory.c, 105 lines).
handler (signal handler). If the child process pid already referred // exit (become a so-called zombie processes), then this call will return immediately. All the resources used by the
child process will be released. // If pid> 0, wait for the process represents a number equal to the child process pid. // If pid = 0, represents the waiting process group number is
--151--
5.10 exit.c program
// If the pid <-1, represents the waiting process group pid number is equal to the absolute value of any child process. // [if pid = -1,
// if options = WUNTRACED, said that if the child process is stopped, it immediately returns (without tracking). // if options = WNOHANG,
said that if no child process exits or terminates immediately returned. // If the return status pointer stat_addr is not empty, then it will save
142 int sys_waitpid ( pid_t pid, unsigned long * stat_addr, int options)
143 {
144 int flag, code;
145 struct task_struct ** p;
146
147 verify_area (Stat_addr, 4);
148 repeat:
149 flag = 0;
// start a scan task from the end of an array of all tasks, to skip empty items, this process as well as sub-items of non-current process of process items.
152 continue;
153 if ((* p) -> father =! current -> pid) // if the child is not the current process is skipped.
154 continue;
// At this scanning process to select a sub p is certainly the current process.
// If the number of child processes to wait pid> 0, but is not equal to the scanning sub-process p pid, the current process which is described further sub-process, the process skips // so, then
155 if (pid> 0) {
156 if ((* p) -> pid = pid!)
157 continue;
// Otherwise, if the specified pid = 0 wait for the process, said it is waiting for the process group number is equal to the current process group number of any child processes. If this time is
scanned // set number of process p process group number of the current process ranging skipped.
processes. If WUNTRACED set, put status information into the 0x7f * stat_addr, and immediately return the child // number pid. Here the return state indicates that the
child process exit code, and releases the sub process. Finally, return to the child process exit code and pid.
--152--
5.11 fork.c program
175 code = (* p) -> exit_code; // exit code to take the child process.
177 put_fs_long (Code, stat_addr); // set status information for the exit code value.
179 default:
180 flag = 1;
181 continue;
182 }
183 }
// After the task facing an array of scanning is finished, if the flag is set, indicating a child process in line with the requirements and no waiting in exit // or dead state. If at this time you have
been set WNOHANG option (indicating that if there are no children in the withdrawal or termination state returns immediately), // immediately return 0 and exit. Otherwise, the current
184 if (flag) {
185 if (options & WNOHANG ) // if options = WNOHANG, then immediately returned.
186 return 0;
187 current -> state = TASK_INTERRUPTIBLE ; // set the current process interrupt-waiting state.
188 schedule (); // reschedule.
// When they began the implementation of this process, if this process does not signal other than SIGCHLD is received, the process is repeated. Otherwise, // returns an error code and
exit.
193 }
// If the child process to meet the requirements is not found, an error code is returned.
fork () System call is used to create a child process. Linux All processes are processes 0 (task 0 ) The child process. The program is sys_fork ()
(in kernel / system_call.s Defined) the secondary processing function set of system calls, gives sys_fork () Two system calls used
C Language functions: find_empty_process () with copy_process () . Also includes verification process memory area and memory allocation functions
verify_area () .
copy_process () And the process used to create the copy of the code and data segments and the environment. In the process of copying process, the main process involved
in setting data structure information. The system first application for a new process for the memory area in the main memory to store the data structure information of its mandate,
and copy all the contents of the current process task data structure as a template for a new process task data structure.
Then copy the data structure of the task to be modified. The current process is set to the parent of the new process, the clear signal bitmaps and reset each new process
statistics. Then set the task state segment based on the current process ( TSS ) The value of each register. Since the new process returns the value creating process should be 0 ,
You need to set tss.eax = 0 . New process kernel mode stack pointer tss.esp0 The new process is set to top the task data structure where memory pages, and stack segment tss.ss0
Is provided to the kernel data segment selector. tss.ldt It is set as a local descriptor table GDT
--153--
5.11 fork.c program
The index value. If the current process uses a co-processor, the state also need to preserve the integrity coprocessor to a new process tss.i387
Structure.
After setting up a new task system code and data segment base address, limit long and copy the current process page table memory paging management. If the parent has
a file is opened, the corresponding increase in the number of open files 1 . Followed by GDT Set new tasks TSS with LDT Descriptor entries, wherein the group address information
point to the new progress of the task structure tss with ldt . Then the final set to run a new task state and returns a new process ID.
Map 5-10 The memory validation function verify_area () Adjust the starting position of the memory and verify scope FIG. Because the memory write verification function write_verify
() You need to be memory page basis ( 4096 Byte) operation, so the call write_verify () We are required before the starting position is adjusted to verify a page start position, while
Code data
Map 5-10 Verify and adjust the memory range starting position
1/*
2 * Linux / kernel / fork.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
1415 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
--154--
5.11 fork.c program
// Some parameters related descriptors set and get embedded assembly function macro statement.
16 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
17 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
18 #include <asm / system.h> // system header files. Set or modify the defined descriptors / interrupt gate or the like embedded macro assembler.
twenty three
// detection operation before the write operation to the current process address from addr to addr + size This is a space in units of pages perform. // Since the detection
page judgment is to operate as a unit, so the program first need to find out where addr start address start page, // then start the process of adding a data segment base to
make this start into CPU 4G linear address space . The last cycle // Call write_verify () before the specified size of memory write verification. If the page is read-only, shared
addr for obtaining a specified start position (i.e., start) where the offset value in the page, // plus the size range of the original verify an offset value that is to be extended to the
page where addr range start position value. Is also required to verify the start position start boundary value is adjusted to page 30 // row. See "Memory Validation adjustment
segment and data segment which is a linear address space base address and limit are the same length.
34 write_verify (Start);
35 start + = 4096;
36 }
37 }
38
// set new tasks of code and data segment base address, limit long and copy the page table. // nr for a
44 code_limit = get_limit (0x0f); // get the local descriptor table entry code segment middle of indefinite length.
45 data_limit = get_limit (0x17); // get the local descriptor table descriptor data items middle indefinite length. // get the base address of the current
46 old_code_base = get_base ( current -> ldt [1]); // take the original code base.
47 old_data_base = get_base ( current -> ldt [2]); // get the original data segment base.
48 if (old_data_base! = old_code_base) // version 0.11 does not support the case of code and data segments discrete.
--155--
5.11 fork.c program
52 new_data_base = new_code_base = nr * 0x4000000; // base address = new task number * 64Mb (size of the job).
53 p-> start_code = new_code_base; // the new process described in the local base
54 set_base (P-> ldt [1], new_code_base); // set the code segment base address field.
55 set_base (P-> ldt [2], new_data_base); // set the base address of a data segment descriptor field. // Set the new process page directory entries and page table entries. That is
the new process of linear memory address corresponding to the page to the actual physical address of the memory page.
56 if ( copy_page_tables (Old_data_base, new_data_base, data_limit)) {// copy the code and data segments.
57 free_page_tables (New_data_base, data_limit); // if an error occurs releasing application memory.
58 return - ENOMEM ;
59 }
60 return 0;
61 }
6263 / *
*/
// copy process.
// where nr parameter is an array of task item number to call find_empty_process () allocation. none is pushed onto the return address stack when calling //
68 int copy_process (Int nr, long ebp, long edi, long esi, long gs, long none,
69 long ebx, long ecx, long edx,
70 long fs, long es, long ds,
71 long eip, long cs, long eflags, long esp, long ss)
72 {
73 struct task_struct * P;
74 int i;
75 struct file * F;
7677
p = (struct task_struct *) get_free_page (); // data structure for a new job to allocate memory.
78 if (! p) // If the memory allocation error, an error code is returned and exit.
79 return - EAGAIN ;
80 task [Nr] = p; // pointer to put the new task structure task array. // where nr is task number, returned by the
previous find_empty_process ().
81 * P = * current ; / * NOTE! This does not copy the supervisor stack * /
/ * Note! This will not copy the super-user stack * / (just copy the contents of the current process).
82 p-> state = TASK_UNINTERRUPTIBLE ; // The status of the new process must first be set uninterruptible wait state.
83 p-> pid = last_pid ; // new process ID. From the previous call find_empty_process () to get.
84 p-> father = current -> pid; // Set the parent process ID.
90 p-> cutime = p-> cstime = 0; // Initialize the child user mode and kernel mode time.
--156--
5.11 fork.c program
92 p-> tss.back_link = 0;
// Because it is assigned to the task structure p a new memory, so in this case esp0 just points to the top of the page. ss0: esp0 // stack for a program executed in kernel
mode.
Whenever a task switch occurs, CPU will set this flag. This flag is used to manage the math coprocessor: // If this flag is set, then each ESC command will be captured.
If the coprocessor Present also set, then it will capture // WAIT instruction. Therefore, if a task switch occurs after ESC instruction begins execution, the contents of the
coprocessor // may need to be saved before the implementation of the new ESC instruction. An error handler will be saved coprocessor and reset the TS flag. //
command is used to save all state fnsave coprocessor operand to a destination designated memory area (tss.i387).
--157--
5.11 fork.c program
133 }
134
// Get the number of non-repetition of the process last_pid for the new process, and return to the task number (array index) in the task array.
The following chart 5-11 It is a task state segment TSS ( Task State Segment )Content. Its description, see the Appendix.
31 twenty three 15 7 0
0,000,000,000,000,000 GS 5C
0,000,000,000,000,000 FS 58
0,000,000,000,000,000 DS 54
0,000,000,000,000,000 SS 50
0,000,000,000,000,000 CS 4C
0,000,000,000,000,000 ES 48
EDI 44
ESI 40
EBP 3C
ESP 38
EBX 34
EDX 30
--158--
5.11 fork.c program
ECX 2C
EAX 28
0,000,000,000,000,000 SS2 18
ESP2 14
0,000,000,000,000,000 SS1 10
ESP1 0C
0,000,000,000,000,000 SS0 08
ESP0 04
CPU All information management tasks need to be stored in a special type of segment, the task state segment ( task state segment - TSS) . Figure executed shows 80386
1. CPU Updated when switching tasks during dynamic set of information. These fields are:
o General purpose registers ( EAX , ECX , EDX , EBX , ESP , EBP , ESI , EDI );
o Segment register ( ES, CS, SS, DS, FS, GS );
returned).
2. CPU Read but static information set does not change. These fields are:
o When the task switching leads CPU Generate a debug ( debug) abnormal T- Bit (bit debug trace);
o I / O Bit bitmap base address (which is the maximum length TSS The maximum length, in TSS Descriptor described).
TSS can be stored anywhere in the linear space. Similar to other types of segments, task state segment is defined by a descriptor. Currently executing
task TSS By the task register ( TR ) To direct. instruction LTR with STR And to modify the read selector (visible part of the task register) of the task register.
I / O Each bit in the bitmap 1 Bit corresponds 1 More I / O port. For example, port 41 The bit is I / O FIG bit base address + 5 , Bit offset 1 Place. In protected mode, when
the encounter 1 More I / O Instruction ( IN, INS, OUT, OUTS) , CPU First, it will check the current privilege level is less than the flag register IOPL If this condition is satisfied, on the
TSS middle I / O Bit bitmap. If the corresponding bit is set, the general protection exception is generated, otherwise it will perform the I / O operating.
in Linux 0.11 In the figure SS0: ESP0 Task stack pointer for storing run-time kernel mode. SS1: ESP1 with SS2: ESP2
Respectively correspond to the privileged class run 1 with 2 When using the stack pointer, the two privilege levels in Linux Not used. And the task operating in the user mode stack
pointer is held in the SS: ESP Register. From the above found, the task enters the kernel mode whenever executed, the kernel mode stack pointer initial position unchanged, both
at the location of the top of the page structure of the task data.
--159--
5.12 sys.c program
sys.c The main program contains many features of the system call to implement a function. Wherein, if the return value - ENOSYS , Then this edition
Linux This function is not implemented, the current reference may code to understand their implementation. All system calls the function description, see the header file include /
linux / sys.h .
The program contains a lot about the process ID Process group ID ,user ID ,user group ID The actual user ID Effective user ID And session ID ( session ) Function
A user has a user ID ( uid ) And user groups ID ( gid ). Both ID Yes passwd File in the user settings ID , Commonly referred to as the actual user ID ( ruid
) And real group ID ( rgid ). In each file i Node information are stored in the host user ID
And group ID They pointed out the file owner and user group. Mainly for permissions when accessing files or performing discriminating operation. In addition, the task data
structure of a process, in order to achieve different functions and save 3 Kinds of users ID And group ID . Table 5-5 Fig.
table 5-5 Associated with the process of the user ID And group ID
Process uid - user ID . Indicating that the user owns the process. gid - group ID . Users specify the group that owns the process.
Effective euid - Effective user ID . Indicates that the right to access the file. egid - Effective group ID . Indicates that the right to access the file.
suid - Saved by the user ID . When the user performs settings file sgid - Save group ID . When the group execute files ID Mark ( set-group-ID )
conserved ID Mark ( set-user-ID ) When set, suid Save the executable file uid . When set, sgid Save the executable file
otherwise suid Equal process euid . gid . otherwise sgid Equal process egid .
Process uid with gid Respectively, it is the process owner user ID And group ID , That is the actual user ID ( ruid ) And real group ID ( rgid ). Power users can use set_uid () with set_gid
() Modify them. Effective user ID And effective group ID Judge for permission to access the file at the time of the process.
Saved by the user ID ( suid ) And save group ID ( sgid ) Process for setting up access set-user-ID or set-group-ID File marker. When executing a program,
process euid Usually the actual user ID , egid Usually the real group ID . Therefore, the process can only be effective user access process, effective user defined set
When a valid user flag is set, then the process ID It will be provided to the user of the host file ID So the process can access a restricted set this flag file,
and the user's host file ID It is saved in suid in. Similarly, file set-group-ID Flag has a similar effect and make the same deal.
For example, if the host application is a super user, but it is provided set-user-ID Mark, then when the program is running a process, then the effective user of the
process ID ( euid ) Will be provided to the superuser ID ( 0 ). So this process will have a super-user privileges. A practical example is the Linux systematic passwd command.
The command is to set up a set-user-Id The program, thus allowing users to change their passwords. Because the program needs to write a new password for the user / etc /
passwd File, and the file is only the super user has write permissions, passwd We need to use the program set-user-ID Mark.
In addition, the process also has its own identity attributes of the process ID ( pid ), The process belongs to the group process group ID ( pgrp or pgid Session) and belongs
session ID ( session ). This 3 More ID It is used to indicate the relationship between a process and the process of the user ID And group ID Nothing to do.
1/*
--160--
5.12 sys.c program
89 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
10 #include <linux / tty.h> // tty header file, which defines tty_io, aspects of the serial communication parameters constant.
11 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
12 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
13 #include <sys / times.h> // define the structure of the process of running time tms and times () function prototype.
16 int sys_ftime ()
17 {
18 return - ENOSYS ;
19 }
20
//
twenty one int sys_break ()
twenty two {
25
// current process for the sub-process debugging (degugging).
26 int sys_ptrace ()
27 {
28 return - ENOSYS ;
29 }
30
// change and print terminal line settings.
31 int sys_stty ()
32 {
33 return - ENOSYS ;
34 }
35
// get information on the terminal line settings.
36 int sys_gtty ()
37 {
38 return - ENOSYS ;
39 }
40
// modify the file name.
41 int sys_rename ()
42 {
43 return - ENOSYS ;
44 }
45
//
46 int sys_prof ()
--161--
5.12 sys.c program
47 {
48 return - ENOSYS ;
49 }
50
// set the actual current task and / or effective group ID (gid). If the task is not super-user privileges, // you can only swap its real group ID and effective group
ID. If the task with super user privileges can be set effective and practical // the group ID. Reserved gid (saved gid) is provided with an effective gid same value.
77 int sys_acct ()
78 {
79 return - ENOSYS ;
80 }
81
// any physical memory mapped into the process's virtual address space.
82 int sys_phys ()
83 {
84 return - ENOSYS ;
85 }
8687 int sys_lock ()
88 {
89 return - ENOSYS ;
90 }
91
--162--
5.12 sys.c program
92 int sys_mpx ()
93 {
94 return - ENOSYS ;
95 }
9697 int sys_ulimit ()
98 {
99 return - ENOSYS ;
100 }
101
// Returns the time value (in seconds) from January 1, 1970 00:00:00 GMT start timing. If tloc is not null, // the time value is also stored there.
110 }
111 return i;
112 }
113 114 /
*
115 * Unprivileged users may change the real user id to the effective uid
116 * Or vice versa.
117 * /
/*
* Non-privileged users can see the actual user identifier (real uid) to change the effective user identifier (effective uid), and vice versa.
*/
// set the actual task and / or the effective user ID (uid). If the task is not super-user privileges, you can only swap its // real user ID and effective user
ID. If the task with super user privileges can be set effective and real user ID. // Reserved uid (saved uid) is provided with the same effective uid
value.
118 int sys_setreuid (Int ruid, int euid)
119 {
120 int old_ruid = current -> uid;
121
122 if (ruid> 0) {
123 if (( current -> euid == ruid) ||
124 (Old_ruid == ruid) ||
125 suser ())
126 current -> uid = ruid;
127 else
128 return (- EPERM );
129 }
130 if (euid> 0) {
131 if ((old_ruid == euid) ||
132 ( current -> euid == euid) ||
133 suser ())
134 current -> euid = euid;
135 else {
136 current -> uid = old_ruid;
--163--
5.12 sys.c program
superuser privileges.
// This function sets the data segment end_data_seg specified. The end of the code must be greater than and less than the end of the stack // 16KB. The return value is the new end of the
data section (if the return value is different from the required value, it indicates that there is an error has occurred). // This function does not directly call the user, and packaged by the libc
173 return current -> brk ; // Returns the current value of the data segment ending process.
174 }
175 176 /
*
177 * This needs some heave checking ...
178 * I just have not get the stomach for it. I also do not fully
179 * Understand sessions / pgrp etc. Let somebody who does explain it.
--164--
5.12 sys.c program
180 * /
/*
* The following code requires some rigorous inspection ...
* I just have no appetite to do that. I do not fully understand sessions / pgrp and so on. Understand them or let people do it.
*/
// set the process group ID is pgid.
// If the parameter pid = 0, then the current process ID. If pgid is 0, the parameter pid specified process group ID as // pgid. If the function is used to move a process from
one process group to another group process, the two processes must belong to the same group // session (session). In this case, the parameter specifies pgid prior to
addition of the process group ID, the group ID of the session at this time must be the same // (line 193) is added to the process.
189 for (i = 0; i < NR_TASKS ; I ++) // array scanning task, the task of finding a specified number of processes.
195 task [I] -> pgrp = pgid; // set pgrp the task.
196 return 0;
197 }
198 return - ESRCH ;
199 }
200
// Returns the group number of the current process. And getpgid (0) equivalents.
211 current -> session = current -> pgrp = current -> pid; // set this process session = pid.
212 current -> tty = -1; // indicates that the current process does not have control terminal.
214 }
215
// Get system information. Which utsname structure contains five fields, namely: the name of the version of the operating system, the network node name, // current release level,
--165--
5.13 vsprintf.c program
224 verify_area (Name, sizeof * name); // verify whether the size of the buffer overrun (beyond the allocated memory, etc.).
225 for (i = 0; i <sizeof * name; i ++) // the copy information byte by byte utsname in the user buffer.
226 put_fs_byte (((Char *) & thisname) [i], i + (char *) name);
227 return 0;
228 }
229
// Set the current process to create the file attributes mask to mask & 0777. And return to the original mask.
mainly includes vsprintf () Function for generating an output formatting parameters. Because the function is C The standard library function, did not address the basic core
operating principle, it can be skipped. Description Use this function directly after reading the code.
1/*
2 * Linux / kernel / vsprintf.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / * Vsprintf.c - Lars Wirzenius & Linus Torvalds * /.
8/*
9 * Wirzenius wrote this portably, Torvalds fucked it up :-)
10 * /
// Lars Wirzenius is Linus's friend, with an office at the University of Helsinki had. In the summer of 1991 to develop Linux //, Linus was not very familiar
with the C language, it will not function using a variable argument list function. So Lars Wirzenius // for him to write this code for the kernel to display
information. He later (1998) acknowledged a bug in the code until // 1994 before anyone discovered and corrected. The bug is in use * as an output
field width, forget the star // increment the pointer to skip a number. In this code, the bug still persists (line 130). His profile is http://liw.iki.fi/liw/
--166--
5.13 vsprintf.c program
13 #include <string.h> // string header file. Mainly defines the built-in functions related to operation of the string.
/ * We use the following definitions, so we can not use the ctype library * /
16 #define is_digit (C) ((C)> = '' && (c) <= ' 9') // determine whether the character numeric characters.
17
// This function converts the character string into digital integer. Input numeric string pointer is a pointer, the result value is returned. Further forward pointer.
30 #define SPACE 8 / * Space if plus * / / * The case of Canada, the space set * /
32 #define SPECIAL 32 / * 0x * / / * 0x * /
33 #define SMALL 64 / * Use 'abcdef' instead of 'ABCDEF' * / / * Lowercase * /
34
// In addition to the operation. Input: n = dividend, base divisor; Results: n = List, the function returns the remainder. // information, see Section 4.5.3
// Input: num- integer; base- band; size- string length; precision- digital length (precision); type- type option. // Output: str string pointer.
40 static char * number (Char * str , Int num, int base, int size, int precision
41 , int type)
42 {
43 char c, sign, tmp [36];
44 const char * digits = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
45 int i;
46
// If the type type noted with lowercase letters, then the definition of lowercase letters set. // If the type pointed out the need to
adjust the left (on the left margin), then fill in the zero flag type of shield.
// If the binary radix less than 2 or greater than 36, then exit the process, i.e. the present process can program the number of radix between 2-32.
than 0, the counter variable sign = minus sign, and the absolute value of num. // Otherwise, if the type is pointed out that the plus sign, then set sign = plus sign, or the sign =
--167--
5.13 vsprintf.c program
57 if (sign) size--;
58 if (type & SPECIAL )
59 if (base == 16) size - = 2;
60 else if (base == 8) size--;
// num If the value is 0, the temporary string = '0'; otherwise the given base num convert the value to a character form.
61 i = 0;
62 if (num == 0)
63 tmp [i ++] = '';
64 else while (num! = 0)
65 tmp [i ++] = digits [ do_div (Num, base)];
// if the number is greater than the accuracy of the numerical value of the character, the extended precision value into
a digital numerical value. // size width value minus the stored value for the number of characters.
// here really began to form the desired conversion results, and temporarily placed in the string str. // If the type is not zero fill
(ZEROPAD) and left-Snap (left justified) flag, the first in str // put the number of spaces to fill the remaining width values noted. For
83 while (i <precision--)
84 * str ++ = '';
// The value for a good turn-numeric characters to fill in str. A total of i.
85 while (i -> 0)
86 * str ++ = tmp [i];
// If the width value is still greater than zero, it means the type of sign has left Snap flag logo. Then placed in the remaining space width.
--168--
5.13 vsprintf.c program
91
// This function is to send output to the format string.
@ In order to use the output format in the kernel, Linus kernel implements the C standard. Wherein // is the format string fmt parameter;
args value of the number is changed; buf is the buffer output string. // Please tell us about the format conversion characters refer to the list
of code.
119 case '+': flags | = PLUS ; Goto repeat; // put a plus sign.
a parameter specified width. Therefore take calls to va_arg width value. // At this time, if the width value is less than 0, a negative number indicates that the flag field with the '-' sign
(left-truing), and therefore need the insertion of the flag in the flag variable and // the value is taken as the width of the field their absolute values.
--169--
5.13 vsprintf.c program
130 / * It's the next argument * / // Here's a bug, should be inserted ++ fmt;
range above. If the numerical accuracy of the domain directly to whichever precision value. If the accuracy is // domain character '*' indicates a parameter specifies the precision.
Therefore take calls to va_arg precision value. At this time, if the width value is less than 0, // the value is taken for the accuracy of the absolute value of the field.
width field value -1 into a space character, then placed in character parameters. If the field width is also greater than 0, then the left flush against the added width value -1 // parameter space
character character.
precision // = string length domain. If the flag field indicates that this time instead of left flush against the front of the field into the (width value - the length of the string) // space characters. Then
placed parameter string. If the field width is also greater than 0, then the left flush against the added // (width value - string length) after the parameter string of space characters.
--170--
5.13 vsprintf.c program
and the need to add zero. Then call the number () function for processing.
--171--
5.13 vsprintf.c program
// If the format conversion indicator is 'n', it indicates the number of characters stored so far should be converted and output to the corresponding parameter designated by the pointer
position.
// first using the va_arg () obtains the argument pointer, and then the number of characters that has been converted into a good position of the cursor.
conversion, it is also written directly to the output character string, and returns to 107 to continue processing rows // format string. Otherwise, it said that it has to deal with at the end of
221 default:
222 if (* fmt! = '%')
223 * str ++ = '%';
224 if (* fmt)
225 * str ++ = * fmt;
226 else
227 - - fmt;
228 break;
229 }
230 }
231 * str = '\ 0 '; // Finally add the converted null string at the end.
232 return str - buf ; // returns the converted character string length value.
233 }
234
vsprintf () Function is printf () One family of functions. These functions generate formatted output: accept the format string determining an output format fmt , Format number
printf Directly output to the standard output handle stdout . cprintf The output to the console. fprintf The output to a file handle.
printf Prozone ' v ' Character (for example, vfprintf) It represents the parameter is from va_arg Array va_list args Accept. printf Preceded by a ' s' It indicates the character to output to null
End of the string buf (In this case the user should ensure buf There is enough space to store the string). The method of using the format string described in detail below.
1. Format string
printf Series format string functions for controlling the function mode conversion, formatting, and outputs the parameters. For each format, you must have the
corresponding parameters, too many parameters are ignored. Format string contained two components, one is to be copied directly to the output of a simple character; the other is
the corresponding parameters for the format conversion instruction character string.
A conversion indicating for each string are required to start a percent sign (%). among them
--172--
5.13 vsprintf.c program
flags Alignment control output, numerical symbols, decimal point, the zero tail, binary, octal, hexadecimal, or the like, see above list
27-33 Comment line. Flag characters and their meanings are as follows:
# It represents the corresponding parameter needs to be converted to a "special form." For octal ( o) , The first character string to be converted
It is a zero. For hexadecimal ( x or X) , The need to convert the string ' 0x ' or' 0X ' beginning. for e, E, f, F, g as well as G Even if no decimal places, the conversion results will
always have a decimal point. for g or G After dragging the zero will not be deleted.
0 Conversion results should be attached to zero. for d, i, o, u, x, X, e, E, f, g with G , The conversion result will fill in the blanks with zeros to the left instead of
With a space. If both appear 0 And - flag, 0 Flag will be ignored. For conversion value, if the accuracy is given field, 0 Flag is also ignored.
- Results converted into the appropriate field boundary will be left adjustment (left). (The default is to make the right adjustments - right). n Conversion Example
'' It should leave a space before a positive number indicates a signed conversion results produced.
+ It represents the total need to place a symbol before a symbol conversion result (+ or -). For default, only negative numbers
negative.
width Specifies the width of the output string, which specifies the minimum width value of the field. If the result is converted smaller than the specified width, at its left (or
right, if the left-adjustment flag is given) needed to fill a space or zero (the flags Flag determines) the number and the like. In addition to using a numerical width fields than can be
used '*' to indicate the width of the field is given by an integer parameter. When the conversion value is larger than the width width When the specified width, in any case small-width
values are not the results are truncated. Field width will be expanded to include the full results.
precision Is a minimum number of digital output. for d, I, o, u, x with X Conversion, precision value indicates the minimum number of digits appear. for e, E, f with F This value
indicates the number appear after the decimal digits. for g or G , Indicates the maximum number of significant digits. for
s or S Conversion, the accuracy of the output value of the maximum number of characters described in the character string.
Length indicator described modified form of the output type Integer conversion. Described below in 'The Integer' represents d, i, o, u, x or
X Conversion.
hh Integer conversion described later corresponds to a signed or unsigned char character parameters.
h Integer conversion described later corresponds to a signed or unsigned short integer parameters.
l Integer conversion described later corresponding to a long or unsigned long integer parameters.
ll Integer conversion described later corresponding to a long integer or unsigned long integer parameters.
type Is a parameter type input and output formats accepted. Converting the meaning of each indicator is as follows:
d, I Integer parameter is converted to a signed integer. If there is accuracy ( precision) , Then given a minimum need for output
Number of digits. If the digital value is converted to a fewer number, it will add zero to its left. The default precision value is 1 .
o, u, x, X Unsigned integer will be converted to an unsigned octal ( o) , Unsigned decimal ( u) Or unsigned hexadecimal ( x or
X) Output representation. x He pledged to use lowercase letters ( abcdef ) To represent hexadecimal number, X Uppercase letters ( ABCDEF ) Represent a hexadecimal number. If there
precision field, it indicates a minimum number of digits required output. If the digital value is converted to a fewer number, it will add zero to its left. The default precision value is 1 .
e, E Both have been rounded for converting characters converts the argument to [-] d.ddde + dd form. Numbers after the decimal point one
--173--
5.14 printk.c program
Number equal precision. Without a precision field, it takes the default value 6 . If the accuracy is 0 , No decimals appear. E Uppercase letters E
To represent the exponent. Exponent part always 2 Digit number. If the value is 0 , Then the index is 00 .
f, F Both have been rounded for converting characters converts the argument to [-] ddd.ddd form. Number of digits after the decimal point, etc.
In accuracy. Without a precision field, it takes the default value 6 . If the accuracy is 0 , No decimals appear. If there is a decimal point, so at least there will be back 1 Digits.
g, G These two parameters will be converted to a conversion character f or e The format (if it is G , It is F or E format). Precision value specifies the number of integers. If the
accuracy is not a domain, it defaults 6 . If the precision is 0 Then as 1 To be treated. If the index is less than the conversion
--4 Greater than or equal to the precision, is used e format. After dragging the fractional part of zero will be deleted. Only when there is at least one decimal place decimal point will
appear.
c Parameter will be converted into an unsigned character and outputs the conversion result.
s It requires input pointer to a string, and the string to be null end. If the field with a precision, output only the fine
n Save for the number of characters so far from the converter output to the position indicated by the pointer corresponding to the input. Right into the parameters
Line conversion.
% A% sign output, conversion is not performed. At this time, i.e. throughout the transition indication to %%.
Because the file is also part of the library functions, so from 1.2 Version of the kernel to start the direct use of the library. That is to delete the file.
printk () Kernel is used in the print (display) function, and function C Standard function library print () the same. The reason to re-write such a function is in the
kernel can not be dedicated to user mode fs Segment register, you must first save it. printk () Function first use svprintf () Parameters for formatting, then save the fs Calling
1/*
2 * Linux / kernel / printk.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
*/
--174--
5.15 panic.c program
12 #include <stdarg.h> // standard parameter header. In the form of macro variables defined parameter list. Mainly it described
- a type // (the va_list) and three macros (va_start, va_arg and va_end), for // vsprintf, vprintf, vfprintf
function.
13 #include <stddef.h> // define the standard header files. Definition of NULL, offsetof (TYPE, MEMBER).
1415 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
18
// The following function vsprintf () in line 92 begins linux / kernel / vsprintf.c in.
19 extern int vsprintf (Char * buf , Const char * fmt, va_list args);
20
// display function used by the kernel.
27 i = vsprintf ( buf , Fmt, args); // Use the output format string fmt args parameter list to buf. // returns the output value i
35 "Call _tty_write \ n \ t" // Call tty_write function. (Kernel / chr_drv / tty_io.c, 290).
36 "Addl $ 8, %% esp \ n \ t" // skipped (dropped) onto the stack two parameters (buf, channel).
39 :: " r "( i): " ax "," cx "," dx "); // Inform the compiler, register ax, cx, dx value may have changed.
40 return i; // Returns string length.
41 }
42
When the kernel error, call the function panic () Error message is displayed and the system into an infinite loop. In many parts of the kernel, and if there was going
seriously wrong call to the function. In many cases, call panic () Function is a straightforward approach. You do well to follow the UNIX "As concise as possible" principle.
panic It is "panic panic" means. in Douglas Adams Novel " Hitch hikers Guide to the Galaxy "(" Galaxy hiker's Guide "), the book's most
famous sentence is" Do not Panic! " . This is a series of novels linux A hacker books read most often.
--175--
5.16 Summary
1/*
2 * Linux / kernel / panic.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
*/
11 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
12 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
is the task 0, it also shows that the task switching error, and has not run a file system synchronization function.
25
linux / kernel Directory 12 Code files are given kernel to achieve the most important mechanisms, including system calls, process scheduling, replication, and terminate the
--176--
6.1 Overview
6.1 Outline
This chapter describes the block device driver in the kernel. in Linux 0.11 Kernel primary support two kinds of hard and floppy drive block device. Because block devices
with major file system and cache, and therefore a good idea to take a quick look a chapter file system. Source code files involved see list 6-1 Fig.
blk.h 3464 bytes 1991-12-05 19:58:01 block device special file header
ll_rw_blk.c 3539 bytes 1991-12-04 13:41:42 block device interface program ramdisk.c
Chapter function program code can be divided into two categories, one of each corresponding block device driver, such procedures are:
Another class of only one program, the kernel is the other programs access block device interface program ll_rw_blk.c . Device special file header block blk.h
And is a three block devices ll_rw_blk.c Interactive program provides a unified set of device requests the same way and start the program.
Read and write operations to the hard and floppy disk block device data is performed by the interrupt handler. The amount of data per read and write to a logical block ( 1024
Bytes), and the device controller is based on a block sector ( 512 Bytes). In the process, the use of write request entries waiting queue buffer by sequentially operating a plurality of
When the program needs to read a logical block on the hard disk, it will apply to the buffer management program, and the process of the program goes to sleep waiting
state. Buffer management program first to find out whether this had previously been read data in the buffer. If the buffer already have, directly to the corresponding buffer header
pointer returns to the program and wakes up the program processes. If the requested data block does not exist in the buffer, the buffer management program can call in this chapter
lower block read and write functions ll_rw_block () Issuing a read operation request block to the corresponding block device drivers. This function will create a request structure for this
item, and inserted into the request queue. In order to provide efficiency of disk read and write, the head moving distance is reduced, when the interrupt request key using an elevator
algorithm moves.
--177--
6.2 overall function
When the request queue is empty entry device when the corresponding block indicates that the block device is not busy at the moment. So the data kernel will immediately
issue a read command to the controller of the block device. When the controller block of the device after the specified data is read into the buffer block, it will send an interrupt
request signal and the read command invokes the appropriate handler, processing continues operation or a read sector process ends this request entry. For example, the closing
operation of the respective blocks and sets the device buffer block flag data has been updated, and finally waiting for the wake-up process of the data block.
According to the above description, we know that low-level read and write functions ll_rw_block () It is to establish contact with various items block device by requesting and
issuing read and write requests. For each piece of equipment, the use of a core block device table blk_dev [] To manage. Each piece of equipment occupies a block in the device
table. Building block device table entry for each block device (taken from the back blk.h ):
struct blk_dev_struct {
void (* request_fn) (void); // function pointer entry operation request.
};
extern struct blk_dev_struct blk_dev [ NR_BLK_DEV ]; // block device table (array) (NR_BLK_DEV = 7).
Wherein the first field is a function pointer, the corresponding entry for the operation request block device. For example, a hard disk driver, which is
do_hd_request () And for a floppy disk device, it is do_floppy_request () . The second field is a pointer to the current request configuration item, for indicating the request entry
device of the present block currently being processed, are set to the initialization NULL .
Block device table in the kernel initialization, init / main.c It is set when the program calls for each device initialization function. To facilitate the expansion,
Linus The table block device built in a major number of the array index. in Linux 0.11 , The master device has a number 7 Species, see Table 6-1 Fig. Wherein the master device
number 1 , 2 with 3 Corresponding block device: virtual disk, floppy disk and a hard disk. In block device array other items are set to default NULL .
0 no no. NULL
When the kernel issues a block write or other operation request device, ll_rw_block () I.e., the device will function in accordance with the operation command number of the
parameters specified in the block header and data buffering, by the corresponding function operation request entry do_XX_request () Establishing a requested item block device,
using an elevator algorithm into the request queue entries. Request queue entry consists of an array of items requested item, total 32 Item, the data structure of each requested
item as follows:
struct request {
int dev; // used device number (if it is -1, indicating that idle).
int cmd; // command (READ or WRITE).
int errors; // number of errors generated during operation.
--178--
6.2 overall function
struct buffer_head * Bh; // buffer header pointer (include / linux / fs.h, 68).
struct request * Next; // points to the next request entry.
};
extern struct request request [ NR_REQUEST ]; // request queue array (NR_REQUEST = 32).
Current Request necklace table pointer array entry request of the device each block device request queue together constitute the apparatus. And between items by using
item field next Forming a linked list pointer. Thus block and associated equipment item request queue structure shown below. Main reason for using an array plus requested item
list structure is designed to meet two purposes: First, by using the array configuration may be requested item when searching an idle cycle operation request block, the program is
very simple and can be compiled; the second is to meet the elevator algorithm insert item operation request, and therefore need the list structure. Map 6-1 In this hard disk device
is shown having 4 A requested item, a floppy disk device having 1 Request items, and virtual disk read and write requests currently no equipment items.
For a current block device idle, when ll_rw_block () A function for the establishment of a requested item, make the device current request pointer entries current_request Directly
to the requested item just created, and call the corresponding device requests entries immediately begin operation function block device read and write operations. When a piece
of equipment has several requests entry list consisting of presence, ll_rw_block () Will use an elevator algorithm, the head movement distance according to the principle of the
minimum, the new request list item into the appropriate position.
In addition, to meet the priority read operation, when a request for the establishment of a new array of items and item search request, the search range of free entry to
establish a write request limit before the entire array of items 2/3 The range, while the remaining 1/3 Requested item devoted to the establishment of a read request items to use.
current_request
The remaining requested item
current_request
current_request
With the hard disk in the system (kernel) IO In operation, it is necessary to consider the interactions between the three objects. They are the system, controller and drive
(e.g., hard or floppy disk drive), see FIG. 6-2 Fig. The system may send a command directly to the controller or the controller waits for an interrupt request; receiving the command
controller will control the operation of the drive, the read / write data, or perform other operations. So here we can interrupt signal issued by the controller seen as a
First, the system controller at the end of the specified command execution caused the interrupt process should call C Function, and then transmits the read block to the
--179--
6.3 Makefile file
When completion of the specified control command will be issued an interrupt request signal, initiating system block device performs interrupt processing, and call the
specified C Function of read / write commands or other processing after the end of the command.
Interrupt Request
For the write operation, the system needs after issuing a write command (using hd_out () ) Administering to wait for the controller allows to write data in response to the
controller, i.e. the data need to query the controller to wait for service request flag status register DRQ Position. once DRQ Is set, the system can transmit data buffer controller to the
When all the controller data write drivers (the error), it will produce an interrupt request signal to the interrupt processing executed in foregoing preset C function( write_intr () ).
This function will check whether there is data to be written. If so, then the system controller transmitted a data sector buffer, and then waits for the interrupt controller again initiated
after the drive data writing has been so repeatedly executed. At this time, if all the data has been written to the drive, the C Processing function is executed after the end of this
write disk: Wake related processes waiting for the requested item about the data, wake up processes waiting for a request item, release the current request item and delete the
item request and the associated buffer release the lock from the list . Then call the function to request entry operation to the next read / write disk request item (if there are any).
For read the disk operating system after transmitting the start position includes a sector to be read, the number of the sector information and other commands to the
controller, the controller waits for an interrupt signal. When the controller in accordance with the requirements of the read command, a sector of the designated data to the buffer
from their drive will issue an interrupt request. Thus performs the foregoing operation is preset to read the disk C function( read_intr () ). This function first data buffer controller of
one sector into the buffer system, the buffer system to adjust the current position of the writing, and then decreasing the number of sectors required to read. If there are data to be
read (the result of diminishing the value is not 0 Under), continue to wait controller sends an interrupt signal. If all the requirements of the sector at this time have already read the
buffer system, the implementation of the above write disk operation like the end of the processing.
For virtual disk device, read and write operations because it does not involve the synchronization between the external apparatus, thus there is no such interrupt
processing. Entry of the current request read and write operations in the virtual device entirely do_rd_request () Implemented.
That makefile File for managing the program to compile all from this category.
1#
2 # Makefile for the FREAX-kernel block device drivers.
3#
--180--
6.3 Makefile file
# Dependency information on here, unless it is (that is not a message .c file) special file.
# (Linux first name FREAX, the name was later changed to Linux ftp.funet.fi administrator).
89 AR
= Gar # GNU binary file processing program for creating, modifying and extracting files from the archive.
10 AS = Gas # GNU assembler.
11 LD = Gld # The GNU linker.
12 LDFLAGS = -s -x # connection program all the parameters, -s omitted all symbols output file information. -x Delete all local symbols.
# The frame pointers; -fcombine-regs merge register, reduce the use of register class; -finline-functions all Jane
# Single short code embedded function calls the program; -mstring-insns Linus own filling optimization options, will no longer use;
# - nostdinc -I ../ include not using the default path contains the file, and use the specified directory (../../include).
14 CFLAGS = -Wall -O -fstrength-reduce -fomit-frame-pointer -fcombine-regs \
15 - finline-functions -mstring-insns -nostdinc -I ../../ include
# C pre-processing options. -E C only run pre-treatment, pre-treatment and the results for all of the specified program is output to the standard output C
# Refers gcc CFLAGS using the specified options compiled C code is compiled without stops (-S), thereby generating
# C each corresponding to the input file assembler code file. Assembler default file name is generated by the original file name C
# Remove .c and .s suffix plus. -o represented followed by the name of the output file. Of which $ *. S (or $ @ ) is automatic target variable,
29 blk_drv.a: $ (OBJS)
30 $ (AR) rcs blk_drv.a $ (OBJS)
31 sync
32
# The following rules for the cleanup. When performing 'make clean', it will execute commands on the line 34--35 remove all compiled
# Connection file generated. 'Rm' command is to delete the file, meaning -f option is to ignore the file does not exist, and does not delete the information.
33 clean:
34 rm -f core * .o * .a tmp_make
35 for i in * .c; do rm -f `basename $$ i .c`.s; done
36
--181--
6.4 blk.h file
# Here was the objective or rules for checking dependencies between files. Methods as below:
# Sed string editing program for the Makefile (i.e. are files), and outputs for deletion Makefile
# File '### Dependencies' all rows behind rows (44 rows from the beginning of the next), and generates tmp_make
# Temporary files (action line 38). Gcc preprocessing operation is then performed for each file in the C kernel / blk_drv / directory.
# - M flag tells the preprocessor output description of the rules relating to each target file, and make compliance with these rules syntax.
# For each source file, the output of preprocessor make a rule, the result is a certain form of the corresponding source file
# File name plus its dependencies - lists all the header files included in the source file. The pretreatment results are added to the temporary
# Tmp_make file, and then copy the temporary file into a new file Makefile.
37 dep:
38 sed '/ \ # \ # \ # Dependencies / q' <Makefile> tmp_make
39 (For i in * .c; do echo -n `echo $$ i | sed '.. S, \ c, \ s,'` ""; \
40 $ (CPP) -M $$ i; done) >> tmp_make
41 cp tmp_make Makefile
4243 ### Dependencies:
This is the first file on the hard-block device parameters, as only a block device, the device code block in the same place. Wherein the primary data structure is defined in
terms of the request queue request , Macro statement defines the elevator with the search algorithm, the kernel is currently supporting virtual disk, hard and floppy disk three kinds
of block devices according to their respective major number of the corresponding constant value.
5/*
6 * NR_REQUEST is the number of entries in the request-queue.
--182--
6.4 blk.h file
7 * NOTE that writes may use only the low 2/3 of these: reads
8 * Take precedence.
9*
10 * 32 seems to be a reasonable number: enough to get some benefit
11 * From the elevator-mechanism, but not so much as to lock a lot of
12 * Buffers when they are in the queue. 64 seems to be too many (easily
13 * Long pauses in reading when heavy writing / syncing is going on)
14 * /
/*
* NR_REQUEST defined below is the number of entries included in the request queue.
* Note that read operations only use these low-end items 2/3; read priority.
*
* 32 seems to be a reasonable figure: enough to benefit from the elevator algorithm,
* But when the buffer is in the queue and locked without appearing to be a big number. 64 spotted
* Go too (when a large number of write / synchronization run can easily lead to long pause).
*/
15 #define NR_REQUEST 32
1617 / *
twenty two * /
/*
* The OK, the following structure is an extended form of the request, and therefore When implemented, we can request the tab
* Using the same request structure. In the tab process, 'bh' is NULL, and the 'waiting' for waiting for the read / write is completed.
*/
// The following is the structure of a request queue entries. Wherein if dev = -1, it indicates that the item was not used.
31 struct buffer_head * Bh; // buffer header pointer (include / linux / fs.h, 68).
32 struct request * Next; // points to the next request entry.
33 };
3435 / *
* This is natural: read the time demands much more stringent than the write operation.
*/
40 #define IN_ORDER (S1, s2) \
41 ((S1) -> cmd <(s2) -> cmd || (s1) -> cmd == (s2) -> cmd && \
42 ((S1) -> dev <(s2) -> dev || ((s1) -> dev == (s2) -> dev && \
--183--
6.4 blk.h file
45 struct blk_dev_struct {
46 void (* request_fn) (void); // pointer to function requested operation.
53
// when the block device drivers (e.g. hd.c) To include this header must be defined and the corresponding driver device major number. Such // below -87 row line 61 can be
*/
6061 #if ( MAJOR_NR == 1) // RAM disc 1 is a major number. The reasoning may be defined herein memory block is also a major number.
79 / * Harddisk * /
80 #define DEVICE_NAME "Harddisk" // hard disk name harddisk.
81 #define DEVICE_INTR do_hd // device interrupt handler do_hd ().
82 #define DEVICE_REQUEST do_hd_request // function device requests do_hd_request ().
83 #define DEVICE_NR (Device) ( MINOR (Device) / 5) // device number (0--1). Each hard disk can have four partitions.
84 #define DEVICE_ON (Device) // has been hard at work, without opening and closing.
--184--
6.4 blk.h file
9091 #endif
9293 #define CURRENT ( blk_dev [ MAJOR_NR ] .Current_request) // CURRENT number is designated the master device requests the current configuration.
94 #define CURRENT_DEV DEVICE_NR ( CURRENT -> dev) // CURRENT_DEV CURRENT is the device number.
95
// The following two macro is defined as stated function pointer.
106 wake_up (& Bh-> b_wait); // wake wait for the process of the buffer.
107 }
108
// end request processing.
// first designated block off the device and check whether the read buffer valid. If the buffer is valid data // update flag set, and unlocks the buffer parameter values. If the update flag
parameter value is 0, indicating that the requested item of operation has failed, so // display the relevant block device IO error message. Finally, the process of waiting for the wake-up
request item and wait for the items appear idle processes a request, release // and delete this request entry from the request list.
112 if ( CURRENT -> bh) { // CURRENT specified number of the current master device request structure.
124 CURRENT = CURRENT -> next; // delete the item request from the request list, and
126
// define macros initialization request.
130 return; \ // represents a request for entry of this equipment is currently no longer need to be addressed.
131 if ( MAJOR ( CURRENT -> dev) =! MAJOR_NR ) \ // If the current major number of the device is not crash.
132 panic ( DEVICE_NAME ": Request list destroyed"); \
133 if ( CURRENT -> bh) {\
134 if (! CURRENT -> bh-> b_lock) \ // If the buffer is not locked during the operation request crash.
--185--
6.5 hd.c program
139140 #endif
141
hd.c The driver program is a hard disk controller, hard drive controller to provide read and write block and the hard disk device initialization process. All program functions
Function information data structures for disk drives and hard disk initialization, such as sys_setup () with hd_init () ; Send commands to the hard disk controller
function hd_out () ; Hard processing the current function of the requested item do_hd_request () ; Hard disk interrupt handling process called C Functions such as read_intr
do_hd_request () Function will also be read_intr () with write_intr () Was invoked; hard disk controller operation assistance functions, such as controler_ready
reset_controler () Wait.
sys_setup () Function use boot / setup.s Program information provided by the system parameters contained in the hard disk drive is set. Then read the hard disk partition
table and try to copy the virtual root file system image file on the boot disk to the virtual disk memory, if successful mount the virtual disk root file system, otherwise it continues to
hd_init () Function for setting the HDD controller interrupt descriptor kernel initialization, the hard disk controller and an interrupt mask is reset to allow the hard disk
hd_out () A hard disk controller transmits the operation command function. This function takes a call during the interruption C Function pointer parameter, before sending
commands to the controller, it first uses this parameter preset the interrupt process will function pointer calls ( do_hd ), Then it sequentially according to a predetermined manner to
the hard disk controller 0x1f0 to 0x1f7 Sending a command parameter block. In addition to controller diagnostics ( WIN_DIAGNOSE ) And the establishment of drive parameters ( WIN_SPECIFY
Later) other than the two commands, the hard disk controller receiving any other command and execute the command, are to CPU Interrupt request signal, causing the system to
do_hd_request () The requested item is a hard disk operation functions. Which procedure is as follows:
First determines whether the current request entries exist, if the current request pointer entry is null, then the current block is a hard disk device has no pending request
entries, thus immediately exit the program. This is the macro INIT_REQUEST Statement executed. Otherwise, continue processing the current request items.
The disk device number and the start sector number requested items specified in the current request is reasonable to verify; information calculation request entries
provided by the current track of the disk number, cylinder number and head number request data; if the flag is reset ( reset ) Has been set, you can also set the hard
drive to re-correction mark ( recalibrate ), And the hard reset operation, the controller sends back "established drive parameters" command ( WIN_SPECIFY ). This
command does not cause the hard disk interrupt; if recalibration flag is set, then it is hard to send commands to the controller recalibrate ( WIN_RESTORE ), And pre-set
before sending the order triggered interrupts need to be performed C function( recal_intr () ), And exit. recal_intr () The main function of the role is: When the controller
performs end and led to interrupt the command to re (continue) to perform this function. If the current request entry specifies a write operation, the first set of hard disk
--186--
6.5 hd.c program
Send command parameter block write operation, and cycle controller queries the status register to determine whether the service request flag ( DRQ ) Whether the set. If
the flag is set, then the controller is "yes" to receive data, then the request is then put within the meaning of the data buffer controller writing data in the buffer. If the
query timeout after circulating the flag is still not set, then the operation fails. So call bad_rw_intr () Function, according to the current number of processing error
occurring requested item is not continuing to determine the current request needs to be set or reset flag item to continue processing the current request re-entry. If the
current entry is a read operation request, the call set hard disk controller C Function read_intr () And sends the operation command to read the disk controller.
write_intr () It is configured as an interrupt process called when the current request is a write operation item C function. After the controller completes a write command
immediately to disk CPU Send an interrupt request signal, then wrote immediately after the operation is complete will call the function in the controller.
This function first calls win_result () Function, the controller reads the status register to determine whether an error occurred. If an error occurs during the write operation,
the call bad_rw_intr () , According to the number of times an error processing the current request item occurs to determine whether to continue the current request to give up items
still need to reset flag is set to continue processing the current request re-entry. If all of the data if no error occurs, according to the total number of sectors required to write the
current item specified in the request, the request is determined to have the requirement to write disk. If there is data to write disk, then a copy of the data sector to the controller
buffer. When all the data has been written disc, then the processing end of the current issues requested items: Wait for the wake-up process is completed the requested item,
request wake-up process waiting for free entry (if any), set the current request referred to in subparagraph buffer data has been updated logo, release the current request item
(block device removes the entry from the list). Finally, we continue to call do_hd_request () Function to continue processing other requests entry of a hard disk device.
read_intr () The requested item is currently being provided to interrupt the read operation during a call C function. The controller in the specified sector after the data is read
into the buffer from the hard drive of their own, it will send an interrupt request signal immediately. The primary role of the function is to copy data from the controller to the item
versus write_intr () Way to start the same process, which also function first calls win_result () Function, the controller reads the status register to determine whether an error
occurred. If an error occurs during read the disk, and then executed write_intr () Same process. If no errors occurred, the data from the buffer is copied to a sector of the requested
item in the specified buffer. Then the total number of sectors to be read specified in the current item request, determines whether all the data has been read. If there are data to be
read, then exit to wait for a break soon. When all the data has been obtained, the processing end of the current issues requested items: wake-up process is currently waiting for the
completion of the requested item, the process waits for an idle request wake-up items (if any), set the current request referred to in subparagraph buffer data flag has been updated
releases the current request item (block device removes the entry from the list). Finally, we continue to call do_hd_request () Function to continue processing other requests entry of a
In order to see more clearly the process hard disk read and write operations, we can put these functions, the interrupt execution timing relationship between the process
--187--
6.5 hd.c program
execute program Hard disk controller execute program Hard disk controller
time
Interrupt processing
Read Status
command write
As it can be seen from the above analysis, the most important application of the present 4 Functions are hd_out () , do_hd_request () , read_intr () with
write_intr () . Understand this 4 The role of a function also understand the operation of the hard disk driver ☺ .
1/*
2 * Linux / kernel / hd.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
* Since all functions are interrupted in the call, these functions can not sleep. Please pay special attention.
* Modified by Drew Eckhardt, the number of hard disk information detection using CMOS.
*/
15
--188--
6.5 hd.c program
16 #include <linux / config.h> // kernel configuration file header. Define the keyboard language and hard disk type (HD_TYPE) option.
17 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
18 #include <linux / fs.h> // file system header files. Table structure definition file (file, buffer_head, m_inode, etc.).
19 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
20 #include <linux / hdreg.h> // header drive parameters. Accessing the hard disk port register definition information, status code, the partition table and the like.
twenty one #include <asm / system.h> // system header files. Set or modify the defined descriptors / interrupt gate or the like embedded macro assembler.
twenty two #include <asm / io.h> // io header files. Defined hardware port I / O macro assembler statements.
twenty three #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
twenty four
// The following must be defined before the constant major number blk.h file because the file blk.h to use the constant.
26 #include " blk.h " // file header block device. Definition request data structure, the data structure of a block device like functions and macros.
2728 #define CMOS_READ (Addr) ({\ // read CMOS parameter macro function.
34 #define MAX_ERRORS 7 When // allow read / write a sector of the maximum number of errors.
3637 static void recal_intr (Void); // hard disk interrupt program when re-calibration function reset operation will call (287 lines).
3839 static int recalibrate = 1; // recalibration flag. Move the head to cylinder 0.
40 static int reset = 1; // reset flag. When a write error occurs This flag is set to reset the controller and the hard disk.
4142 / *
// each field are the number of heads, number of sectors per track, the number of cylinders, the pre-write precompensation cylinder number, the head landing zone cylinder number, the control
45 struct hd_i_struct {
46 int head , Sect, cyl, wpcom, lzone, ctl;
47 };
// If already defined in HD_TYPE include / linux / config.h header file, which can take as parameters defined // hd_info [] data. Otherwise, the
first default values are set to 0, it will be set in the setup () function.
48 #ifdef HD_TYPE
49 struct hd_i_struct hd_info [] = {HD_TYPE};
50 #define NR_HD ((Sizeof ( hd_info )) / (Sizeof (struct hd_i_struct ))) // count the number of hard disks.
51 #else
52 struct hd_i_struct hd_info [] = {{0,0,0,0,0,0}, {0,0,0,0,0,0}};
53 static int NR_HD = 0;
54 #endif
55
// define hard disk partition structure. Give a physical start sector number of each partition, partitioning the total number of sectors. Wherein //
item (e.g. hd [0], and HD [5], etc.) at a multiple of 5 parameters representative of the entire hard disk.
--189--
6.5 hd.c program
59 } hd [5 * MAX_HD ] = {{0,0},};
60
// read port port, nr words were read, stored in buf.
61 #define port_read (Port, buf , Nr) \
62 __asm __ ( " cld; rep; insw "::" d "( port), " D "( buf ) " c "( nr): " cx "," di ")
63
// write port port, nr words were written, fetch data from buf.
64 #define port_write (Port, buf , Nr) \
65 __asm __ ( " cld; rep; outsw "::" d "( port), " S "( buf ) " c "( nr): " cx "," si ")
6667 extern void hd_interrupt (Void);
// hard disk interrupt process (system_call.s, 221 lines).
68 extern void rd_load (Void); // create a virtual disk loading function (ramdisk.c, 71 lines).
6970 / * This may be used only once, enforced by 'static int callable' * /
/ * The following function is called once during initialization. Static variables callable as a call sign. * / // parameters of the function provided by the initialization program routine init init / main.c to
point at 0x90080, where setup.S // store the program acquired from the hard disk BIOS 2 basic parameters table (32 words section). See the following list of instructions after the hard disk
parameter table information. // This function is the main function of the hard disk parameter table and the CMOS read information to the hard disk partition structure is provided hd, virtual RAM
79 if (! callable)
80 return -1;
81 callable = 0;
// If not defined in the config.h drive parameters, it is read from the 0x90080.
82 #ifndef HD_TYPE
83 for (drive = 0; drive <2; drive ++) {
84 hd_info [Drive] .cyl = * (unsigned short *) BIOS; // number of cylinders.
86 hd_info [Drive] .wpcom = * (unsigned short *) (5 + BIOS); // write precompensation front cylinder number.
87 hd_info [Drive] .ctl = * (unsigned char *) (8 + BIOS); // control byte.
88 hd_info [Drive] .lzone = * (unsigned short *) (12 + BIOS); // Number cylinder head landing zone.
89 hd_info [Drive] .sect = * (unsigned char *) (14 + BIOS); // the number of sectors per track.
90 BIOS + = 16; // parameter table of each disk 16 bytes long, where BIOS points to the next table.
91 }
// setup.S program in the hard disk parameter table information taken in the BIOS, if only a hard disk, will correspond to the second 16-byte hard disk // cleared. Thus here as long as
the second hard disk is determined whether the cylinder number 0 can not know the second hard drive.
94 else
95 NR_HD = 1;
96 #endif
// Set the start sector number and the total number of sectors per disk. Wherein the meaning of number i * 5 refer to the procedure described after.
--190--
6.5 hd.c program
100 hd_info [I] .sect * hd_info [I] .cyl; // total number of sectors of the hard disk.
101 }
102
103 /*
104 We querry CMOS about hard disks: it could be that
105 we have a SCSI / ESDI / etc controller that is BIOS
106 compatable with ST-506, and thus showing up in our
107 BIOS table, but not register compatable, and therefore
108 not present in CMOS.
109
110 Furthurmore, we will assume that our ST-506 drives
111 <If any> are the primary drives in the system, and
112 the ones reflected as drive 1 or 2.
113
114 The first drive is stored in the high nibble of CMOS
115 byte 0x12, the second in the low nibble. This will be
116 either a 4 bit drive type or 0xf indicating use byte 0x19
117 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.
118
119 Needless to say, a non-zero value means we have
120 an AT controller hard disk for that drive.
121122123
*/
/*
* We have some doubts about the information on the hard drive CMOS: may be the case, we have a SCSI / ESDI / etc.
* The controller, which is based on ST-506 is compatible with the way the BIOS, which will appear in our BIOS parameter table, but not
data (fs / buffer.c, 267), the hard disk parameter 0x300 major number // (see list following description). The first two bytes and a hard disk at the sector position
--191--
6.5 hd.c program
// This sector is located 0x1BE beginning of the partition table is valid. Finally, the hard disk partition information into the partition table data structure in hd.
153 }
154 if ( NR_HD ) // if the hard disk is present and has been read partition table, partition table information correctly printed.
155 printk ( ' Partition table% s ok. \ N \ r ", ( NR_HD > 1)? " s ":" ");
156 rd_load (); // Load (create) RAMDISK (kernel / blk_drv / ramdisk.c, 71).
157 mount_root (); // root file system is mounted (fs / super.c, 242).
158 return (0);
159 }
160
//// wait cycle is determined and the drive is ready.
// read status register hard disk controller port HD_STATUS (0x1f7), and loop detection and the drive controller ready bit busy bit. // If the return value is 0,
167 }
168
//// hard state after detecting the command execution. (Win_ an acronym that stands Winchester hard disk)
// read status register command execution result status. 0 indicates a normal return, an error has occurred. If you execute the wrong command, // read the error
--192--
6.5 hd.c program
185
186 if (drive> 1 || head > 15) // If the drive letter (0,1)> 1 or head number> 15, it does not support.
187 panic ( ' Trying to write bad sector ");
188 if (! controller_ready ()) // If you wait a period of time is still not ready errors, crashes.
191 outb_p ( hd_info [Drive] .ctl, HD_CMD ); // the control byte to the output control register (0x3f6).
194 outb_p (Nsect, ++ port); // Parameters: read / write total number of sectors.
198 outb_p (0xA0 | (drive << 4) | head , ++ port); // parameters: number + the drive head number.
200 }
201
//// wait for the hard disk is ready. I.e. wait cycle master controller is busy status flag is reset. If only ready or seek end flag // set, success,
210 i & = BUSY_STAT | READY_STAT | SEEK_STAT ; // detect busy bit, ready position and seek end position.
222 for (i = 0; i <100; i ++) nop (); // wait a period of time (cycle no operation).
223 outb ( hd_info [0] .ctl & 0x0f, HD_CMD ); // normal control byte retransmission (retry does not prohibit, re-read).
224 if ( drive_busy ()) // If the hard disk is ready to wait for a timeout, an error message is displayed.
--193--
6.5 hd.c program
// interrupt occurs when an unexpected hard disk, hard disk interrupt handler C default handler calls. In the called function pointer is null // call the
245 end_request (0); // the end of the request wake-up process and wait for the request, and the
246 if ( CURRENT -> errors> MAX_ERRORS / 2) // if the number of times an error reading a sector has more than 3 times.
248 }
249
//// read interrupt function is called. The process is called interrupt triggered at the end of the hard disk read command.
// This function first determines whether the read command operation error. If the command controller further after the end of a busy state or command error, the hard disk operation // the
process failures, then requests for the hard reset request and performs other processing items.
// If the command is not the read error, the data from the port data register to read a sector in a buffer request entry, and decrements the value requested item // sectors need to be read. If after
decrementing is not equal to 0, indicates that this data item request and did not get finished, then return directly after the interruption // wait another sector of data read out in the hard disk.
Otherwise, all sectors showed that the required items are reading this request, then the processing of this request item // end matters. The last call do_hd_request again (), to handle requests
other hard items. // Note: row statement 256 257 refers to the memory word, i.e. 512 bytes.
253 bad_rw_intr (); // the hard disk read and write process fails
254 do_hd_request (); // then requests the hard disk accordingly (reset) for again.
255 return;
256 }
257 port_read ( HD_DATA , CURRENT -> buffer, 256); // request to read data from the data buffer register port structure.
258 CURRENT -> errors = 0; // clear the number of errors.
259 CURRENT -> buffer + = 512; // adjust the buffer pointer to the new empty area.
261 if (- CURRENT -> nr_sectors) { Sector // If the desired readout number has not yet finished, the
262 do_hd = & read_intr ; // set again hard to call a C function pointer read_intr ()
263 return; // because the hard drive when the interrupt handler do_hd each call
--194--
6.5 hd.c program
265 end_request (1); // if all sector data has been read, the process issues the request ends,
267 }
268
//// sector write interrupt function is called. Hard disk is called the interrupt handler.
// After the write command is executed, the hard disk will generate an interrupt signal, the interrupt handler performs a hard disk, in this case the hard disk // C interrupt handler function pointer
do_hd () call has been directed write_intr (), thus completes the write operation after (or error), the function is executed.
272 bad_rw_intr (); // the first hard disk read and write process fails,
273 do_hd_request (); // then again requests the hard disk for the corresponding (reset) process,
274 return; // then return (also withdrew from the hard disk interrupts).
275 }
276 if (- CURRENT -> nr_sectors) { // Otherwise, the number of sectors to be written minus 1, if there is to write the sector, the
277 CURRENT -> sector ++; +1 // start sector number of the current request,
280 port_write ( HD_DATA , CURRENT -> buffer, 256); // port data register again write 256 words.
281 return; // return until the hard-completed interrupt handling after the write operation again.
282 }
283 end_request (1); // if all sector data has been written, the end of the request process issues,
285 }
286
//// hard disk recalibrate (RESET) interrupt function is called. Hard disk is called the interrupt handler.
// returns an error message if the hard disk controller, the hard disk is first read failure processing, and accordingly requests the hard disk (reset) process.
// If the requested item is a piece of equipment, then the request entry pointer of the current block device (see ll_rw_blk.c, 28 line) directly to the // request entries, and call this function will
immediately perform read and write operations. Otherwise, in a read or write operation to complete the process of interruption caused by the hard disk, the request // if there are items need
to be addressed, it will call this function during the interruption. See kernel / system_call.s, 221 line.
301 INIT_REQUEST ;
// get sub-device number (device number described after the hard see list) of the device number. Sub-device number that is the number of partitions on the hard disk.
302 dev = MINOR ( CURRENT -> dev); // CURRENT defined as blk_dev [MAJOR_NR] .current_request.
303 block = CURRENT -> sector ; // start sector requests.
// If the sub-device number does not exist or is greater than the starting sector number of sectors -2 partition, the request is ended, and the jump to the label // repeat (INIT_REQUEST
defined at the beginning). 2 because of a requirement to read and write sectors (512 bytes * 2), so that the requested sector number is not greater than the partition // penultimate last sector
number.
--195--
6.5 hd.c program
// The following code is embedded in the assembly used to calculate the track sector number // (sec), where the cylinder number (CYL) and head number (head) from the
hard disk information structure according to the start sector number and the number of sectors per track .
310 __asm __ ( " divl% 4 ":" = a "( block), "= d "( sec): "" (block), " 1" ( 0),
311 "R" ( hd_info [Dev] .sect));
312 __asm __ ( " divl% 4 ":" = a "( cyl), "= d "( head ): "" (Block), " 1" ( 0),
313 "R" ( hd_info [Dev]. head ));
314 sec ++;
315 nsect = CURRENT -> nr_sectors; // To read / write the number of sectors.
// If the reset flag is set, the reset operation is performed. And resetting the hard disk controller, and the correction flag is set need to return.
316 if ( reset ) {
317 reset = 0;
318 recalibrate = 1;
319 reset_hd ( CURRENT_DEV );
320 return;
321 }
// If recalibration flag (Recalibrate) is set, then the flag is reset first, and then resend correction command to the hard disk controller. // This command will perform seek
322 if ( recalibrate ) {
323 recalibrate = 0;
324 hd_out (Dev, hd_info [ CURRENT_DEV ] .Sect, 0,0,0,
325 WIN_RESTORE , & recal_intr );
326 return;
327 }
// if the current request is a write sector operation, a write command is sent, the status register read cycle information and determines whether the requested service // DRQ_STAT
flag is set. DRQ_STAT requests a service disk status register bit, indicates that the drive be ready to transfer a word of data between a host and // or a byte of data ports.
request. Otherwise, the data of one sector is written to the hard disk controller port data register HD_DATA.
332 if (! r) {
333 bad_rw_intr ();
334 goto repeat; // The label on the final surface blk.h file, that jumps to 301 lines.
335 }
336 port_write ( HD_DATA , CURRENT -> buffer, 256);
// if the current request is a read hard disk sector, the sector transmits a read command to the hard disk controller.
--196--
6.5 hd.c program
344 {
345 blk_dev [ MAJOR_NR ] .Request_fn = DEVICE_REQUEST ; // do_hd_request ().
346 set_intr_gate (0x2E, & hd_interrupt ); // Set the door hard disk interrupt vector int 0x2E (46).
// hd_interrupt in (kernel / system_call.s, 221).
347 outb_p ( inb_p (0x21) & 0xfb, 0x21); // Reset the mask bits 8259A int2 main pick-linked, allowing the sheet // interrupt
request signal.
348 outb ( inb_p (0xA1) & 0xbf, 0xA1); // reset the hard disk interrupt request mask bits (from the on-chip), allowing the hard disk //
349 }
350
AT Programming register port of the hard disk controller are described in Table 6-2 Fig. Also see include / linux / hdreg.h head File.
table 6-2 AT And the role of hard disk controller register interface
0x1f1 HD_ERROR Error register (error status) Pre-register before the write compensation
0x1f2 HD_NSECTOR Sector Number Register -- The number of sectors (read, write, test, formatting)
0x1f3 HD_SECTOR Sector Number Register -- Starting sector (read, write, test)
0x1f4 HD_LCYL Cylinder number register -- Low byte cylinder number (read, write, test, formatting)
0x1f5 HD_HCYL Cylinder number register -- High byte cylinder number (read, write, test, formatting)
0x1f6 HD_CURRENT Drive / head register - Drive number / head number ( 101dhhhh, d = Drive letter, h = Head number)
0x3f7 Digital input register (with 1.2M Floppy disk combination) ---
This is a pair 16 Bit high speed PIO Data transmitter for a sector read, write and format operations track. CPU Written to or read from the hard disk to the hard disk via the
data register 1 Data sectors, i.e. to the command ' rep outsw ' or' rep insw ' Repeat read / write cx = 256 word. ◆ error register (read) / write pre-compensation before the register
When reading this register storing 8 Error Status bit. But only when the main status register ( HD_STATUS , 0x1f7) Bit 0 = 1
Data in the register is valid. Different meaning when other command when performing diagnostic controller command. Table 6-3 Fig.
--197--
6.5 hd.c program
In the write operation, i.e., the register as register before a write precompensation. It records the write precompensation starting cylinder number. Substantially
corresponds to the hard disk parameter table displacement 0x05 At a word, to be in addition to 4 After the output. ◆ Sector Number Register ( HD_NSECTOR , 0x1f2 )
This register stores read, write, verify, and format commands specified number of sectors. When used in a multi-sector operation, each completed 1 The operation of the
sector register is decremented 1 Until it is 0 . If the initial value 0 , Then the maximum number of sectors transmission 256 . ◆ Sector Number Register ( HD_SECTOR , 0x1f3 )
This register stores read, write, verify operations sector number specified by the command. When multi-sector operation, is stored in the start sector number, and each
completed 1 Automatically by operation of a sector 1 . ◆ cylinder number register ( HD_LCYL , HD_HCYL , 0x1f4 , 0x1f5 )
The two cylinder number registers are stored with a low number of cylinders 8 And high bit 2 Bit. ◆
This register stores read, write, test, and a seek command format specified drive and head number. Its place in the format 101dhhhh . among them 101 He expressed using ECC
And each check code sectors 512 byte; d It represents the selected drive ( 0 or 1 ); hhhh It represents the head selection.
◆ master status register (read) / command register (Write) ( HD_STATUS / HD_COMMAND , 0x1f7)
When reading, corresponding to a 8 Main bit status register. Reflecting the operation state of the hard disk controller before and after the execution of the command.
Command execution error. DESCRIPTION previous command when an error bit to the end. At this time, the syndrome register
0 ERR_STAT 0x01
bits and status register contains some information that caused the error.
1 INDEX_STAT 0x02 Received index. When the disk rotation index mark will encounter this bit is set.
ECC Parity error. When faced with a recoverable data errors and has been corrected, it will set this bit. This does not interrupt a
2 ECC_STAT 0x04
multi-sector read operation.
Data request service. When this bit is set, it indicates that the drive be ready to transfer a byte or a word of data between a
3 DRQ_STAT 0x08
host and a data port.
Drive seek an end. When this bit is set, it indicates a seek operation has been completed, the magnetic head has been stopped on
4 SEEK_STAT 0x10 the specified track. When an error occurs, this bit does not change. Only after the host reads the status register, this bit will indicate
Drive failure (write error). When an error occurs, this bit does not change. Only after the host reads the status register, the bit
5 WRERR_STAT 0x20
error will indicate the current state of the write operation again.
Drive ready (ready). It indicates that the drive is ready to receive commands. When an error occurs, this bit does not change.
Only after the host reads the status register, this bit will indicate the current drive again ready state. When turned on, this bit
6 READY_STAT 0x40
should be reset until the drive accelerates to normal and can receive commands.
Controller busy. When the drive is operating This bit is set by the drive controller. When the host can not send the command
block. Read operations to any command register will return the status register. This bit is set under the following conditions: a
7 BUSY_STAT 0x80 machine reset signal RESET Becomes negative or device control registers SRST After being set 400 Nanoseconds or less. After
--198--
6.5 hd.c program
Recalibration host command register to write, read, read buffer, initializes the drive parameters and perform diagnostics
During a write operation, the write buffer or Format Track commands transmitted 512 Bytes of data 5 Within microseconds.
When performing a write operation, the command register corresponds to the port, accepts CPU Hard disk control command is issued, a total of 8 Types of commands, see Table 6-5
Fig. The last one for the operation of the controller after the end of the corresponding command taken (that caused the break or do nothing).
Table low byte command code 4 Bit is an additional parameter, its meaning is:
R It is stepping rate. R = 0 , The stepping rate is 35us ; R = 1 for 0.5ms Order volume increased. The default program R = 0 .
L Is the data model. L = 0 It indicates a read / write sectors 512 byte; L = 1 It indicates a read / write sectors 512 plus 4 Byte ECC code. The default is the program L = 0 .
T A retry mode. T = 0 Retry is expressed; T = 1 Retry is prohibited. Programs take T = 0 . ◆ hard disk control
This register is write-only. A hard disk used to store the control byte and controls reset operation. Displacement table which defines the basic parameters of the hard disk 0x08
Unused
0x08 byte Place 3 If the number of heads greater than 8 The home 1
Place 4 Unused ( 0)
Place 5 If the number of cylinders + 1 FIG bad area at the manufacturer, then set 1
When operation control of the hard disk controller, need to send parameters and commands. The command format Table 6-7 Fig. First send
--199--
6.5 hd.c program
6 Byte parameters, and finally sent 1 Byte command code. Whatever this command require the complete output 7 Command block bytes sequentially write port 0x1f1 - 0x1f7 . .
port Explanation
First of all CPU The port control register ( HD_CMD) 0x3f6 Output control byte, hard to establish the appropriate control mode. The above embodiment can be established
after the order of transmission parameters and commands. The steps of: detecting an idle state controller: CPU By reading the main status register, if the bit 7 for 0 Indicating that
the controller is idle. If within the prescribed time controller has been in a busy state, the penalty for a timeout error. Test the drive is ready: CPU Analyzing the main status register
bit 6 Whether 1 To see whether the drive is ready. for 1 You can output parameters and commands.
Output command block: in order respectively to a corresponding output port and the output parameter command.
CPU Wait interrupt: command execution, interrupt request signal is generated by the hard disk controller ( IRQ14 - The corresponding interrupt int46 ) Or the controller state is set
to idle, or indicates a request indicating that the operation end sector transmission (multi-sector read / write). Detection Result: CPU The main status register is read again, if the bit 0
equal 0 It means that the command is successful, otherwise fail. If the failure can be further query error register ( HD_ERROR) Take error code.
Interrupt vector table, int 0x41 Interrupt vector location ( 4 * 0x41 = 0x0000: 0x0104 ) Address stored in the program is not interrupted but the first hard disk basic
parameter table, Table 6-8 Fig. for 100% Compatible BIOS , Here kept the first address array of hard disk parameter table F000h: E401h . The second hard disk parameter table
table 6-8 The basic parameters of the hard disk information table
0x03 word The write current begins to decrease cylinder (only PC XT Use, the other for 0)
0x07 byte maximum ECC The burst length (only XT Use, the other for 0 )
Unused
Place 4 Unused ( 0)
Place 5 If the number of cylinders + 1 FIG bad area at the manufacturer, then set 1
- 200 -
6.5 hd.c program
0x09 byte Standard timeout value (only XT Use, the other for 0 )
0x0A byte Formatting timeout value (only XT Use, the other for 0 )
0x0B byte Drive timeout value detector (only XT Use, the other for 0 )
1- RAM, 2- Disk, 3- hard disk, 4-ttyx, 5-tty, 6- Parallel port, 7- Due to non-named pipes 1 A hard disk can exist 1--4 Partition, so the hard disk partition also be specified
depending on the partition with minor number. Thus the hard disk logical device number consists of the following ways:
among them 0x300 with 0x305 Which does not correspond to the partition, but on behalf of the entire hard disk. From linux Kernel 0.95 After using this version is
no longer cumbersome naming, but now using the same naming method.
In order to realize a plurality of operating systems to share resources hard disk, the hard disk can be logically divided into 1--4 Partitions. Between the sector number of
each partition are contiguous. The partition table 4 Table entries, each entry is made 16 Byte, information corresponding to a partition, partition size and storing the cylinder
number, track number and sector number of the start and end, Table 6-10 Fig. Stored in the hard disk's partition table 0 cylinder 0 Head first 1 Sectors
0x00 boot_ind byte Boot flags. 4 Partition at the same time only one partition is bootable.
--201--
6.6 ll_rw_blk.c program
0x00- Not boot the operating system from the partition; 0x80- Operating system from the boot partition.
0x02 sector byte Partition start sector number (bits 0-5) And high starting cylinder number 2 Bit (Bit 6-7) .
0x04 sys_ind byte Partition type byte. 0x0b-DOS; 0x80-Old Minix; 0x83-Linux ...
0x05 end_head byte The end of the head number of the partition.
0x06 end_sector byte End sector number (bits 0-5) And high-end cylinder number 2 Bit (Bit 6-7) .
0x0c - 0x0f nr_sects Long word The number of sectors occupied by partitions.
The main program block device for performing low-level read / write operation, a chapter all block devices and other parts of the system interface program. Other program
functions through the lower block calls to read and write the program ll_rw_block () Reading and writing data to the block device. The main function of the device function is to create a
block write request entry as a block device, and the device is inserted into the specified block in the request queue. The actual read and write operations are requested item by the
device handler request_fn () carry out. For the operation of the hard disk, the function is do_hd_request () ; For floppy operations, the function is do_fd_request () ; For the virtual disk is do_rd_request
() . If the ll_rw_block () Is a block device to establish a requested item, and tested in block device entry pointer of the current request is determined when the device is idle empty, the
new request will be provided for the current item request entries, and to direct calls request_fn ()
Operate the requested item. Otherwise it will use the new algorithm to lift request entry into the request necklace table of the device for processing. And when request_fn () End
processing of a request for entry, it will put the request to delete items from the list.
due to request_fn () At the end of each requested item processing will break through the callback C Function (mainly read_intr () with
write_intr () ) Called again request_fn () Request itself to process the remaining items in the list, so long as the request table necklace apparatus (or as queues) in the presence of a
pending request entries, all of which will be processed until the request table of the device is a necklace empty. When requested necklace empty table, request_fn () It will not send
commands to the drive controller, but quit immediately. Therefore, request_fn () This concludes the cycle calling function. Referring to FIG. 6-4 Fig.
--202--
6.6 ll_rw_blk.c program
ll_rw_block ()
Triggered interrupts
Table interrupt request necklace Call request_fn () interrupted process
Call request_fn ()
For virtual disk device, because of its read and write operations do not involve the above hardware synchronization with the outside world, so there is no such interrupt
processing. Entry of the current request read and write operations in the virtual device entirely do_rd_request () Implemented.
1/*
2 * Linux / kernel / blk_dev / ll_rw.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
*/
10 #include <errno.h> // error number header files. The system comprises various error number. (Linus from the introduction of minix)
11 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
12 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
13 #include <asm / system.h> // system header files. Set or modify the defined descriptors / interrupt gate or the like embedded macro assembler.
1617 / *
--203--
6.6 ll_rw_blk.c program
/*
* Request structure that contains all the necessary information is loaded nr sector data into memory.
*/
twenty one struct request request [ NR_REQUEST ];
2223 / *
29 * do_request-address
30 * next-request
31 * /
/ * Blk_dev_struct block device structure: (kernel / blk_drv / blk.h, 23)
* do_request-address // pointer to the corresponding request handler major number.
disk driver // initialize (hd.c, 343 lines), i.e., a first statement for setting blk_dev [3] content.
45 while (bh-> b_lock) // If the buffer is locked, then sleep until the buffer is unlocked.
46 sleep_on (& Bh-> b_wait);
47 bh-> b_lock = 1; // immediately lock the buffer.
48 sti (); // open the interruption.
49 }
50
// release (unlocked) lock buffers.
51 static inline void unlock_buffer (Struct buffer_head * Bh)
52 {
53 if (! bh-> b_lock) // If the buffer is not locked, then print an error message.
54 printk ( ' ll_rw_block.c: buffer not locked \ n \ r ");
55 bh-> b_lock = 0; // clear lock flag.
56 wake_up (& Bh-> b_wait); // wake task waiting for the buffer.
57 }
5859 / *
--204--
6.6 ll_rw_blk.c program
70 if (req-> bh)
71 req-> bh-> b_dirt = 0; // clear buffer "dirty" flag.
// If the current sub-segment dev request (current_request) is empty, then the device is not currently requested item, this is the first request entries // 1, and therefore the device can block
the current request pointer entry directly to the request, and immediately function execution request corresponding device.
75 (Dev-> request_fn) (); // function execution apparatus a request for a hard disk is do_hd_request ().
76 return;
77 }
// If present, the device has been requested items are waiting, first use the elevator algorithm searches for the best insertion position, and then insert the current request // the request list. The
role of the elevator algorithm is to make the smallest disk head movement distance, thereby improving hard disk access time.
88 static void make_request (Int major, int rw, struct buffer_head * Bh)
89 {
90 struct request * Req;
91 int rw_ahead;
9293 / * WRITEA / READA is special case - it is not really needed, so if the * /
94 / * Buffer is locked, we just forget about it, else it's a normal read * /
/ * WRITEA / READA is a special case - they do not need, so if the buffer has been locked * / / * We can not ignore it and quit, otherwise
// Here 'READ' and meaning 'WRITE' behind the 'A' character on behalf of the English word Ahead, indicate in advance the pre-read / write data blocks. // For the command is case
READA / WRITEA when the specified buffer is in use and has been locked, abandoned pre-read / write requests. // otherwise operate as normal READ / WRITE command.
--205--
6.6 ll_rw_blk.c program
98 if (rw == READA )
99 rw = READ ;
100 else
101 rw = WRITE ;
102 }
// If the command is not a READ or WRITE said kernel is wrong, an error message and crashes.
end of the queue // start operation, and a write request from the search to only fill an empty entry at the head of the queue queue 2/3.
117 else
118 req = request + (( NR_REQUEST * 2) / 3); // For a write request, the queue pointers to 2/3 of the queue.
119 / * Find an empty request * /
/ * Search for an empty request item * /
// search forward from the rear, when dev field value of the request structure request = -1 indicates that unoccupied.
pointers has been searched over the head), then view this times whether the request is // read ahead / write (READA or WRITEA), if it is to give up the request. Otherwise, make
this request sleep (wait request queue // make room for items), after a while again search request queue.
124 if (req < request ) { // If there is no empty request queue entry, then
125 if (rw_ahead) { // If it is ahead of the read / write requests, then unlock the buffer exit.
// program execution to here indicates an idle request to find items. See request structure (kernel / blk_drv / blk.h, 23).
133 req-> dev = bh-> b_dev; // Device No.
--206--
6.7 ramdisk.c program
136 req-> sector = Bh-> b_blocknr << 1; // start sector. Block number is converted into sector number (sector 2 = 1).
142 add_request (Major + blk_dev , Req); // added to the request queue entry (blk_dev [major], req).
143 }
144
//// low-level function blocks to read and write data, a block device interface to the rest of the system function.
// This function is called fs / buffer.c in. The main function is to create a block write request entry device and the device is inserted into the specified block in the request queue. // actual reading
and writing operations is () function is performed by request_fn device. For the operation of the hard disk, the function is do_hd_request (); // for floppy operations, the function is do_fd_request
(); for the virtual disk is do_rd_request (). // Further, it is necessary to read / write block device information has been saved in the buffer header structure, such as device number, block number.
// Parameters: rw - READ, READA, WRITE command or WRITEA; bh - Data block header buffer pointer.
155 }
156
//// block device initialization function, invoked by the initialization program main.c (init / main.c, 128). // array initialization request, the request
entry into an idle all items (dev = -1). There are 32 (NR_REQUEST = 32).
This document is a virtual memory disk ( Ram Disk ) Driver by Theodore Ts'o prepared by. A virtual disk apparatus to simulate the actual physical memory using the disk
storage data. Its main purpose is to increase the speed of read and write operations on the "Disk" data. In addition to the need
--207--
6.7 ramdisk.c program
Some take up valuable memory resources, its main drawback is that once a system crash or shut down all virtual disk data will be lost. Therefore, the virtual disk is usually stored
some of the commonly used system commands such as utilities or temporary data, rather than an important input document.
When linux / Makefile File defines constants RAMDISK , Kernel initialization program will draw a constant value that specifies the size of the virtual memory area for storing
data in the disk memory. DETAILED located position of the virtual disk in physical memory is determined at the kernel initialization phase ( init / main.c , 123 Line), which is located
between the kernel buffer cache and main memory area. If the operation of the machine contains 16MB Physical memory, the virtual disk area will be set in memory 4MB At the
beginning of the virtual disk capacity that is equal to RAMDISK Value ( KB ). If the
RAMDISK = 512 , See the case where the memory 6-5 Fig.
Map 6-5 Virtual disk 16MB Specific memory location in which the system
Virtual disk read and write access to the device operate in full accordance with the principle of common disk operations, but also need to follow the way of access to the
block device to read and write operations. Since not involved in the realization of synchronous operation with the controller or an external device, and therefore it is relatively
simple implementation. For data only need to perform memory copy operations to data blocks in the "transmission" between the system and device.
This program includes 3 Functions. rd_init () It will be at system initialization init / main.c Program calls for determining the position and size of the specific virtual disk in
physical memory; do_rd_request () Requested item is a function of the operation of the virtual disk apparatus, the current request access to virtual disk data entry operation; rd_load
() It is a virtual root file loading function. In the system initialization, the function is used to attempt to block position designated disk from the beginning of the boot disk to load a
root file system to the virtual disk. In function, the start position is defined as disk blocks
256 . Of course, you can also change this value according to their specific requirements, as long as the disk capacity specified in this value can hold the kernel image file.
Such a boot image file by the kernel ( Bootimage ) Plus root file system image file ( Rootiamge ) A combination of "combo" disc, you can start like DOS As the system disk to
boot Linux system. About this way of making composite disc left to the reader to consider.
Before the normal root file system load is performed, the system will first perform rd_load () Function, the first attempt from disk 257 Root file system reads the block
superblock. If successful, put the root file virtual disk image file into memory, and the root file system device mark
ROOT_DEV As a virtual disk device ( 0x0101 ), Otherwise exit rd_load () The system continues to perform root from the other device file load operation.
1/*
2 * Linux / kernel / blk_drv / ramdisk.c
3*
4 * Written by Theodore Ts'o, 12/2/91
5*/
/ * Compiled by Theodore Ts'o, 12/2/91
*/
--208--
6.7 ramdisk.c program
// Theodore Ts'o (Ted Ts'o) is the linux community of famous people. Linux is popular in the world has his big // credit, back in the Linux operating system
has just come out, and he with great enthusiasm to provide for the development of linux maillist, and // first established in North America the linux ftp site
(tsx-11.mit.edu), and remains, to provide services for the majority of linux users //. One of the greatest contribution he has made to linux is proposed and
implemented ext2 file system. The file system has become the de facto world // linux file system standard. He recently launched the ext3 file system,
greatly improving the efficiency // stability and access to the file system. As respected for his first 97 (2002) Journal of linuxjournal him as a // Cover, and
interviewed him. Currently, he is the IBM linux Technology Center, and engaged in work on LSB // (Linux Standard Base) and other aspects. (His home
page: http: //thunk.org/tytso/)
67 #include <string.h>
// string header file. Mainly defines the built-in functions related to operation of the string.
89 #include <linux / config.h> // kernel configuration file header. Define the keyboard language and hard disk type (HD_TYPE) option.
10 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
11 #include <linux / fs.h> // file system header files. Table structure definition file (file, buffer_head, m_inode, etc.).
12 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
13 #include <asm / system.h> // system header files. Set or modify the defined descriptors / interrupt gate or the like embedded macro assembler.
14 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
15 #include <asm / memory.h> // memory copy header files. Containing memcpy () macros embedded assembly function.
// virtual disk function of the current term operation request. Program structure and do_hd_request () is similar to (hd.c, 294). // After the establishment of a virtual disk (rd) in the claims, the
terms lower block device interface function ll_rw_block () and added to the list in rd, // This function is called rd the current request for processing items. The function first calculates the
value of the byte length corresponding to the number of sectors the current len requested item specified in the start position corresponding to the start sector @ addr requirements and
which virtual disk memory, and in accordance with the request command entry // operation. If the write command WRITE, put the request referred to in subparagraph data buffer is copied
directly to the memory location addr // place. If the read operation and vice versa. End_request can directly call the data has been copied () to make this request entry process ends. // then
twenty four {
25 int len;
26 char * Addr;
27
// Check the legitimacy of the item request, Ruoyi not request entry to exit (see blk.h, 127).
28 INIT_REQUEST ;
// The following statement is made corresponding to the start sector ramdisk memory start position and length of the memory.
// sector << 9 wherein represents sector * 512, CURRENT defined as (blk_dev [MAJOR_NR] .current_request).
29 addr = rd_start + ( CURRENT -> sector << 9);
30 len = CURRENT -> nr_sectors << 9;
// if the number is not sub> 1 at the end of a virtual disk or a memory corresponding to the start position, the end of the request, and to repeat the jump. // repeat reference defined
within the macro INIT_REQUEST, located at the beginning of the macro, see blk.h, 127 rows.
--209--
6.7 ramdisk.c program
43 } Else
44 panic ( ' unknown ramdisk-command ");
After successful treatment // requested item, set the update flag. And proceed to the next processing device of the present entry request.
45 end_request (1);
46 goto repeat;
47 }
4849 / *
// virtual disk initialization function. Determining a virtual disk memory starting address, length. And the entire virtual disk area cleared.
*/
//// try to load the root file system to a virtual disk.
// This function () is called (hd.c, 156 lines) is provided in the kernel function setup. Further, a disk block = 1024 bytes.
71 void rd_load (Void)
72 {
73 struct buffer_head * Bh; // pointer to the cache block header.
77 int nblocks;
--210--
6.7 ramdisk.c program
85 return;
// read floppy disk block 256 1,256,256 + + 2. breada () for reading the specified block of data, and also need to read the block mark, then // return buffer pointer
contains data block. If it returns NULL, then the data block is unreadable (fs / buffer.c, 322). // here refers to the super block + 1 blocks on the disk.
// If the number of blocks is greater than the number of memory blocks can be accommodated in the virtual disk is not loaded, an error message and returns. Otherwise, display // Load data
block information.
104 cp = rd_start ;
105 while (nblocks) {
106 if (nblocks> 2) // if the number of blocks to be read more than 3 Pilot Pre fast read mode is used to read the data block.
--211--
6.8 floppy.c program
122 }
123 printk ( "\ 010 \ 010 \ 010 \ 010 \ 010done \ n ");
124 ROOT_DEV = 0x0101; // modify ROOT_DEV to point to a virtual disk ramdisk.
125 }
126
This procedure is the floppy disk controller driver. As with other block device drivers, the program also function operation request entry
Considering the floppy disk drive motors typically does not turn on when not working, so before you can actually read and write to a floppy disk drive, we need to wait for
the motor to start and reach normal operating speed. Compared with the running speed of the computer, the longer this period of time, usually required 0.5
Or so seconds.
Further, when a disk read and write operation is complete, and we need to stop the rotation of the drive, the disk surface to reduce friction paint. But we can not operate on
the disk immediately after it is stopped. Because, you may soon need to be read and write operations. Therefore, after a drive that does not need to drive or operate idle for some
time, waiting for the possible arrival of read and write operations, if the drive is not operating in a longer period of time, the program to make it stop. This time can be set to maintain
When a disk read and write error occurs, or some other cases cause a drive motor is not turned off. At this point we also need to let the system automatically after
a certain time to turn it off. Linus In this program, the delay value is set 100 second.
Thus, when the floppy disk drive will be used to operate a lot of delay (timing) of operation. Thus the timing involves more processing functions in the driver. There are
several functions that deal with the relationship between the timing was placed relatively close kernel / sched.c (Line 201-262 ). This is the biggest difference between the hard disk
and floppy disk driver the driver, floppy driver is complex reasons than the hard disk driver.
While this procedure is relatively complicated, but the principle has a floppy disk read and write operations with other blocks are the same devices. This procedure is the
use of the request and the request entries necklace table structure to handle all read and write operations of the floppy disk. Thus the function key operation request do_fd_request
() It remains one of the important functions of this program. In reading should be the function of the main line. In addition, a floppy disk controller is more complex, involving many
execution state flag and a controller. Therefore, when reading, the need for a description with reference to the program file header, and frequently the Program include / linux /
fdreg.h . This file defines all parameters constant floppy disk controller, and explains the meaning of these constants.
1/*
2 * Linux / kernel / floppy.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
--212--
6.8 floppy.c program
* 02.12.91 - Modify a static variable, and to accommodate the reset correction operation again. This makes certain things
* Make it more convenient (output_byte reset inspection), and means that the interrupt jump on error
* And I have only one floppy drive. Also, I should do more troubleshooting work, as well as to correct more errors.
* For some floppy disk drives, this procedure if there are some problems. I have tried to be corrected,
* But we can not guarantee that the problem has disappeared.
*/
2122 / *
twenty three * As with hd.c, all routines within this file can (and will) be called
twenty four * By interrupts, so extreme caution is needed. A hardware interrupt
25 * Handler may not sleep, or a kernel panic will happen. Thus I can not
26 * Call "floppy-on" directly, but have to set a special timer interrupt
27 * Etc.
28 *
29 * Also, I'm not certain this works on more than floppy 1. Bugs may
30 * Abund.
31 * /
/*
* As hd.c files, all routines in the file can be interrupted calls, so they need special
* Be careful. Hardware interrupt handlers can not sleep, otherwise the kernel silly out (crash) ☺ . It is not
* Direct call "floppy-on", but only to set up a special timer interrupt and so on.
*
* In addition, I can not guarantee that the program can work on more than one floppy drive systems, there may be errors.
*/
3233 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
34 #include <linux / fs.h> // file system header files. Table structure definition file (file, buffer_head, m_inode, etc.).
35 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
36 #include <linux / fdreg.h> // floppy header. Definitions of parameters comprises the floppy disk controller.
37 #include <asm / system.h> // system header files. Set or modify the defined descriptors / interrupt gate or the like embedded macro assembler.
38 #include <asm / io.h> // io header files. Defined hardware port I / O macro assembler statements.
39 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
47
--213--
6.8 floppy.c program
// current digital output register (Digital Output Register), defined in sched.c, 204 rows. // This variable is an important indicator of the
variable floppy operation, description of the DOR register, see after the procedure.
51 __asm __ ( " outb% 0,% 1 \ n \ tjmp 1f \ n1: \ tjmp 1f \ n1: "::" a "(( char) (val)), " i "( port))
52
// definition of these two devices for computing the floppy disk number. Minor number = TYPE * 4 + DRIVE. See the list after the calculation method.
55 / *
56 * Note that MAX_ERRORS = 8 does not imply that we retry every bad read
57 * Max 8 times - some types of errors increase the errorcount by 2,
58 * So we might actually retry only 5-6 times before giving up.
59 * /
/*
* Note that the following definitions MAX_ERRORS = 8 does not mean trying to up to eight times for each read errors - some types
* Error error count value will be multiplied by 2, so we really just try 5-6 times before giving up operation can be.
*/
60 #define MAX_ERRORS 8
6162 / *
// each bit in the status byte of these parameters, see include / linux / fdreg.h header file.
65 #define MAX_REPLIES 7 // FDC return result information up to 7 bytes.
66 static unsigned char reply_buffer [ MAX_REPLIES ]; // store the result response information returned by the FDC.
67 #define ST0 ( reply_buffer [0]) // Returns status byte 0.
68 #define ST1 ( reply_buffer [1]) // Returns status byte 1.
69 #define ST2 ( reply_buffer [2]) // Returns status byte 2.
70 #define ST3 ( reply_buffer [3]) // Returns status byte 3.
7172 / *
* "Search for the correct type" - type of code to handle because of its puzzling and strange. This program
* I have encountered many problems.
*
* Some types of flexible disk (for example, a 360kB 1.2MB floppy disk drive, etc.), 'stretch' for
* Detecting whether a track require special handling. Other parameters should be self-explanatory.
*/
// floppy disk parameters:
// size Size (number of sectors);
--214--
6.8 floppy.c program
// spec1 Parameters (four high step rate, lower four head unloading time).
* Spec1 parameter is 0xSH, where S is the step rate (F-1 millisecond, E-2ms, D = 3ms, etc.),
105 extern char tmp_floppy_area [1024]; // boot / head.s 132 at line buffer floppy defined.
106107 / *
108 * These are global variables, as that's the easiest way to give
109 * Information to interrupts. They are the data used for the current
110 * Request.
111 * /
/*
* Here are some global variables, because this is the information to interrupt the program the easiest way. They are
*/
112 static int cur_spec1 = -1;
113 static int cur_rate = -1;
114 static struct floppy_struct * floppy = floppy_type ;
115 static unsigned char current_drive = 0;
--215--
6.8 floppy.c program
// lower 2 bits digital output register (the DOR) for specifying the selected floppy (0-3 corresponds AD).
* When the floppy disk can not sleep: So at this time can only use round-robin fashion.
*/
//// floppy diskette replace the specified detection conditions. If the disk is replaced returns 1, otherwise it returns 0.
--216--
6.8 floppy.c program
within the 1M address range. If the disk is write command, you need to take to copy data to the staging area.
// port single channel mask register 0x10. Bits 0-1 specify the DMA channel (0--3), Bit 2: 1 for shielding, 0 indicates permission request.
--217--
6.8 floppy.c program
// before sending a byte to the controller, the controller needs to be in the ready state, and data transmission direction is CPU FDC, // so the controller must first read
the status information. This uses the query cycle ways to make appropriate delay.
208 reset = 1;
209 printk ( ' Unable to send byte to FDC \ n \ r ");
210 }
211
//// read result information FDC execution.
// up to 7 bytes of the result information, stored in reply_buffer [] in. Returns the number of bytes to read the result, if the return value // = -1 indicates an error. Program
216 if ( reset )
217 return -1;
218 for (counter = 0; counter <10000; counter ++) {
219 status = inb_p ( FD_STATUS ) & ( STATUS_DIR | STATUS_READY | STATUS_BUSY );
// If the controller is READY state, has no data showing Preferably, it returns the number of bytes read.
--218--
6.8 floppy.c program
234 {
235 CURRENT -> errors ++; // current request item number by 1 error.
// If the current request item number of errors greater than the maximum allowed number of errors, then deselect the current floppy drive, and ends the request item (// buffer zone
It is called (Bottom half) // interrupt processing operation at the end of the floppy disk controller triggered in.
message is displayed, the current drive is released, and ends the current request entry. Otherwise, execution error // counting process. Then proceed to the floppy request
entry operation. The meaning of the following states see fdreg.h file. // (0xf8 = ST0_INTR | ST0_SE | ST0_ECE | ST0_NR)
// (0xbf = ST1_EOC | ST1_CRC | ST1_OR | ST1_ND | ST1_WP | ST1_MAM, should be 0xb7) // (0x73 = ST2_CM | ST2_CRC |
ST2_WC | ST2_BC | ST2_MAM)
252 if ( result ()! = 7 || ( ST0 & 0xf8) || ( ST1 & 0xbf) || ( ST2 & 0x73)) {
253 if ( ST1 & 0x02) { // 0x02 = ST1_WP - Write Protected.
254 printk ( ' Drive% d is write protected \ n \ r ", current_drive );
255 floppy_deselect ( current_drive );
256 end_request (0);
257 } Else
258 bad_flp_intr ();
259 do_fd_request ();
260 return;
261 }
// If the current request buffer items located 1M address above, then read the contents of the floppy disk is also placed in the temporary buffer // buffer needs to be copied to the item's
current request (because the DMA can only 1M addressable address range).
262 if ( command == FD_READ && (unsigned long) ( CURRENT -> buffer)> = 0x100000)
263 copy_buffer ( tmp_floppy_area , CURRENT -> buffer);
// release the current floppy drive (do not give up selected), execution of the current term ends request processing: Wake wait until the request items are, waiting wake empty // request free
entry process (if any), from the floppy device requests necklace table To remove this request item. A floppy disk and then continue with other requests // entry operation.
--219--
6.8 floppy.c program
272 do_floppy = rw_interrupt ; // set the floppy disk interrupt call the function pointer.
278 output_byte (2); / * Sector size = 512 * / // parameters (number of bytes (N = 2) 512 bytes).
279 output_byte ( floppy -> sect); // parameters (number of sectors per track).
280 output_byte ( floppy -> gap); // (sectors interval length).
281 output_byte (0xFF); / * Sector size (0xff when n! = 0?) * /
// parameters (when N = 0, the sector is defined byte length), here useless.
// reset when the flag is set, then proceed to the next floppy operation request.
282 if ( reset )
283 do_fd_request ();
284 }
285 286 /
*
287 * This is the routine called after every seek (or recalibrate) interrupt
288 * From the floppy controller. Note that the "unexpected interrupt" routine
289 * Also does a recalibrate, but does not come here.
290 * /
/*
* This subroutine is called after each seek floppy disk controller (or recalibration) interrupted. note
* "Unexpected interrupt" (unexpected interruption) will perform the recalibration routine operations, but not here.
*/
Function is called during the end //// seek treatment interruption.
// first transmission detector interrupt status command, status information to obtain location information ST0 and track the magnetic head. If the error count is performed // an error
detection process or cancel the operation request entry diskette. Otherwise, set the current track information according to the state variables, and then calls the function //
setup_rw_floppy () Set the floppy disk and outputs the DMA write and read commands and parameters.
to the set track, an error occurs, the error count detecting process is then performed, then continue floppy // request entry and exit.
302 }
303
--220--
6.8 floppy.c program
304 / *
305 * This routine is called when everything should be correctly set up
306 * For the transfer (ie floppy motor is on and the correct floppy is
307 * Selected).
308 * /
/*
* This function is (that is after all the information in the floppy motor transport operations are set up properly invoked turned
* And you have selected the correct floppy disk (floppy drive).
*/
//// read and write data transfer function.
4 high step rate, lower four head unloading time; Parameter 2: head loading time).
(FD_DCR).
319 if ( reset ) {
320 do_fd_request ();
321 return;
322 }
// If the seek flag is zero (no tracking), is set DMA read and write operations and send appropriate commands and parameters, and then returns.
323 if (! seek ) {
324 setup_rw_floppy ();
325 return;
326 }
// otherwise perform seek treatment. Floppy disk interrupt handler function is set to seek an interrupt function calls.
328 if ( seek_track ) {
329 output_byte ( FD_SEEK ); // send head seek command.
330 output_byte ( head << 2 | current_drive ); // transmission parameters: the current head number + number floppy.
332 } Else {
333 output_byte ( FD_RECALIBRATE ); // resend correction command (zero head).
334 output_byte ( head << 2 | current_drive ); // transmission parameters: the current head number + number floppy.
335 }
// If the reset flag is set, then continue with the floppy requested item.
336 if ( reset )
337 do_fd_request ();
338 }
339 340 /
*
341 * Special case - used after a unexpected interrupt (or reset)
--221--
6.8 floppy.c program
342 * /
/*
* For the unexpected interruption (or reset) process - a special case.
*/
//// floppy recalibration interrupt function is called.
// send first detection interrupt status command (no parameters), if the return results show an error, then reset flag is set, otherwise reset again // correction mark. Floppy disk and then
346 if ( result ()! = 2 || ( ST0 & 0xE0) == 0x60) // if the number of results returned is not equal to 2 bytes or command
351 }
352
//// accident floppy disk interrupt request interrupt function is called.
// send first detection interrupt status command (no parameters), if the return results show an error, then reset flag is set, otherwise it is set to re-// correction mark.
356 if ( result ()! = 2 || ( ST0 & 0xE0) == 0x60) // if the number of results returned is not equal to 2 bytes or command
359 recalibrate = 1;
360 }
361
//// floppy recalibration handler.
// send commands and parameters recalibration, and resets the flag to recalibrate the floppy disk controller FDC.
366 do_floppy = recal_interrupt ; // set the floppy disk interrupt call a function pointer to recalibrate the calling function.
368 output_byte ( head << 2 | current_drive ); // add transmission parameters :( head number) current drive letters.
369 if ( reset ) // If the error (the reset flag is set) proceed floppy request.
370 do_fd_request ();
371 }
372
//// floppy disk controller FDC reset interrupt function is called. In the floppy disk interrupt handler calls.
// first transmission detection interrupt status command (without parameters), then the readout results of bytes returned. Then send commands to set parameters // floppy and related
377 output_byte ( FD_SPECIFY ); // send command to set the floppy drive parameters.
--222--
6.8 floppy.c program
381 }
382 383 /
*
384 * Reset is done by pulling bit 2 of DOR low for a while.
385 * /
/ * Reset by the FDC digital output register (the DOR) Bit 2 0 achieved while * / //// reset the floppy disk
controller.
386 static void reset_floppy (Void)
387 {
388 int i;
389
390 reset = 0; // reset flag set to zero.
391 cur_spec1 = -1;
392 cur_rate = -1;
393 recalibrate = 1; // recalibration flag.
394 printk ( ' Reset-floppy called \ n \ r "); // reset operation information display performed diskette.
396 do_floppy = reset_interrupt ; // set the floppy disk interrupt handler function call.
397 outb_p ( current_DOR & ~ 0x04, FD_DOR ); // reset operation of the floppy disk controller FDC.
402 }
403
//// floppy start timer interrupt function is called.
// first check digital output register (DOR), so as to select the specified drive current. Then call // function to perform read and write transfers floppy transfer ().
// timer tick time delayed by 2, then the transfer function calls to read and write a floppy disk transfer (). Otherwise called directly floppy disk read and write transfer function.
412 add_timer (2,& transfer ); // add a timer and execute the transfer function.
413 } Else
414 transfer (); // perform reading and writing floppy transfer function.
415 }
416
//// floppy disk write request entries handler. //
--223--
6.8 floppy.c program
422 if ( reset ) {
423 reset_floppy ();
424 return;
425 }
// If recalibration flag is set, then re-execute the floppy correction operation and return.
426 if ( recalibrate ) {
427 recalibrate_floppy ();
428 return;
429 }
// Check the legitimacy of the item request, Ruoyi not request entry to exit (see blk.h, 127).
430 INIT_REQUEST ;
// the type of floppy diskette request entry structure of the device number (MINOR (CURRENT-> dev) >> 2) to obtain a floppy disk as an index into the parameter block.
the end of the second floppy disk requested item, a request to perform the next item.
435 block = CURRENT -> sector ; // get current item request floppy start sector number block.
436 if (block + 2> floppy -> size) { // If block + 2 is greater than the total number of disk sectors are
440 sector = Block% floppy -> sect; // start sector modulo the number of sectors per track, the track sector number obtained.
441 block / = floppy -> sect; // rounded start sector number of sectors per track to give the starting track number.
442 head = Block% floppy -> head ; // start track number modulo of the number of heads, the head number to obtain operation.
443 track = Block / floppy -> head ; // starting track number for the number of heads rounding operations to obtain the track number.
444 seek_track = track << floppy -> stretch; // corresponding to the type of the disk drive is adjusted to obtain tracking number.
// If the seek current head number of the track where different, the flag is set to require a seek seek.
448 if ( CURRENT -> cmd == READ ) // If the request entry is a read operation, a read command code is set to a floppy disk.
// Set the request handler diskette block device (do_fd_request ()), and set the diskette interrupt gate (int 0x26, // hardware interrupt request signal corresponding to IRQ6), and then
cancel the interrupt mask signal, which allows the transmission floppy disk controller FDC interrupt request signal.
--224--
6.8 floppy.c program
460 set_trap_gate (0x26, & floppy_interrupt ); // set the floppy disk interrupt gate int 0x26 (38).
461 outb ( inb_p (0x21) & ~ 0x40,0x21); // reset interrupt request mask bit floppy disk, the floppy disk controller
462 }
463
in Linux , The major number of floppy 2 Minor number = TYPE * 4 + DRIVE ,among them DRIVE for 0-3 , Respectively floppy A , B , C or D ; TYPE Is the type
of floppy, 2 Show 1.2M Floppy drive, 7 Show 1.44M Floppy drive, that is floppy.c in 85
Line defines diskette type ( floppy_type [] ) Array index value, see Table 6-11 Fig.
Types of Explanation
0 No need to.
For example, because 7 * 4 + 0 = 28 ,and so / dev / PS0 (2,28) Refers 1.44MA Driver, which is a device number 0x021c . Similarly / dev / at0 (2,8) Refers 1.2MA
Programmed floppy disk controller is relatively cumbersome. For access to programming 4 Ports, respectively corresponding to one or more registers. for 1.2M
0x3f2 just write Digital Output Register ( DOR ) (Digital Control Register)
Digital Output DOR (Digital control port) is a 8 Bit register which controls the drive motor is turned on, the drive selection, start / reset FDC As well as enable /
disable DMA And interrupt request. Each bit of this register See Table 6-13 Fig.
--225--
6.8 floppy.c program
3 DMA_INT allow DMA And interrupt request; 0- Ban DMA And interrupt request.
2 RESET Allowing the floppy disk controller FDC jobs. 0- Reset FDC .
1 DRV_SEL1 0
FDC The status register is a main 8 Bit register is used to reflect the floppy disk controller FDC And a floppy disk drive FDD The basic state. Typically, CPU to FDC Before
sending a command or from FDC Before obtaining the operation result, the master must read the status register bits, to discriminate the current FDC Data register is ready and
5 NDM non- DMA the way: 1- non- DMA the way; 0- DMA the way
FDC A plurality of registers corresponding to the data port (write only type parameter register and the command register, read-only result register), but any one time, only
one appears in the data port register 0x3f5 . When accessing the write-only register, the main state control DIO Direction bit must be 0 ( CPU FDC ), And vice versa when the read
access type register. When reading the results only in FDC After reading the results considered busy, usually resulting data Up 7 Bytes.
Data input register ( DIR ) Only bits 7 ( D7 ) Floppy effectively used to represent the state of the disk replacement. The remaining seven for a hard disk controller interface.
Disk Control Register ( DCR) Rate selection for data transmission disc for use on different types of drives. Use only low 2 Bit ( D1D0 ),
Controller, floppy disk controller and programming. for 386 compatible PC , Floppy controller uses hardware interrupts IR6 (Corresponding to the Interrupt Descriptor 0x26 ), And
using DMA Channel controller 2 . related DMA Control process see later section.
The floppy disk controller can accept a total of 15 Command. Each command through three stages: the command phase, implementation phase and the results stage.
Command stage CPU to FDC Send command byte and parameter bytes. The first byte of each command byte is always the command (command code). Thereafter followed 0--8 Byte
parameters.
--226--
6.8 floppy.c program
The implementation phase is FDC Perform the operation specified command. In the implementation phase CPU That without intervention, usually through FDC It issues an
interrupt request to know the end of the command execution. in case CPU dispatched FDC Command is transmitted data, FDC You can interrupt or DMA Conducted. Interrupt each
transfer 1 byte. DMA Way in DMA Controller Management, FDC Transmitting data to and from memory until all of the data transferred. at this time DMA Controller will signal the
transfer byte count termination FDC Finally, the FDC Issues an interrupt request signal inform CPU The implementation phase is completed.
The result is a stage CPU Read FDC Data register return value, to thereby obtain FDC The results of the command execution. Return result data length 0--7 byte. For data
command does not return results, should the FDC Interrupt Status command transmission detecting operation state is obtained.
due to Linux 0.11 Floppy disk driver use only 6 Command, so the commands used here only for description.
This command is used to allow the head to return 0 Track. Commonly used for the head is positioned in the floppy recalibration operation error. Its command code is
The command has no result phase, the program needs to get through the results of the command execution "detection interrupt state." Table 6-15 Fig.
This command allows the drive the selected head is moved to the specified track. The first 1 Parameter specifies the drive and head number, position 0-1 Is the drive
number, position 2 A head number, other unwanted bits. The first 2 Parameter specifies the track number.
The command also inconclusive stage, through the implementation of the program need to "detect interrupt status" to get the results of the command. Table 6-16
Fig.
2 C Track number.
This command is used to read the specified sector position from the disk, the DMA Control is transferred to system memory. Every time one sector is read, the parameters 4
( R ) Is automatically added 1 To continue to read the next sector until DMA The controller sends a signal to terminate the transfer count to the floppy disk controller. This command is
usually started after the head has head seek command is executed at the specified track. Table 6-17 Fig.
Return result, the track number C And sector number R It is the current head location. Since the start sector number of a sector after reading R Automatic gain 1 Therefore
results R Value is next unread sector number. If just reading the last sector on a track (i.e. EOT ), The track number will increase 1 ,and R Reset the value 1 .
--227--
6.8 floppy.c program
2 C Track number
3 H Head number
5 N Sector bytes
5 H Head number
6 R Sector Number
7 N Sector bytes
MT It represents a multi-track operation. MT = 1 Representation allows continuous operation of the two heads on the same track.
MF It represents the recording mode. MF = 1 Selected express MFM Recording mode, otherwise it is FM Recording.
SK Skip delete flag indicating whether there are sectors. SK = 1 It means skip. Returns the status byte ST0 , ST1 with ST2 Meaning are shown in
76
ST0_INTR Cause of the interruption. 00 - Command normal end; 01 - Command ends abnormally;
10 - Command is invalid; 11-- Floppy disk drive state changes.
5 ST0_SE Seek operation or recalibrate the end of the operation. ( Seek End )
4 ST0_ECE Error checking devices (track zero error correction). ( Equip. Check Error )
10 Select the drive number (an interrupt occurs drive letter). ( Drive Select )
ST0_DS
00--11 Respectively drive 0-3 .
7 ST1_EOC Access to more than the maximum sector number on the track EOT . ( End of Cylinder )
6 Unused( 0 ).
--228--
6.8 floppy.c program
3 Unused( 0 ).
7 Unused( 0 ).
6 ST2_CM SK = 0 When reading data encountered delete flag. ( Control Mark = deleted )
4 ST2_WC Sector ID Track number information C It does not match. ( Wrong Cylinder )
2 ST2_SNS The search condition does not meet the requirements. ( Scan Not Satisfied )
1 ST2_BC Sector ID Track number information C = 0xFF , Track bad. ( Bad Cylinder )
0 ST2_MAM Sector data flag is not found DATA AM . ( Missing Address Mask )
This command is used to data in memory to disk. in DMA The transmission mode, the floppy disk controller data memory specified serially written to disk sectors. Complete
each sector, start sector number is automatically increased 1 And continue to write a sector until the floppy controller receives DMA Count termination signal of the controller. Table 6-21
Shown, wherein the same meaning as the abbreviated name and the read command.
table 6-21 write fan Area number According to life make ( FD _WRITE )
2 C Track number
3 H Head number
5 N Sector bytes
5 H Head number
6 R Sector Number
7 N Sector bytes
--229--
6.8 floppy.c program
After sending the command floppy disk controller will immediately return to the normal results 1 with 2 (Ie state ST0 In which the track number and the head PCN ). They state
after execution of a command on the controller. Usually at the end of a command to be executed CPU Interrupt signals. For sector read, write track, write delete flag, reading
identification field, and formatting commands and scanning non- DMA Command transmission mode due to interrupt can be known directly from the interrupt flag of the main reasons
for the status register. For the driver changes the ready signal, a seek and re-calibration (zero return channel head) caused interrupted, because there is no return a result, it is
necessary to utilize the command execution controller reads the state information of the command. Table 6-22 Fig.
table 6 -twenty two Detect in Break shape State life make ( FD _SENSEI )
carried out
This command is used to set the initial value of the internal timer three floppy disk controller, and selects a transmission mode, i.e., the driving motor step rate ( STR ), The
head loading / unloading ( HLT / HUT ) Time and whether to adopt DMA Information way to transfer data into the floppy disk controller. Table 6-23 Fig.
table 6- twenty three Assume set drive Actuator Ginseng The number of commands ( F D_SPECIFY )
command 1 SRT (unit 2ms ) HUT (unit 32ms ) The motor step rate, the head unloading time
2 HLT (unit 4ms ) ND Head load time, non- DMA the way
result no no
in PC Machine, commonly used with the floppy disk controller NEC PD765 or Intel 8287A Compatible chip, for example, Intel of 82078 . Since a driver diskette complicated,
so for the following more detailed description of such programming is the floppy disk controller chips.
A typical operation of the control disk include not only wait for the controller to send commands and returns the results, the floppy disk drive is a low-level operations, it
Before being sent to the floppy disk controller in the above-described operation command or parameter, you must first query the master controller status register ( MSR ), In
order to know the drive and direction of data transfer ready state. Floppy disk driver uses a output_byte (byte) Function to specifically implement the operation. The function is the
This function loops until the master state data port ready flag register RQM for 1 And direction signs DIO Yes 0 ( CPU FDC ), Then the controller had been ready to accept
commands and parameters bytes. From timeout counting function loop, to cope with the case where the controller does not respond. This cycles the driver would be provided 10000
Times. The choice of the number of cycles required careful to avoid making incorrect program timeout judgment. in Linux Kernel version 0.1x to 0.9x Often encounter the need to
adjust the number of cycles of this problem, because at that time people used PC Machine running speeds vary greatly ( 16MHz - 40MHz ), The actual delay cycle is also generated
a great difference. This can be seen early Linux Mailing list of many articles. To solve this problem, it is best to use the system hardware clock
--230--
6.8 floppy.c program
Results phase controller for reading the result of the byte string, also needed to send a command the same operation, but this time the direction of data transmission
requirements are set state flag ( FDC CPU ). This procedure is a function of the corresponding result () . This function reads the status byte result stored in the reply_buffer [] Byte
array.
Y
MSR = 10XXXXXXb main
Count-up value
return
N
exceeds the set?
Y
Timeout error count
Map 6-6 Sending a command byte to the floppy disk controller or parameters
Initializing operation of the floppy disk drive controller includes appropriate parameters in the controller is reset. The controller is reset operation of the digital output
register means DOR Bit 2 (start up FDC Flag) 0 Then set 1 . After reset the machine, "specify drive parameters" command SPECIFY The value of the set is no longer valid, it is
reset_floppy () And interrupt handling C function reset_interrupt () in. Before a function for modifying DOR Bits 2 , So that the controller is reset, the function to be used after a reset
controller SPECIFY Command to re-establish a drive parameter controller. In the data transmission preparation phase, if it is judged from the actual disk size different, still
After reset the controller, the digital control registers should also DCR Sends the specified transmission rate value, to reinitialize the data transmission rate. If the machine
to perform a reset operation (e.g., hot start), the data transmission rate becomes the default value 250Kpbs . However, by the digital output register DOR Issued to the controller
reset operation does not affect the data transmission rate setting.
Drive recalibrate ( FD_RECALIBRATE ) And head seek ( FD_SEEK) Two head positioning command. Re-correction command to zero so that the head is moved track, and the
head seek command allows the head is moved to the specified track. The two head positioning command with typical read / write command is different, because they are no results
stage. Once one of the two command is issued, the controller will immediately be in the main status register ( MSR ) Return to the ready state, and after performing head positioning
operation table form. After the positioning operation, the controller will generate an interrupt to request the service. At this point it should send a "detector interrupt status" command
to end the interruption state and the read positioning operation. And the drive motor is a direct enable signal from the Digital Output Register ( DOR ) Control, and therefore, if the
The operation must be carried out before issuing positioning commands. Figure flowchart 6-7 Fig.
--231--
6.8 floppy.c program
DOR
start the motor
Seek command
N
Status?
Data read or write operation requires several steps to complete. First, the drive motor need to turn on, and the head is positioned to the correct track, then initialize DMA Controller,
and finally send the data read or write command. In addition, the need to develop treatment options when an error occurs. Typical operation flow chart shown in Figure 6-8 Fig.
--232--
6.8 floppy.c program
Recalibrate
N
Motor starting time> 0.5s?
Y
DMA controller initialization
Y
Counter overtime? failed controller timeout error
N
N
Detected a controller interrupt? Read / write cycles> 3 times?
N NN
Counter overtime? Seek retry> 3
Y YY
Prior to the disk data transfer, disk drive motor must first reach normal operating speed. For most 3 ½ inch floppy drive is concerned, this start-up time
takes about 300ms ,and 5 ¼ inch floppy drive takes about 500ms . in floppy.c This program will become a start-up delay time setting 500ms .
After starting the motor, it is necessary to use a digital control register DCR Disk media provided with the current data transfer rate matching. If an implicit seek ways not
open, then you need to send a seek command FD_SEEK , The head is positioned to the correct track. At the end of the seek operation, the head takes some place (load) time. For
most drivers, this minimum delay time required 15ms . When using an implicit tracking mode, then you can use "specify drive parameters" command specifies the head loading time
( HLT ) To determine the minimum time the head in place. In the data transfer rate of e.g. 500Kbps Under the circumstances, if HLT = 8 , The effective time of the head in place 16ms .
Of course, if the head is already in place on the right track, there is no need to put in place to ensure that this time.
Then DMA Controller initialization operation, write command is also executed immediately. Typically, after completion of the data transfer, DMA The controller will issue a
terminal count ( TC ) Signal, then the floppy disk controller will complete the current data transfer and an interrupt request signal, indicating that the operation has reached the stage
results. If an error occurs during the operation or the last sector of the track number is equal to the last sector ( EOT ), Then the floppy disk controller will immediately enter the
stage results.
According to the above flowchart, if errors are found in the reading result of the status byte will reinitialize by DMA Controller, and then try to re-start performing a data read
or write command. Persistent error usually indicates a seek operation and did not let the head reaches the specified track, this time should be repeated recalibration of the head,
and the seek operation is performed again. Thereafter, or if an error, then the final write operation failed controller will report to the driver.
--233--
6.8 floppy.c program
Linux 0.11 Although not implemented in the kernel of the floppy disk format operation, but as a reference, the disk format operation is here briefly described. During the
disk format operation comprises the head is positioned on each track, and creates a data field consisting of a (field 4 ) Fixed format field.
After the motor is started and set the correct data transfer rate, the magnetic head returns the zero track. At this time, the disk needs 500ms Reach normal operating speed
Built on the disk during operation format identifier field ( ID Field) is in the implementation phase by the DMA Controller. DMA The controller is initialized to be provided for
each track sector identification field ( C ),magnetic head( H ), Sector number ( R ) And the value of the sector byte. For example, for each track having 9 Sectors of the disk, the size of
each sector is 2 ( 512 Bytes), if the magnetic head 1 Format Track 7 Then
DMA The controller should be programmed to transmit 36 Bytes of data ( 9 Sector x Per sector 4 Bytes), the data field should be: 7,1,1,2 ,
7,1,2,2 , 7,1,3,2 , ..., 7,1,9.2 . Because during the formatting command, the data floppy disk controller provides direct identification field will be recorded on the disk, the content data
may be arbitrary as. So some people take advantage of this feature to prevent the disk copy protection.
After each head on a track format operation have been performed, you need to be executed before a seek operation so that the head moves on to the next track, and the
format operation is repeatedly performed. Because the "Format Track" command does not contain implicit seek operation, the seek command must use SEEK . Similarly, the
magnetic head in place of the previously discussed time also set after each seek.
DMA ( Direct Memory Access) Yes " Direct memory access " abbreviation of. DMA The main function of the controller is to enhance the performance of the system by allowing
the external device data directly with memory transfer. It is generally made on the machine Intel 8237 Chip or a compatible chip. By DMA The controller is programmed data transfer
between peripherals and memory are not capable CPU Conducted under controlled conditions. Therefore, during the data transfer, CPU You can do other things. DMA Controller
Program by DMA Controller port its initialization. The operations include: ① to DMA The controller transmits a control command; ② Start address memory transfer; ③ Data
length. Sending commands specified use for transmission DMA Channel, is transmitted to the peripheral memory (write) data transfer to the memory or peripheral, or a
single-byte transmission batch (block) transmission. for PC Machine, a floppy disk controller designated for use DMA aisle 2 . in Linux 0.11 Kernel, a floppy disk driver using a
Intel 8237 Only chip 16 Address pins (wherein 8 In combination with the root data line), and therefore can only address 64KB Memory space. In order to make it
accessible 1MB Address space, DMA A controller uses the page register 1MB Memory is divided into 16 Pages to operate, see Table 6-24 Fig. Thus the transmission must
be converted to the starting address of the memory in which the DMA Page offset address value of the page. Each time data transfer can not exceed the length of the 64KB .
4 Explanatory information on the disk format, previously filed are translated into the field. In fact, for speaking programmers, which translated into a field or fields may be more pleasing to the ear of some. ☺
--234--
6.8 floppy.c program
2 . data transmission
After initialization is complete, to DMA The controller mask register set, open DMA aisle 2 ,thereby DMA The controller starts data transmission.
3 . End of Transmission
When the data transfer is complete all the required transmission, DMA Controller will generate an "operation complete" ( EOP ) Signal is sent to a floppy disk
controller. At this time, the floppy disk controller to perform operations: turn off the drive motor and CPU Transmitting an interrupt request signal.
in PC / AT Machine, DMA The controller has 8 Separate channels may be used, after which 4 Channels are 16 Bit. The floppy disk controller designated for use DMA aisle
2 . It must first be set before using a channel. This involves the operation of three ports, namely: page register port (offset) port address register and data count register ports.
due to DMA Register is 8 Bits, and the address and count values are 16 Bit, so each needs to be sent twice. Low byte sent first, then the high byte transmitted. Each channel
table 6-25 DMA Each channel used page Surface, and the address count register ports
For the usual DMA Applications, there 4 Commonly used for controlling the registers DMA State controller. These are the command register, the register request,
a single mask register, and a mode register clears trigger byte pointer. Table 6-26 Fig. Linux 0.11 The kernel uses a table shaded 3 Port registers ( 0x0A, 0x0B, 0x0C ).
Port Address
name
(aisle 0-3 ) (aisle 4-7 )
--235--
6.8 floppy.c program
Command register for specifying DMA The controller chip operating requirements, set DMA The overall state of the controller. It is usually no need to change it after the
startup initialization. in Linux 0.11 After the kernel, floppy disk drivers directly use the Power ROM BIOS The set value. For reference, the meaning of each bit are listed here
command register, see Table 6-27 Fig. (At the port read, the content is obtained DMA
Place Explanation
7 DMA Peripheral response signal DACK : 0-DACK Active low; 1-DACK Active high.
6 Peripheral request DMA signal DREQ : 0-DREQ Active low; 1-DREQ Active high.
5 Write mode selection: 0- After selecting the write-behind; 1- Select Extended to write; X- If the bit 3 = 1 .
3 DMA Cycle Selection: 0- Normal timing period ( 5 ); 1- Compression timing period ( 3 ); X- If the bit 0 = 1 .
2 Open DMA Controller: 0- It allows the controller to work; 1- Prohibit controllers work.
1 aisle 0 Address hold: 0- Prohibition channel 0 Address hold; 1- It allows the channel 0 Address hold; X- If the bit 0 = 0 .
0 Memory transmission: 0- Memory-to-memory transmission is prohibited; 1- Mode allows the memory to memory transfer.
Peripheral request register for recording the channel signal requesting service DREQ . Each channel corresponds to one. when DREQ When the position corresponding to
the effective 1 , when DMA The position will be made in response to the controller 0 . If you do not use DMA Request signal DREQ Pin, may be provided directly by the corresponding
channel request bit to request programming DMA Service controller. in PC Machine, a floppy disk controller DMA
Channel controller 2 Direct request signal DREQ Connections, so Linux There is no need for the kernel register operation. For reference, here byte format requested
table 6-28 DMA The meaning of each bit in the request register
Place Explanation
10
Channel selection. 00-11 Were selected channel 0-3 .
Single-port register mask 0x0A (for 16 Bit channel is 0xD4 ). A Channel is masked, it refers to the use of the peripheral channel emitted DMA Request signal DREQ Can
not get DMA The controller's response, therefore, can not let DMA The controller operates the channel. Each bit of this register See Table 6-29 Fig.
Place Explanation
2 Mask flag. 1 - Masking the selected channel; 0 - Open the selected channel.
10
Channel selection. 00-11 Were selected channel 0-3 .
It is used to specify a mode register DMA Operation mode channel. in Linux 0.11 Kernel, which uses the read ( 0x46 ) And write ( 0x4A ) In two ways.
--236--
6.8 floppy.c program
table 6-30 DMA The meaning of each bit in the mode register
Place Explanation
76 Select transmission.
00- Request mode; 01- Single-byte pattern; 10- Byte block mode; 11- A series mode.
32 Transmission type.
00-DMA check; 01-DMA Write transfer; 10-DMA Read transfer. 11- invalid.
10
Channel selection. 00-11 Were selected channel 0-3 .
Channel address and count registers can be read 16 Bits of data. Clear has a trigger port 0x0C It is used to write in a read / DMA
Before the controller or the address information of the byte count has initialized to the default trigger condition. When the trigger is byte 0 When the low byte is accessed; trigger
when the byte is 1 When, access high byte. Each visit once, it changes the trigger once. write 0x0C Port can be set to trigger 0 status.
In use DMA The controller typically required to follow certain steps, the following procedure is used in floppy disk drive DMA Way controller to illustrate:
2. Modified mask register (Port 0x0A ), To shield the need to use DMA aisle. For it is through floppy disk driver
Road 2 ;
3. to 0x0C Port write operation, the byte counter has a default state of the flip-flop;
4. Write mode register (port 0x0B ), To set the operating mode word specified channel. for;
5. Write Address Register (port 0x04 ), Set up DMA Offset address memory pages in use. The first to write low byte, written after the high word
Section;
6. Write page register (port 0x81 ), Set up DMA Memory pages used;
7. Write count register (Port 0x05 ), Set up DMA Number of bytes transferred. It should transfer length - 1 . The same need for high and low
Byte write once, respectively. Every book floppy driver requirements DMA Is the length of the transmission controller 1024 Bytes, so write
9. Finally, the interrupt is turned on to allow the system to the floppy disk controller issues an interrupt request after transmission.
--237--
7.1 Overview
7.1 Outline
in linux 0.11 The kernel, the character control equipment includes a terminal device and a serial terminal. Chapter is the code for operating these input and output
devices. Works related to the terminal driver may reference MJBach of" UNIX Operating System Design "section 10 Chapter 3 Section.
This chapter can be divided into three. One is about RS-232 Serial line drivers, the program comprising rs_io.s with serial.c ; The other one is involved in console driver,
which includes a keyboard interrupt-driven program keyboard.S And the console display driver console.c ; Third part is a terminal driver interfaces with the upper portion, including
program input and output terminal tty_io.c And a terminal control program tty_ioctl.c . Below we first outlines the basic principles of the control terminal implemented driver, and
then divided into three parts which describe their basic function.
Terminal driver for controlling a terminal device, transmitting data between the terminal device and processes the transmitted data and perform some processing. The user
types on the keyboard of the original data ( Raw data ), After treatment using the terminal program is transmitted to a receiving process; process the data sent to the terminal, after
the terminal program processing, is displayed or transmitted over the serial link to the remote terminal on the terminal screen. Treatment of data in accordance with input or output
terminal program mode, the terminal can be divided into two operating modes. One is the mode specification ( canonical ), This time via the data terminal program conversion
processing is to be performed, and then sent out. For example, the TAB Extended character 8 A space character, with typed delete characters ( backspace ) Control to delete
characters such as typed earlier. Handler rules used generally called line ( line discipline)
Module. Another non-canonical mode or said original ( raw) mode. In this mode, only the line data transfer rules of procedure between the terminal and processes the data
Driver in the terminal, according to their relationship to the device, and the position in the execution flow may be divided into direct character device driver interface
program and direct contact with the upper layer. We can use the map 7-1 Schematically this control relationship.
--239--
7.2 Overall Functional Description
write
Device Drivers
Character device
Each corresponds to a terminal device tty_struct Data structure, the terminal device mainly used to save the current parameter settings, foreground process belongs to the
group ID And character IO Message queue buffer and the like. This structure is defined in include / linux / tty.h File whose structure is shown below:
struct tty_struct {
struct termios termios ; // io terminal control characters and attribute data structure.
Linux The kernel uses an array tty_table [] To store information of each terminal device in the system. Each array entry is a data structure
tty_struct , Corresponding to a system terminal. Linux 0.11 Kernel supports a total of three terminal devices. Is a console device, the other two are on the system using a
termios The structure for storing the corresponding terminal device io Attributes. For a detailed description of the structure see below. pgrp It is the process group ID that
indicates a process group session in the foreground, that currently owns the process of the terminal device group. pgrp The main job for process control operations. stopped It is a
flag indicating whether the corresponding terminal device has stopped using. Function pointer * write () That the output process function terminal device for the console terminal,
which is responsible for driving the display hardware, characters and the like on the information display screen. For a serial port connected to the terminal via a serial system,
which is responsible for the output characters sent to the serial port.
The data processing terminal is held in 3 More tty_queue Character buffer queue structure (or character table), are represented below:
struct tty_queue {
unsigned long data; // Wait for the current queue statistics data buffer. // For serial
--240--
7.2 Overall Functional Description
Each character is a buffer queue length 1K byte. Wherein the read buffer queue read_q For temporarily storing an original from the keyboard or the serial input terminal ( raw )
Sequence of characters; write buffer queue write_q Written to the console for storage or display of data to a serial terminal; according
ICANON Signs, auxiliary queue secondary Used to store from read_q Data taken out through line program processing rules (filters) before, or cooked called ( cooked) Mode data. This
is the raw data line rules of procedure of the special characters such as deleted ( backspace ) Specification data is input character conversion, character is read in units supply for use
by applications. The upper terminal read function tty_read () I.e., for reading
When the user types the data is read, the interrupt processing program is only responsible for the compilation of the original character data in the input buffer queue, and
called by the interrupt handling process C function( copy_to_cooked () ) To deal with change jobs characters. For example, when the process of writing data to a terminal, the
terminal driver will call the line function rules copy_to_cooked () , All the user data buffer into the write buffer queue, and the data sent to the terminal display. Characters on a
terminal key is pressed, the keyboard interrupt process triggered by the key scan codes corresponding to put into the read queue read_q And calls the handler specification mode read_q
Characters processed then into secondary queue secondary in. At the same time, if the terminal device is set up Echo flag ( L_ECHO ), It can also put the character into the write
queue write_q
And calls the write function to end the character displayed on the screen. In addition to generally as type the password or other special requirements beyond, echoing the flag is
set. We can modify the terminal termios Information structure to change the flag value.
In the above tty_struct Structure further comprises a termios Structure, which is defined in the include / termios.h Header file, the contents of its fields follows:
struct termios {
unsigned long c_iflag; / * Input mode flags * / // input mode flag.
unsigned long c_oflag; / * Output mode flags * / // output mode flag.
unsigned long c_cflag; / * Control mode flags * / // control mode flag.
unsigned long c_lflag; / * Local mode flags * / // local mode flag.
unsigned char c_line; / * Line discipline * / // line discipline (rate).
unsigned char c_cc [ NCCS ]; / * Control characters * / // control character array.
};
among them, c_iflag Input mode flag is set. Linux 0.11 The kernel implements POSIX.1 All definitions 11 Input flags, see termios.h
Header file description. Terminal device driver using these flags to control how characters by converting the input terminal (filtration). For example, whether the input of line
breaks ( NL ) Into a carriage ( CR ), The need to convert uppercase to lowercase character entry (because in the past some terminal equipment can only uppercase characters)
File copy_to_cooked () .
c_oflag Output mode flag is set. Terminal device driver uses these flags to control how characters output to the terminal. c_cflag
Control mode flag is set. Mainly used to define the characteristics of serial transmission terminal, including baud rate, stop bits, and number of bits of a character and the like. c_lflag
Local mode flag is set. User interaction with the main driver for controlling. For example, the need for echo ( Echo ) Character, in addition to the need to paint the characters
displayed directly on the screen, whether the need to type the characters on the terminal control signal is generated. These operations also in the
Above-mentioned 4 Type of the markers are set unsigned long , Each bit may represent a marker, so that each may have a flag set up
32 Input flag. All of these flags and their meanings can be found in termios.h head File.
c_cc [] An array containing all the special characters that can be modified. For example, you can modify the interrupt character (^ C ) Produced by the other keys. among
Therefore, the use of system calls ioctl Or use the correlation function ( tcsetattr ()) We can modify termios Information structure to change the setting parameters of the
terminal. Row rules function that is operating in accordance with these set parameters. For example, if you want to control terminal of the characters typed
--241--
7.2 Overall Functional Description
Echoed back, setting the baud rate of a serial transmission terminal, and a write buffer queue empty read buffer queue.
When the user terminal to modify the parameters, the canonical mode flag is reset, then the terminal will be set to operate in the original mode, where the user will type the
rows procedural rules intact data transmitted to the user, but also when the carriage as an ordinary character. Therefore, the user uses the system call read When, we should make
some kind of decision-making programs to determine system calls read What if considered complete and return. This will be terminal
termios Structure VTIME with VMIN Control characters decide. These two timeout timer value read operation. VMIN That in order to satisfy a read operation, the minimum number
We can use the command stty To view the current terminal equipment termios Set case flag structure. in Linux 0.1x System command line prompt, type stty Command
[/ Root] # stty
- - - - - - - - - Characters --------- INTR:
'^ C' QUIT: '^ \' ERASE: '^ H' KILL: '^ U' EOF: '^ D'
TIME: 0 MIN: 1 SWTC: '^ @' START: '^ Q' STOP: '^ S'
SUSP: '^ Z' EOL: '^ @' EOL2: '^ @' LNEXT: '^ V'
DISCARD: '^ O' REPRINT: '^ R' RWERASE: '^ W'
- - - - - - - - - - Control Flags ---------
- CSTOPB CREAD -PARENB -PARODD HUPCL -CLOCAL -CRTSCTS Baud rate:
9600 Bits: CS8
- - - - - - - - - - Input Flags ----------
- IGNBRK -BRKINT -IGNPAR -PARMRK -INPCK -ISTRIP -INLCR -IGNCR ICRNL -IUCLC
IXON - IXANY IXOFF -IMAXBEL
- - - - - - - - - Output Flags ---------
OPOST -OLCUC ONLCR -OCRNL -ONOCR -ONLRET -OFILL -OFDEL Delay modes:
CR0 NL0 TAB0 BS0 FF0 VT0
- - - - - - - - - - - Local Flags ---------
ISIG ICANON -XCASE ECHO -ECHOE -ECHOK -ECHONL -NOFLSH
- TOSTOP ECHOCTL ECHOPRT ECHOKE -FLUSHO -PENDIN -IEXTEN rows 0 cols 0
Which with a minus sign means no. In addition to the current Linux System, you need to type 'Stty -a' To display all of this information, and display formats differ.
The relationship between the main data structures used by the terminal program and they are visible in FIG. 7-2 Fig.
--242--
7.2 Overall Functional Description
Serial terminal
when c_lflag middle ICANON When the flag is set, the pattern that is processed in accordance with the terminal specification data input. At this time, the input character is
assembled in a row, the read process in the form of character row. When his characters input terminal driver returns immediately. There delimiter line NL ,
EOL , EOL2 with EOF . Which, among the last EOF (End of file) will be deleted handler, the other four characters will be used as the last line of a character
In the specification mode, the input terminal of the character to be processed: ERASE , KILL , EOF , EOL , REPRINT , WERASE
with EOL2 .
ERASE In addition to paint a character ( Backspace ). In the specification mode, when copy_to_cooked () In case of a function deletes the last character input buffer queue
when the input characters. If the queue is the last character of the character line (for example, NL ), Not any treatment. After the characters are ignored, not into the buffer queue.
KILL Line character is deleted. It deletes the queue last line of characters. Since the character is ignored.
EOF It is the end of file. in copy_to_cooked () The function of the character and end of line character EOL with EOL2 They will be treated as carriage returns to deal with. The
encounter characters read function will return immediately. EOF Characters are not placed in the queue but was ignored.
REPRINT with WERASE Specification is extended to identify the character mode. REPRINT Let all unread input is output. and
WERASE In addition to paint word (skip blank character). in Linux 0.11 , The program ignores the two-character recognition and processing.
in case ICANON Is in the reset state, the terminal program works noncanonical mode. At this time, the terminal processing program does the character, but they will be
treated as an ordinary character. Input data is also no line concept. When the terminal program returns process is read by the MIN with
TIME The determined value. These two variables are c_cc [] An array of variables. They can be changed by modifying the way in dealing with the process of noncanonical mode
read characters.
MIN Indicates a read operation requires a minimum number of characters to be read; TIME Waiting to read a specified character timeout value (unit of measurement is 1/10 second).
They can be divided according to the value of four cases will be described.
1. MIN> 0 , TIME> 0
at this time TIME Is a character timeout interval timer value to be used after the receipt of the first character. Before the timeout, if the first
--243--
7.2 Overall Functional Description
Received the MIN Characters, the read operation returns immediately. If the receipt MIN Time out, the read operation returns the number of characters has been received
before the characters. At this point at least be able to return a character. Therefore, prior to receiving a character if secondary Empty, the read process will be blocked
(sleep).
2. MIN> 0 , TIME = 0
Only in this case received MIN Characters read operation before returning. Otherwise wait indefinitely (blocking).
3. MIN = 0 , TIME> 0
at this time TIME Timeout timer value is a read operation. Upon receipt of a character or has timed out, the read operation returns immediately. If a timeout is
4. MIN = 0 , TIME = 0
In this arrangement, if there is data in the queue can be read, the read operation reads the desired character. Otherwise, it returns immediately 0 A number of
characters.
In the above case Fourth, MIN Only indicate the minimum number of characters read. If the process requires more than reading MIN To many characters, as long as there
is a queue process could meet the current demand. For a read operation processing of the terminal device, see the program tty_io.c middle
tty_read () function.
in Linux 0.11 Kernel, drivers relates to the console terminal keyboard.S with console.c program. keyboard.S For processing the characters typed by the user, put them into
the read buffer queue read_q And calls copy_to_cooked () Function reads read_q Characters, after converted into secondary buffer queue secondary . console.c Output processing
For example, when the user types a character on the keyboard, will cause keyboard interrupt response (interrupt request signal IRQ1, Corresponding to the interrupt number
INT 33 ), This time will the keyboard interrupt handler reads the corresponding keyboard scan codes from the keyboard controller, and then translated into the corresponding
character according to the keyboard scan code mapping table to be used, into tty Read queue read_q in. Then call the interrupt handler C function do_tty_interrupt () , Calling it a
direct line rules function copy_to_cooked () The character filter process, and put tty Auxiliary queue secondary While the character into the tty Write queue write_q And calls the write
function console con_write () . At this time, if the terminal echo ( echo ) Property is set, the character will be displayed on the screen. do_tty_interrupt () with copy_to_cooked () Function tty_io.c
do_tty_interrupt
read_q
copy_to_cooked
secondary
con_write
Keyboard hardware interrupt
write_q
--244--
7.2 Overall Functional Description
For the execution process tty Write operation, a terminal driver is processed character by character. In the write buffer queue write_q When not full, it takes a
character from the user buffer, processed into write_q in. When all the data into the user write_q At this queue, or write_q Full, call termination structure tty_struct Specified in
the write function, the write_q Output buffer queue data to the console. For the console terminal, its function is to write con_write () ,in console.c Program implementation.
For drivers console terminal operation, involving two main programs. One is the keyboard interrupt handler keyboard.S , Mainly for the user typed characters and
put read_q Buffer queue; the other is a screen display processing program console.c For from write_q
Queues the fetched character and displayed on the screen. All relationships between the three character buffer queue or file with the above function can be used in FIG. 7-4 Clearly
represented.
tty_write () tty_read ()
tty_io.c Character device driver
secondary
Note: The function tty_write (),
con_write () put_queue ()
console.c keyboard.S
Map 7-4 The relationship between the character buffer queues, and console terminal functions and procedures
Program processing operation of the terminal with a serial serial.c with rs_io.s . serial.c Program is responsible for the serial port initialization. Further, by the removal of
Transmit Holding Register empty interrupt enable mask for the character on the serial interrupt transmission operation. rs_io.s Program is a serial interrupt process. According
Case of serial interrupt occurs causing the system are: a. due to modem The state has changed; b. Since the line status changes;
c. Since the character is received; d. Since the interrupt enable flag register is set Transmit Holding Register interrupt enable flag needs to send characters. Processing of the first
two cases caused the interrupt by reading a register value corresponding to the status, so that it is reset. For the case where the result of receiving a character, the program first
reads the character into buffer queue read_q Then call copy_to_cooked () Converted into a function to regulate the behavior of the character mode in units of character into the
auxiliary queue secondary in. In the case of the characters to be sent, the program first from the write buffer queue write_q Remove the tail pointer of one character is sent out, and
then determines whether the write buffer queue is empty, if there are characters in the loop transmission operation performed.
For the access terminal through a serial port of the system, in addition to processing similar to the console, but also the need for an input / output processing operation of
the serial communication. Data is read from the serial interrupt handler into the read queue read_q And subsequently performing an operation the same console terminal.
For example, for a serial port connected 1 On the terminal, the first character type transmitted over the serial link to the host, causing the host serial port 1 Interrupt
request. At this time, the serial port interrupt handler will put the character serial terminal 1 of tty Read queue read_q Then
--245--
7.2 Overall Functional Description
Call the interrupt handler C function do_tty_interrupt () , Calling it a direct line rules function copy_to_cooked () The character filter process, and put tty Auxiliary queue secondary
While the character into the tty Write queue write_q And calls write the serial terminal 1 The function rs_write () . The function will turn back to the characters serial terminal,
then echoing If the terminal ( echo ) Attribute is set, the character will be displayed on the screen of the serial terminal.
When the process time required to write data to a serial terminal, the terminal is similar to the write operation, but this time the terminal tty_struct Data structure write
function is the function to write a serial terminal rs_write () . The cancel function allows the Transmit Holding Register empty interrupt mask, thereby transmitting the serial interrupt
to occur will cause the holding register is empty. And the serial interrupt process according to the reason for the cause of the interruption from write_q
Write buffer queue into the send out a character and character transmission operation holding register. During this operation is an interrupt to send a character to the last write_q Mask
will empty Transmit Holding Register empty interrupt bit allows again, thereby inhibiting the occurrence of such an interrupt.
Write function serial terminal rs_write () in serial.c Program implementation. Serial interrupt program rs_io.s Implemented. Relationship serial character buffer queue and
Map 7-5 The relationship between the function of the buffer queue character serial terminal device
Seen from the figure, the main difference between the serial console terminal and the terminal using a serial processing procedure rs_io.s Substituted program console
operator display and the keyboard console.c with keyboard.S , The rest of the process is exactly the same.
Typically, the user is dealing with the device via the file system, each device has a file name, the file system accordingly also occupies an inode ( i Node), but the i Node file
type is the device type, to be distinguished from other normal files. Users can directly use the file system calls to access the device. The terminal driver also aim to provide a call to
the file system interface functions for this purpose. Interface to other programs and a terminal driver system is used tty_io.c Files in generic functions to achieve. Wherein the read
terminal function implemented tty_read () And write terminal function tty_write () And the input line rules function copy_to_cooked () . In addition, tty_ioctl.c Program, input-output control
to achieve the function to modify the parameters of the terminal (or system call) tty_ioctl () . Setting parameters of the terminal is on the terminal data structure termios Structure in
which more parameters, but also more complex, refer to include / termios.h Instructions in the file.
For different terminal devices may have different rules of procedure matching rows. However, Linux 0.11 Only one line rule function, so termios Field
--246--
7.3 Makefile file
1#
2 # Makefile for the FREAX-kernel character device drivers.
3#
4 # Note! Dependencies are done automagically by 'make dep', which also
5 # Removes any old dependencies. DO NOT put your own dependencies here
6 # Unless it's something special (ie not a .c file).
7#
# Makefile file FREAX (Linux) kernel device driver characters.
# note! Dependency is performed by the 'make dep' automatically, which will automatically remove the original dependency information. Do not put your own
# Dependency information on here, unless it is (that is not a message .c file) special file.
89 AR
= Gar # GNU binary file processing program for creating, modifying and extracting files from the archive.
10 AS = Gas # GNU assembler.
11 LD = Gld # The GNU linker.
12 LDFLAGS = -s -x # connection program all the parameters, -s omitted all symbols output file information. -x Delete all local symbols.
# The frame pointers; -fcombine-regs merge register, reduce the use of register class; -finline-functions all Jane
# Single short code embedded function calls the program; -mstring-insns Linus own filling optimization options, will no longer use;
# - nostdinc -I ../ include not using the default path contains the file, and use the specified directory (../../include).
14 CFLAGS = -Wall -O -fstrength-reduce -fomit-frame-pointer -fcombine-regs \
15 - finline-functions -mstring-insns -nostdinc -I ../../ include
# C pre-processing options. -E C only run pre-treatment, pre-treatment and the results for all of the specified program is output to the standard output C
# Refers gcc CFLAGS using the specified options compiled C code is compiled without stops (-S), thereby generating
# C each corresponding to the input file assembler code file. Assembler default file name is generated by the original file name C
# Remove .c and .s suffix plus. -o represented followed by the name of the output file. Of which $ *. S (or $ @ ) is automatic target variable,
--247--
7.3 Makefile file
27 OBJS = tty_io.o console.o keyboard.o serial.o rs_io.o \ # Define the target file variable OBJS.
28 tty_ioctl.o
2930 chr_drv.a: $ (OBJS)
# Use the following command to connect to the target file in the library with chr_drv.a prerequisite OBJS.
37 clean:
38 rm -f core * .o * .a tmp_make keyboard.s
39 for i in * .c; do rm -f `basename $$ i .c`.s; done
40
# Here was the objective or rules for checking dependencies between files. Methods as below:
# Sed string editing program for the Makefile (i.e. are files), and outputs for deletion Makefile
# File '### Dependencies' all rows behind rows (48 rows from the beginning of the next), and generates tmp_make
# Temporary files (action line 44). Gcc preprocessing operation is then performed for each file in the C kernel / chr_drv / directory.
# - M flag tells the preprocessor output description of the rules relating to each target file, and make compliance with these rules syntax.
# For each source file, the output of preprocessor make a rule, the result is a certain form of the corresponding source file
# File name plus its dependencies - lists all the header files included in the source file. The pretreatment results are added to the temporary
# Tmp_make file, and then copy the temporary file into a new file Makefile.
41 dep:
42 sed '/ \ # \ # \ # Dependencies / q' <Makefile> tmp_make
43 (For i in * .c; do echo -n `echo $$ i | sed '.. S, \ c, \ s,'` ""; \
44 $ (CPP) -M $$ i; done) >> tmp_make
45 cp tmp_make Makefile
4647 ### Dependencies:
--248--
7.4 keyboard.s program
68 . . /../include/asm/segment.h ../../include/asm/system.h
The keyboard driver assembler including keyboard interrupt handler. In English usage, the make It represents a key is pressed; break It represents a bond is released
(release).
The program first special key The keyboard (e.g. Alt , Shift , Ctrl , Caps Key) status is set to use later in the program state flag variable mode Value, and then according to the
keyboard interrupt causes the key scan code, the corresponding call has been arranged into scan code table processing routine jumps, the scan code corresponding to the read
character into character train ( read_q )in. Next call C Handler do_tty_interrupt () ( tty_io.c ,
342 Line), which contains only one function row protocol function copy_to_cooked () It calls. The main function of the role is to line discipline
read_q Buffer queue read characters into proper treatment mode specification queue (queue auxiliary secondary ), And in the process, if the corresponding terminal echo
flag is set, the character will be written into the queue ( write_q ), So that will show just typed characters on the terminal screen.
for AT The keyboard scan code when the key is pressed, the corresponding key scan code is sent, but when the key release will be sent two bytes, the first one is 0xf0 The
first 2 It is a scan code when pressed. For backwards compatibility, the designers AT Keyboard scan code conversion issue has become old-fashioned PC / XT Standard keyboard
scan codes. So here only PC / XT The scan code to be processed. For a description of keyboard scan codes, see the description of the program list after.
1/*
2 * Linux / kernel / keyboard.S
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
1415 .text
16 .globl _keyboard_interrupt
17
--249--
7.4 keyboard.s program
18 / *
19 * These are for the keyboard read functions
20 * / / *
*/
// size of the keyboard buffer is the length (number of bytes).
twenty one size 1024 = / * Must be a power of two! And MUST be the same
twenty two as in tty_io.c !!!! * /
/ * Values must be a power of 2! And match the value in tty_io.c !!!! * /
// These are the offset of the buffer queue structure * /
twenty three head = 4 // offset buffer pointer field header.
twenty four tail = 8 // offset buffer tail pointer field.
25 proc_list = 12 // wait for the buffer process queue field offset.
26 buf = 16 // buffer field offset.
27
// mode is to press the keyboard status flags of special keys.
// shows a state case shift key (caps), the exchange key (alt), the control key (Ctrl) and the shift key (Shift) of. // Bit 7 caps key is
pressed;
// status bit key 6 caps (should be the same as the corresponding flag bit leds); // Right Bit 5
alt key is pressed; // 4-bit left alt key is pressed; // 3-bit right-ctrl key is pressed; bit 2 // left
ctrl key is pressed; // 1 bit right shift key is pressed; 0 // bit left shift key is pressed.
// bit 1 num-lock (initially set to 1, i.e. set the number lock key (num-lock) as a bright arc tube); // bit 0
scroll-lock.
29 leds: . byte 2 / * Num-lock, caps, scroll-lock mode (nom-lock on) * /
@ When the code is scanned 0xe0 0xe1 or when the flag is set. Thereafter it represents 1 or even went with two character scan code, see list described later. Bit 1 = 1 //
30 e0: . byte 0
3132 / *
* con_int actual interrupt handling routine, for reading and converting keyboard scan codes
* To the corresponding ascii characters.
*/
//// keyboard interrupt handler entry point.
37 _keyboard_interrupt:
38 pushl% eax
39 pushl% ebx
40 pushl% ecx
41 pushl% edx
--250--
7.4 keyboard.s program
42 push% ds
43 push% es
44 movl $ 0x10,% eax // The ds, es segment register is set to the kernel data segment.
45 mov% ax,% ds
46 mov% ax,% es
47 xorl% al,% al / *% Eax is scan code * / / * eax is the scan code * /
48 inb $ 0x60,% al // read the scan code al.
49 cmpb $ 0xe0,% al // The scan code is 0xe0 it? If the flag is set then jumps to the code at e0.
50 je set_e0
51 cmpb $ 0xe1,% al // scan code is 0xe1 it? If the flag is set then jumps to the code at e1.
52 je set_e1
53 call key_table (,% eax, 4) // calls the key handler ker_table + eax * 4 (see below line 502).
54 movb $ 0, e0 // reset e0 flag.
// The following code (lines 55-65) is used for the PC 8255A's standard keyboard processing circuit performs hardware reset. 0x61 // 8255A port is the output port B address, bit 7
(PB7) for inhibiting the output port of the keyboard and allows the processing of data. // This program is used to make a response to the scan code received. First method is prohibited
55 e0_e1: inb $ 0x61,% al // take PPI Status Port B, for which 7 bits enable / disable (0/1) keyboard.
60 1: jmp 1f
61 1: outb% al, $ 0x61 // make PPI PB7 bit.
62 jmp 1f // delay for a while.
63 1: jmp 1f
64 1: andb $ 0x7F,% al // al Bit 7 is reset.
65 outb% al, $ 0x61 // make PPI PB7 bit is reset (to allow the keyboard work).
66 movb $ 0x20,% al // send to 8259 interrupts chip EOI (End Of Interrupt) signal.
69 receive the call _do_tty_interrupt // copy the data into a canonical specification character pattern data and stored in the buffer queue.
70 addl $ 4,% esp // discard the parameters onto the stack, and pop the register reservations, and interrupt return.
71 pop% es
72 pop% ds
73 popl% edx
74 popl% ecx
75 popl% ebx
76 popl% eax
77 iret
78 set_e0: movb $ 1, e0 // receive scan 0xe0 preamble, set e0 flag (bit 0).
79 jmp e0_e1
80 set_e1: movb $ 2, e0 // receive scan preamble 0xe1, set e1 flag (bit 1).
81 jmp e0_e1
8283 / *
84 * This routine fills the buffer with max 8 bytes, taken from
85 *% Ebx:% eax (% edx is high) The bytes are written in the..
86 * Order% al,% ah,% eal,% eah,% bl,% bh ... until% eax is zero.
87 * / / *
* The following subroutine to ebx: eax up to eight characters in the insertion of the buffer queue. (Edx is
* The sequence of characters is written al, ah, eal, eah, bl, bh ... until eax equal to 0.
*/
--251--
7.4 keyboard.s program
88 put_queue:
89 pushl% ecx // save ecx, edx content.
90 pushl% edx // get console tty structure read buffer queue pointer.
95 andl $ size-1,% ecx // pointer to the buffer size adjustment head (if exceeded starts the return buffer).
96 cmpl tail (% edx),% ecx # buffer full - discard everything // == head pointer tail
pointer right (buffer queue is full)?
97 je 3f // If full, not back into the characters all abandoned.
98 shrdl $ 8,% ebx,% eax The ebx // 8 bits to 8-bit-right in eax, ebx but unchanged.
99 je 2f // There are characters? If not (equal to 0) is the jump.
100 shrl $ 8,% ebx // ebx in the right eight bits, and a jump to the label to continue.
101 jmp 1b
102 2: movl% ecx, head (% edx) // Ruoyi all the characters are placed in a queue, save the head pointer.
103 movl proc_list (% edx),% ecx // pointer to the queue of waiting processes?
104 testl% ecx,% ecx // pointer detection task structure is empty (there waiting for the queue process?).
111 ctrl: movb $ 0x04,% al // 0x4 mode flag is a schematic left ctrl key corresponding bits (2 bits).
112 jmp 1f
113 alt: movb $ 0x10,% al // 0x10 mode flag is a schematic left alt key corresponding bits (4 bits).
114 1: cmpb $ 0, e0 // e0 flag is set yet (or press ctrl alt key is to the right of it)?
115 je 2f // not the turn.
116 addb% al,% al // is the corresponding flag bit is set then change to the right (position 3 or position 5).
117 2: orb% al, mode // set flag bit pattern corresponding mode.
118 ret
// This code processing ctrl or alt key scan code released, the corresponding bit in the mode flag reset mode. When processing according // e0 flag is set to
119 unctrl: movb $ 0x04,% al // left mode flag pattern corresponding to the ctrl key bit (bit 2).
120 jmp 1f
121 unalt: movb $ 0x10,% al // 0x10 mode flag is a schematic left alt key corresponding bits (4 bits).
122 1: cmpb $ 0, e0 // e0 flag is set yet (the release is ctrl or alt key to the right of it)?
123 je 2f // not, then turn.
124 addb% al,% al // it is the corresponding flag bit is reset to the right (position 3 or position 5).
130 orb $ 0x01, mode // left shift key is pressed, the corresponding setting mode flag (bit 0).
131 ret
132 unlshift:
133 andb $ 0xfe, mode // left shift key is released the reset mode corresponding flag bit (bit 0).
134 ret
--252--
7.4 keyboard.s program
135 rshift:
136 orb $ 0x02, mode // right shift key is pressed, the corresponding setting mode flag (1 bit).
137 ret
138 unrshift:
139 andb $ 0xfd, mode // right shift key is released the reset mode corresponding flag bit (bit 1).
140 ret
141142 caps:
testb $ 0x80, mode // mode in the test mode flag bit is already set 7 (pressed state).
143 jne 1f // If the pressed state, return (ret).
144 xorb $ 4, leds // leds flip caps-lock flag bits (2 bits).
145 xorb $ 0x40, mode // flip caps mode key is pressed in the flag bit (bit 6).
146 orb $ 0x80, mode // set the mode flag caps key has been pressed flag (bit 7).
// This code flag according leds, LED indicators on or off.
147 set_leds:
148 call kb_wait // wait for the keyboard controller input buffer empty.
149 movb $ 0xed,% al / * Set leds command * / / * set the LED command * /
150 outb% al, $ 0x60 // send keyboard commands 0xed to 0x60 ports.
151 call kb_wait // wait for the keyboard controller input buffer empty.
154 ret
155 uncaps: andb $ 0x7f, mode // caps release the key, the corresponding mode flag is reset bit (bit 7) mode of.
156 ret
157 scroll:
158 xorb $ 1, leds // scroll key is pressed, corresponding to the inverted bit (bit 0) leds the flag.
159 jmp set_leds // re-open or closed based on LED indicator leds flag.
160 num: xorb $ 2, leds // num key is pressed, corresponding to the inverted bit (bit 1) leds the flag.
161 jmp set_leds // re-open or closed based on LED indicator leds flag.
162 163 / *
* Here the process direction keys / numeric keyboard arrow keys, numeric keypad and the like is detected.
*/
167 cursor:
168 subb $ 0x47,% al // scan code is the key on the numeric keypad (its scan code> = 0x47) issued?
172 jne cur2 / * Check for ctrl-alt-del * / / * check if ctrl-alt-del * / // if equal to 12, then the del key has
been pressed then determine whether alt ctrl // press and .
--253--
7.4 keyboard.s program
180 je cur // If not set (num LED is not lit), the cursor moving process be performed.
181 testb $ 0x03, mode / * Shift forces cursor * / / * shift key also moves the cursor * / // test mode flag in
the mode flag shift pressed.
182 jne cur // if the shift key is pressed, the cursor moving process be performed.
183 xorl% ebx,% ebx // inquiry scan or digital form (line 199), to take a digital ASCII code corresponding to the key.
184 movb num_table (% eax),% al Eax // to as the index value, the corresponding numeric characters take al.
188 cur: movb cur_table (% eax),% al // substitution character al cursor in the character table corresponding key.
189 cmpb $ '9,% al // If the character <= '9', is described Previous, Next, insert or delete key,
190 ja ok_cur // the functions to be included on a sequence of characters in the character '-'.
193 movw $ 0x5b1b,% ax // put in the ax 'esc [' character, and word high characters eax movement sequence.
198 num_table:
199 . ascii "789 456 1230." @ Keys on the numeric keypad corresponding to an ASCII code table.
200 #else
201 num_table:
202 . ascii "789 456 1230,"
203 #endif
204 cur_table:
205 . ascii "HA5 DGC YB623" @ Numeric keypad on the moving direction of insertion and deletion key or keys represent the corresponding character table.
206 207 / *
210 func:
211 pushl% eax
212 pushl% ecx
213 pushl% edx
214 call _show_stat // call the function display of each task status (kernl / sched.c, 37).
--254--
7.4 keyboard.s program
229 jl end_func // need to put four character sequence, if fit, will be returned.
230 movl func_table (,% eax, 4),% eax // fetch function keys corresponding to the sequence of characters.
237 * Function keys send F1: 'esc [[A' F2: 'esc [[B' etc.
238 * / / *
* Scan code sent by function key, F1 key is: 'esc [[A', F2 key as: 'esc [[B' and the like.
*/
239 func_table:
240 . long 0x415b5b1b, 0x425b5b1b, 0x435b5b1b, 0x445b5b1b
241 . long 0x455b5b1b, 0x465b5b1b, 0x475b5b1b, 0x485b5b1b
242 . long 0x495b5b1b, 0x4a5b5b1b, 0x4b5b5b1b, 0x4c5b5b1b
243
// scan code -ASCII Character Map.
// definition of the config.h keyboard type (FINNISH, US, GERMEN, FRANCH), the corresponding key scan code mapping to ASCII characters //.
245 key_map:
246 . byte 0,27 // scan code 0x00,0x01 ASCII code corresponding to;
247 . ascii "1234567890+ '" // scan code 0x02, ... 0x0c, 0x0d corresponding ASCII code, similar to the following.
255 . fill 16,1,0 / * 3A-49 * / / * 0x3A-0x49 scan code corresponding to ASCII code * /
256 . byte '-, 0,0,0,' + / * 4A-4E * / / * 0x4A-0x4E scan code corresponding to ASCII code * /
257 . byte 0,0,0,0,0,0,0 / * 4F-55 * / / * 0x4F-0x55 scan code corresponding to ASCII code * /
261 shift_map:
262 . byte 0,27
263 . ascii "! \" # $% & / () =? `"
264 . byte 127,9
265 . ascii "QWERTYUIOP] ^"
266 . byte 13,0
267 . ascii "ASDFGHJKL \\ ["
268 . byte 0,0
269 . ascii "* ZXCVBNM;: _"
270 . byte 0, '*, 0,32 / * 36-39 * /
271 . fill 16,1,0 / * 3A-49 * /
272 . byte '-, 0,0,0,' + / * 4A-4E * /
273 . byte 0,0,0,0,0,0,0 / * 4F-55 * /
--255--
7.4 keyboard.s program
277 alt_map:
278 . byte 0,0
279 . ASCII "\ 0 @ \ $ 0 \ 0 \ 0 {[]} 0 \\\"
280 . byte 0,0
281 . byte 0,0,0,0,0,0,0,0,0,0,0
282 . byte '~, 13,0
283 . byte 0,0,0,0,0,0,0,0,0,0,0
284 . byte 0,0
285 . byte 0,0,0,0,0,0,0,0,0,0,0
286 . byte 0,0,0,0 / * 36-39 * /
287 . fill 16,1,0 / * 3A-49 * /
288 . byte 0,0,0,0,0 / * 4A-4E * /
289 . byte 0,0,0,0,0,0,0 / * 4F-55 * /
290 . byte '|
291 . fill 10,1,0
292 293 #elif defined (KBD_US)
294
// The following is a US keyboard scan code mapping table.
295 key_map:
296 . byte 0,27
297 . ascii "1234567890- ="
298 . byte 127,9
299 . ascii "qwertyuiop []"
300 . byte 13,0
301 . ascii "asdfghjkl; '"
302 . byte ' `, 0
303 . ascii "\\ zxcvbnm,. /"
304 . byte 0, '*, 0,32 / * 36-39 * /
305 . fill 16,1,0 / * 3A-49 * /
306 . byte '-, 0,0,0,' + / * 4A-4E * /
307 . byte 0,0,0,0,0,0,0 / * 4F-55 * /
308 . byte '<
309 . fill 10,1,0
310311312 shift_map:
--256--
7.4 keyboard.s program
345
// The following is a German keyboard scan code mapping table.
346 key_map:
347 . byte 0,27
348 . ascii "1234567890 \\ '"
349 . byte 127,9
350 . ASCII " qwertzuiop @ +"
351 . byte 13,0
352 . ascii "asdfghjkl [] ^"
353 . byte 0, '#
354 . ascii "yxcvbnm, .-"
355 . byte 0, '*, 0,32 / * 36-39 * /
356 . fill 16,1,0 / * 3A-49 * /
357 . byte '-, 0,0,0,' + / * 4A-4E * /
358 . byte 0,0,0,0,0,0,0 / * 4F-55 * /
359 . byte '<
360 . fill 10,1,0
361 362 363 shift_map:
--257--
7.4 keyboard.s program
397
// The following French keyboard scan code mapping table.
398 key_map:
399 . byte 0,27
400 . ascii "& {\" '(-} _ / @) = "
401 . byte 127,9
402 . ascii "azertyuiop ^ $"
403 . byte 13,0
404 . ascii "qsdfghjklm |"
405 . byte ' `, 0,42 / * Coin sup gauche, do not know, [* | mu] * /
406 . ascii "wxcvbn,;:!"
407 . byte 0, '*, 0,32 / * 36-39 * /
408 . fill 16,1,0 / * 3A-49 * /
409 . byte '-, 0,0,0,' + / * 4A-4E * /
410 . byte 0,0,0,0,0,0,0 / * 4F-55 * /
411 . byte '<
412 . fill 10,1,0
413 414 shift_map:
--258--
7.4 keyboard.s program
* do_self for handling "normal" key, that meaning has not changed and only a return key characters.
*/
453 do_self:
// 454-460 mode for selecting one row alt_map, shift_map or key_map mapping table according to the mode flag.
454 lea alt_map,% ebx // alt key while mapping table base when pressed alt_map ebx.
455 testb $ 0x20, mode / * Alt-gr * / / * the right alt key while pressing the? * /
456 jne 1f // yes, forward jump to number 1.
457 lea shift_map,% ebx Base address mapping table when // shift key while pressing shift_map ebx.
458 testb $ 0x03, mode // the shift key while pressing there yet?
// get the scan code mapping table ASCII characters, if no corresponding character, is returned (transferred none).
461 1: movb (% ebx,% eax),% al // The scan code value as an index, taking the ASCII code corresponding al.
// if the key is pressed or ctrl caps lock key, and the characters 'a' - '}' in the range of (0x61-0x7D), then it is transferred to uppercase // (0x41-0x5D).
464 testb $ 0x4c, mode / * Ctrl or caps * / / * control key has been pressed or caps bright? * /
// If the ctrl key has been pressed, and the characters '' '--'_' between (0x40-0x5F) (uppercase characters), it is converted into control characters // (0x00-0x1F).
471 2: testb $ 0x0c, mode / * Ctrl * / / * ctrl key while pressing yet? * /
472 je 3f // If not then go to number 3.
--259--
7.4 keyboard.s program
473 cmpb $ 64,% al // al and the '@' (64) comparison character (i.e., character belongs is determined range).
475 cmpb $ 64 + 32,% al // al and the '' '(96) comparison character (i.e., character belongs is determined range).
476 jae 3f // If the value of> = ' `', turn the numeral 3.
// If the alt key while pressing the left, then bit 7 set of characters.
478 3: testb $ 0x10, mode / * Left alt * / / * alt key while pressing the left? * /
479 je 4f // No, turn the key 4.
480 orb $ 0x80,% al // 7-bit character set.
// al characters into the read buffer queue.
481 4: andl $ 0xff,% eax // clear the high word of eax and ah.
* Minus has its own processing subroutine, because 0xe0 minus sign before the scan code
*/
491 minus: cmpb $ 1, e0 // e0 flag is set yet?
492 jne do_self // no, the call do_self to the minus symbol for normal processing.
493 movl $ '/,% eax // Otherwise, the '/' Alternatively minus '-' al.
498 * This table decides which routine to call when a scan-code has been
499 * Gotten. Most routines just call do_self, or none, depending if
500 * It is make or break.
501 * /
/ * Here is a subroutine address of the jump table. When the scan code after obtaining call processing routine corresponding scan code in accordance with this table.
* Most subroutine call is do_self, or none, which must then play button (make) or the release button (break).
*/
502 key_table:
503 . long none, do_self, do_self, do_self / * 00-03 s0 esc 1 2 * /
504 . long do_self, do_self, do_self, do_self / * * 04-073456 /
505 . long do_self, do_self, do_self, do_self / * 08-0B 7 8 9 0 * /
506 . long do_self, do_self, do_self, do_self / * 0C-0F + 'bs tab * /
507 . long do_self, do_self, do_self, do_self / * 10-13 qwer * /
508 . long do_self, do_self, do_self, do_self / * 14-17 tyui * /
509 . long do_self, do_self, do_self, do_self / * 18-1B op} ^ * /
510 . long do_self, ctrl, do_self, do_self / * 1C-1F enter ctrl as * /
511 . long do_self, do_self, do_self, do_self / * 20-23 dfgh * /
512 . long do_self, do_self, do_self, do_self / * 24-27 jkl | * /
513 . long do_self, do_self, lshift, do_self / * 28-2B {para lshift, * /
514 . long do_self, do_self, do_self, do_self / * 2C-2F zxcv * /
515 . long do_self, do_self, do_self, do_self / * 30-33 bnm, * /
--260--
7.4 keyboard.s program
--261--
7.4 keyboard.s program
* Kb_wait subroutine for waiting for the keyboard controller buffer empty. There is no time-out process - if
575 testb $ 0x02,% al // test whether the input buffer is empty (equal to 0).
* This subroutine is provided by the keyboard controller, outputs a negative pulse reset line, to reset the system restart (reboot).
*/
583 reboot:
584 call kb_wait // First wait keyboard controller input buffer is empty.
The host system keyboard controller board is used intel 8042 Chip or a compatible chip, which diagram, see FIG. 7-6 Fig. Wherein the output port P2 They are used
for other purposes. Place 0 (P20 Pin) for implementing CPU Reset operation, the bit 1 ( P21 Pin) for control A20 On signal line or not. When the bit output port 0 for 1 When it is
A signal line. See the boot program in the chapter on A20 Detailed description of the signal line.
--262--
7.4 keyboard.s program
Input port P1
Output port P2
Data (0x60) input buffer
Bus P20 A20 reset NC NC strobe output
P21 buffer full (the IRQ1) input buffer
(0x64) input buffer P22 empty (unused)
P23
P24
P25
(0x64) Status Register
P26 Keyboard clock (two-way)
P27 Keyboard Data (bidirectional)
Assigned to the keyboard controller IO Port range is 0x60-0x6f ,But in fact IBM CP / AT Use only 0x60 with 0x64 Two port address ( 0x61 , 0x62 with 0x63 And for XT Compatibility
purposes) Table 7-1 Shown, together with the meaning of the read and write operations of different ports, and thus may have major 4 Different operations. Keyboard controller is
programmed, the chip will involve status register, an input buffer and an output buffer.
Is a 8 Bit read-only register. When the controller receives the keyboard scan codes from the keyboard or a command
Data port or an output buffer
0x60 read response, the status register bit is set on the one hand 0 = 1 On the other hand generate an interrupt IRQ1 . Generally should
For transmitting the command and / or subsequent parameter to a keyboard or write parameters to the keyboard controller.
0x60 write The input buffer
There are keyboard commands 10 And more, see the table after the description. Usually in the state should only port bit 1 = 0 When writing.
The port 0x61 Yes 8255A Output port B The address is for use / compatible 8255A of PC Standard keyboard processing
circuit performs hardware reset. The port is used to make a response to the scan code received. First method is prohibited
keyboard, and then immediately re-enabled keyboard. The operation data is: Bit 7 = 1 Prohibition keyboard; = 0 Allows the
0x61 Read / Write
keyboard; bit 6 = 0 Forcing the keyboard clock is low, so the keyboard can not send any data. Place 5-0 These bits are
Is a 8 Bit read-only register bit fields which are meanings: Bit 7 = 1 Parity error data transmitted
from the keyboard; bits 1 6 = Receive Timeout (keyboard transfer has not occurred IRQ1) ; Bit 5
= 1 Send Timeout (keyboard does not respond); Bit 4 = 1 Keyboard interface keyboard lock is
disabled; [a = ?? 0 When] Bit 3 = 1 Data is written to the input buffer is a command (via port 0x64)
0x64 read Status Register
;
= 0 Data is written into the input buffer parameters (through port 0x60) ; Bit 2 System flag
--263--
7.4 keyboard.s program
Place 1 = 1 Input Buffer Full ( 0x60 / 64 Mouth to 8042 Data); Bit 0 = 1 Output buffer full
Write command to the keyboard controller. You can take a parameter, the parameter from the port 0x60 Write. Keyboard
0x64 write The input buffer
controller command has 12 Article, see the table illustrates.
In the port system 0x60 Write 1 Byte, it is to send keyboard commands. After receiving a command keyboard 20ms Response should be within that returns a command
response. After some commands need to keep up a parameter (also written to the port). Command List Table 7-2 Fig. Note that unless otherwise specified, all commands are sent
Set / reset mode indicator. Put 1 Open, 0 shut down. Parameters byte: Bit 7-3 Are all
reserved 0 ; Bit 2 = caps-lock Key; bit 1 = num-lock Key; bit 0 = scroll-lock key.
0xed Have
0xf0 Have 0x01 - Selection scan code set 1( For PCs , PS / 2 30 Wait);
0xf2 no Read the keyboard identification number (read 2 Bytes). AT Keyboard returns a response code 0xfa .
Rate and delay time setting scan code sent continuously. The meaning of parameter byte: Bit 7 Leave 0 ; Bit 6-5 Delay
value: Order C = Place 6-5 , There is a formula: latency value = ( 1 + C) * 250ms ; Bit 4-0 Scan code rate
transmitted continuously; Order B = Place 4-3 ; A = Place 2-0 , There is the formula: Rate = 1 / ((8 + A) * 2 ^ B *
0xf3 Have
0.00417) . The default parameter value 0x2c .
0xfe no Retransmission scan code. When the system detects the keyboard to transmit data is an error, send the command.
Reset operation performed on a keyboard, called the basic assurance tests ( BAT) . During operation as follows:
0xff no 2. Keyboard controller so that the keyboard clock and data lines is asserted high;
4. If completed normally, the keyboard sends 0xaa ; Otherwise transmit 0xfd And stop scanning.
--264--
7.4 keyboard.s program
The system input buffer (port 0x64) Write 1 Byte, i.e. sends a command to the keyboard controller. You can take a parameter. Parameters is by writing 0x60
0x20 no The last byte of a read command to the keyboard controller, on the port 0x60 For the system to read.
0x21-0x3f no Low read by the command 5 Bits specified internal controller RAM Commands.
Write keyboard controller command byte. The default value parameter byte :( 0x5d ) Bit 7 Leave 0 ; Bit 6 IBM PC Compatibility
mode (parity, the system is converted to a scan code, one-byte PC Disconnect code); Bit 5 PC Mode (without scan code
parity; the system is not converted into a scan code); Bit 4 Working disable the keypad (keyboard so that the clock is low); Bit
3 Beyond prohibited ( override) , Keyboard lock converter ineffective; bit 2 System flag; 1 Indicates that the controller works
0x60-0x7f Have correctly; bit 1 Leave 0 ; Bit 0 It allows the output register full interrupt.
0xaa no Keyboard controller initialization self-test. Successful return 0x55 ; Failure to return 0xfc .
0x00 Error-free;
0xac no Diagnostic dump. 804x of 16 byte RAM , An output port, the input port are sequentially output to the system state.
0xc0 No Reading 804x Input port P1 And placed 0x60 For reading;
0xd0 No Reading 804x Output port P2 And placed 0x60 For reading;
0xd1 Write 804x Output port P2 ,original IBM PC Using bit output port 2 control A20 door. Note that the bit 0 ( system
System Reset) should always set bit.
0xe0 no Read test end T0 with T1 An input buffer for the system to send the read output.
Place 1 Keyboard data; bit 0 Keyboard clock.
control led status. Put 1 Open, 0 shut down. Parameters byte: Bit 7-3 Are all
reserved 0 ; Bit 2 = caps-lock Key; bit 1 = num-lock Key; bit 0 = scroll-lock key.
0xed Have
Send pulses to the output port. The output port control command sequence P20-23 Line, the keyboard controller logic see FIG. To make
0xf0-0xff no what a negative output pulse ( 6 Sec), i.e., the bit is set 0 . That is the order of the low 4 Control the position of the negative pulse. For
example, to reset the system, you need to issue the command 0xfe (P20 Low) can be.
PC It is non-coding machine keyboard. Each key has a position number on the keyboard, from left to right from top to bottom. and PC XT
--265--
7.4 keyboard.s program
Machine and AT Keypad code location varies greatly. The microprocessor in the system is sent to the keyboard corresponding to the key scan code. When the key is pressed, the
keyboard scan code output is called ON ( make) Scan code when the key is sent is called loosening off ( break) Scan code. XT Each key keyboard scan code table 7-4 Fig.
Each key on the keyboard has a low byte contains 7 Bit (Bit 6-0 ) Corresponding scan code. At a high level (position 7 ) Represents a key or button is released. Place 7 = 0 Represents
just pressed the key scan code bits 7 = 1 It represents a scan code of the key release. For example, if someone had just ESC
Key is pressed, the scan code is transmitted to the system would be 1 ( 1 Yes ESC Key scan code), when releasing the key will produce 1 + 0x80 = 129 Scan code.
for PC , PC / XT Standard 83 Key keyboard, the key scan code number ON (key position code) is the same. And with 1 Bytes. E.g" A "Key, the key position number is 30 ,
Access code scan code is 0x1e . And it is on its off code is the scan code plus 0x80 , which is 0x9e . for AT Used machine 84/101/102 Extended keyboard, and then PC / XT Standard
For some "extended" keys, the situation is somewhat different. When an extended key is pressed, an interrupt is generated and the keyboard port outputs an
"extended" scan code prefix 0xe0 And on the next "break" will be given. For example, for PC / XT Standard keyboard, the left control key ctrl The scan code is 29 , And the
right of "extended" control key ctrl The scan code having a spreading 29 . This rule is also suitable for alt Arrow keys.
In addition, there are two key processing is very special. PrtScn Key and Pause / Break key. Press PrtScn Key keyboard program will be interrupted to send * 2* Extended
characters, 42 (0x2a) with 55 (0x37) , So the actual byte sequence will be 0xe0 , 0x2a , 0xe0 , 0x37 . However, transmitting only the spreading code is generated when the key repeat 0x37
. When the key is released again sent two plus extension 0x80 Code ( 0xe0 ,
0xaa , 0xe0 , 0xb7 ). when prtscn When the key is pressed, if shift or ctrl Key is also pressed, only the transmitted 0xe0 , 0x37 And transmits only upon release 0xe0 , 0xb7) .
for Pause / Break key. If you press this button while also pressing the Control key, the line will expand as key 70 , While it sends a character sequence in
other cases 0xe1 , 0x1d , 0x45 , 0xe1 , 0x9d , 0xc5 . The Press and will not repeat the scan code, but also does not release any key scan code.
Thus, it can be used to view and handle: scan code 0xe0 It means that there is a character followed, and the scan code 0xe1 It said later followed 2 Characters.
for AT Keyboard scan codes, and PC / XT Slightly different. When the key is pressed, the corresponding key scan code is sent, but the key is released, will be sent two
bytes, the first one is 0xf0 The first 2 A key scan code is the same. Designers now use the keyboard 8049 As a AT Keyboard input processor for backwards compatibility will AT Keyboard
scan code conversion issue has become old-fashioned PC / XT Standard keyboard scan codes.
AT There are three separate keyboard scan code set: one is that we described above ( 83 Key mapping, increases have extra keys 0xe0 Code), an almost sequence, there is
a but only 1 Bytes! The last one kind of problem is caused by only the left shift , caps ,left ctrl And left alt Release the key code is transmitted. The default keyboard scan code set is
the scan code set 2 , You can use the command change.
For the scan code set 1 with 2 With special code 0xe0 with 0xe1 . They have the keys for the same function. For example: left control key ctrl Location is 0x1d ( for PC /
XT) The control keys on the right is 0xe0 , 0x1d . This is to PC / XT Program compatibility. Please note that the only use 0xe1 The time when it means a temporary control keys, this
--266--
7.5 console.c program
This is one of the longest in the kernel, but relatively simple function. All of which are routine in order to achieve the terminal screen write function con_write () And a
terminal initialization.
function con_write () From the terminal will tty_struct Write buffer queue structure write_q Remove the characters or character sequences, depending on the nature and
character (ordinary characters or escape sequences), the characters are displayed on the terminal screen, or some cursor movement, character control operation screens such as
an erasable.
Terminal screen initialization function con_init () The system is based on information obtained during system initialization, settings related to the basic parameters of the
For a description of the terminal device may be found in the character buffer queue include / linux / tty.h head File. Wherein the data structure is given character buffer
queue tty_queue The data structure of the terminal tty_struct And some of the value of the control characters. There are also a number of macro definition buffer queue operation.
1/*
2 * Linux / kernel / console.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
8* console.c
9*
10 * This module implements the console io functions
11 * 'Void con_init (void)'
12 * 'Void con_write (struct tty_queue * queue)'
13 * Hopefully this will be a rather complete VT102 implementation.
14 *
15 * Beeping thanks to John T Kohl.
16 * /
/*
* The console module for input and output functions
*
* Thanks John T Kohl realized beep indication.
*/
1718 / *
19 * NOTE !!! We sometimes disable and enable interrupts for a short while
20 * (To put a word in video IO), but this will work even for keyboard
--267--
7.5 console.c program
twenty one * Interrupts. We know interrupts are not enabled when getting a keyboard
twenty two * Interrupt, as we use trap-gates. Hopefully all is well.
twenty three * /
/*
* Note !!! We sometimes briefly interrupts disabled and enabled (in a word (word) into the video IO), but even
* It is also possible for the keyboard interrupt work. Because we use a trap door, so we get to know in a
* When the keyboard interrupt is not allowed. I hope everything were normal.
*/
2425 / *
// Some parameters related descriptors set and get embedded assembly function macro statement.
31 #include <linux / tty.h> // tty header file, which defines tty_io, aspects of the serial communication parameters constant.
32 #include <asm / io.h> // io header files. Defined hardware port I / O macro assembler statements.
33 #include <asm / system.h> // system header files. Set or modify the defined descriptors / interrupt gate or the like embedded macro assembler.
3435 / *
52 #define VIDEO_TYPE_EGAC 0x21 / * EGA / VGA in Color Mode * / / * EGA / VGA color * /
5354 #define NPAR 16
--268--
7.5 console.c program
68
// the following variables are used to screen scrolling operations.
69 static unsigned long origin ; / * Used for EGA / VGA fast scroll * / // scr_start. / * For EGA / VGA fast
scrolling * / // scroll starting memory address.
70 static unsigned long scr_end ; / * Used for EGA / VGA fast scroll * /
/ * For EGA / VGA fast scrolling * / // Scroll end memory address.
71 static unsigned long pos ; // current cursor position corresponding to the display memory.
73 static unsigned long top , bottom ; // top-line number when scrolling; bottom line number.
// state for the current step indicated at process ESC escape sequence. npar, par [] for storing intermediate processing parameters ESC sequence.
75 static unsigned long npar , par [ NPAR ]; // ANSI escape sequence number of parameters and the parameter array.
*/
// csi - preamble sequence control (Control Sequence Introducer).
85 #define RESPONSE "\ 033 [1;? 2c"
8687 / * NOTE! Gotoxy thinks x == video_num_columns is ok * /
/ * Note! gotoxy function think x == video_num_columns, that's right * / //// tracking the current
cursor position.
// Parameters: new_x - cursor column number; new_y - cursor line number.
// Update the current cursor position variables x, y, and correction points corresponding to the position pos cursor in the display memory.
88 static inline void gotoxy (Unsigned int new_x, unsigned int new_y)
89 {
--269--
7.5 console.c program
// If the cursor is beyond the number of the input line number display column, or cursor line number exceeds the maximum number of lines displayed, exit.
92 x = New_x;
93 y = New_y;
94 pos = origin + y * video_size_row + ( x << 1);
95 }
96
//// scroll start display memory address is provided.
position adjustment // memory location corresponding to the end of the last line of the screen and the character pointers scr_end.
// moved to the display memory at the starting position video_mem_start, and appear on a new line fill the space character.
position video_mem_start);% 3 - esi (the contents of the screen memory corresponding to the starting position of origin). @ Moving direction: [edi] [esi], the mobile ecx longword.
121 "Stosw"
122 :: " a "( video_erase_char ),
123 "C" (( video_num_lines -1)* video_num_columns >> 1),
124 "D" ( video_mem_start ),
125 "S" ( origin )
--270--
7.5 console.c program
(space character).
//% 0 - eax (erase character attributes +);% 1 - ecx (number of character rows in the display);% 2 - edi (corresponding to the last line of the screen at the start of memory);
corresponding to the screen will move from the top row to the end of the specified screen display memory data of all rows up one line, and rub // fill in the row of characters in addition to
emerging.
//% 0-eax (erase character attributes +);% 1-ecx (top row rows beginning at row 1 to the last line of the screen memory corresponding to the length of words); //% 2-edi (top row at
140 } Else {
141 __asm __ ( " cld \ n \ t " // clear direction bit.
146 "Stosw"
147 :: " a "( video_erase_char ),
148 "C" (( bottom - top -1)* video_num_columns >> 1),
149 "D" ( origin + video_size_row * top ),
150 "S" ( origin + video_size_row * ( top +1))
151 : " cx "," di "," si ");
152 }
153 }
// If the display type is not EGA (a MDA), is performed following the move operation. Because MDA display controller automatically adjusts the display case exceeds the range // around, i.e.
automatically scrolling pointer, corresponding to the case where the memory does not exceed the contents of the screen display memory separately. // processing method and the
--271--
7.5 console.c program
// window moves up one line screen, the screen display content moving down one line, a new line appeared to be moved over the start line. Description See the list of programs // later.
Processing method scrup () is similar to, but does not appear to display data in a mobile cover case error // condition, copying is performed when the reverse direction the data memory, i.e., the
reciprocal of the last character of the line from the copied second start screen
// [?? if and else seems to operate exactly the same ah! Why were you deal with it? Is it relevant to the task switching? ]
corner //% 2-edi (Screen Finally, a long word location);% 3-esi (screen penultimate line last word length position). @ Moving direction: [esi] [edi], the mobile ecx longword.
178 "Movl _video_num_columns, %% ecx \ n \ t" // Ecx = 1 is set number of lines of characters.
179 "Rep \ n \ t" // erases the character to fill the top of the new line.
180 "Stosw"
181 :: " a "( video_erase_char ),
182 "C" (( bottom - top -1)* video_num_columns >> 1),
183 "D" ( origin + video_size_row * bottom -4)
184 "S" ( origin + video_size_row * ( bottom -1) -4)
185 : " ax "," cx "," di "," si ");
186 }
// If not EGA display type, do the following (at present exactly the same as above).
187 else / * Not EGA / VGA * /
188 {
189 __asm __ ( " std \ n \ t "
190 "Rep \ n \ t"
191 "Movsl \ n \ t"
192 "Addl $ 2, %% edi \ n \ t" / *% Edi has been decremented by 4 * /
193 "Movl _video_num_columns, %% ecx \ n \ t"
194 "Rep \ n \ t"
195 "Stosw"
196 :: " a "( video_erase_char ),
197 "C" (( bottom - top -1)* video_num_columns >> 1),
198 "D" ( origin + video_size_row * bottom -4)
199 "S" ( origin + video_size_row * ( bottom -1) -4)
200 : " ax "," cx "," di "," si ");
201 }
202 }
203
//// position of the cursor down one line (lf - line feed newline).
204 static void lf (Void)
205 {
--272--
7.5 console.c program
// If the cursor was not in the penultimate line, the current line of the cursor directly modify the variable y ++, and adjusts the display memory location corresponding to the cursor // POS (plus
232 if ( x ) {
233 pos - = 2;
234 x -;
235 * (Unsigned short *) pos = video_erase_char ;
236 }
237 }
238
//// delete portions associated with the cursor position on the screen, in screen units. csi - preamble sequence control (Control Sequence // Introducer).
// ANSI escape sequences: 'ESC [sJ' (s = 0 to the bottom of the screen cursor is deleted; 1 starts to remove the screen cursor; 2 deleted the entire screen). // Parameters: par - corresponding
to the above s.
--273--
7.5 console.c program
243
// first need to remove were set according to the number of characters and three cases of display memory deletion start position.
//% 0 - ecx (the number of characters you want to delete count);% 1 - edi (delete start address);% 2 - eax (fill in the erase character).
// ANSI escape sequences: 'ESC [sK' (s = 0 to the end of the line deleted; 1 removed from the beginning; delete whole line 2).
--274--
7.5 console.c program
290 }
// then use the erase character to delete characters to fill in place.
//% 0 - ecx (the number of characters you want to delete count);% 1 - edi (delete start address);% 2 - eax (fill in the erase character).
'ESC [nm'. n = 0 normal display; 1 bold; 4 underlined; reverse display 7; 27 normal display.
// The display memory corresponding to the cursor position pos, set the display position of the cursor controller.
move to the right indicates low byte and then moved to the high byte divided by 2). With respect to the default display memory operations.
--275--
7.5 console.c program
333 copy_to_cooked (Tty); // pattern into a canonical (into the auxiliary queue).
334 }
335
//// insert a space character at the cursor position.
character, then the line will not be the last character modifiers ☺?
357 bottom = video_num_lines ; // set the screen to scroll the last line.
358 scrdown (); // From the beginning of the cursor, the contents of the screen to scroll down one line.
370 i=x;
371 while (++ i < video_num_columns ) {
372 * p = * (p + 1);
373 p ++;
374 }
// Fill erase the last character of the character (the space character).
375 * P = video_erase_char ;
--276--
7.5 console.c program
376 }
377
//// cursor to delete rows.
// volume line from the start line where the cursor onscreen.
385 bottom = video_num_lines ; // set the screen to scroll the last line.
386 scrup (); // From the beginning of the cursor, the contents of the screen to scroll up one line.
--277--
7.5 console.c program
433
//// it saves the current cursor position.
0: an initial state; originally state or 4; or a state originally, but not the character '['; //
1: 0 state was originally, and the character is an escape character ESC (0x1b = 033 = 27);
// 3: 2 was originally state; state or was originally 3, and the character is a ';' or digital.
--278--
7.5 console.c program
475 else if (c == 8) {
476 if ( x ) {
477 x -;
478 pos - = 2;
479 }
// If the character c is a horizontal tab TAB (9), the cursor will be a multiple of 8 columns. If the cursor is at this time the number of columns exceeds the maximum number of columns of the
480 } Else if (c == 9) {
481 c = 8- ( x & 7);
482 x + = C;
483 pos + = C << 1;
484 if ( x > video_num_columns ) {
485 x - = video_num_columns ;
486 pos - = video_size_row ;
487 lf ();
488 }
489 c = 9;
// If the character c is the bell character BEL (7), beep function is called, is the sound from the speakers.
490 } Else if (c == 7)
491 sysbeep ();
492 break;
// 0 if the original state, and the character is an escape character ESC (0x1b = 033 = 27), then the process moves to a state 1.
--279--
7.5 console.c program
493 case 1:
494 state = 0;
// If character c is '[', the state will go to state 2.
495 if (c == '[')
496 state = 2;
// If the character c is 'E', then move to the next row at the beginning (0).
time '?', Then go directly to the state 3 to deal with, or to read a character, and then to state 3 at handling code.
517 case 3:
// If the character c is a semicolon ';', and par full array, the index value plus one.
525 case 4:
526 state = 0;
527 switch (c) {
// If the character c is a 'G' or '' ', the PAR [] the first parameter represents a column number. If the column number is not zero, then the cursor right one space.
--280--
7.5 console.c program
// ANSI escape sequences: 'ESC [sJ' (s = 0 to the bottom of the screen cursor is deleted; 1 starts to remove the screen cursor; 2 deleted the entire screen).
[sK' (s = 0 to the end of the line deleted; 1 removed from the beginning; delete whole line 2).
--281--
7.5 console.c program
// If the character c is 'L', n represents a row insert (ANSI escape sequences 'ESC [nL') at the cursor position.
sequences: 'ESC [nm'. n = 0 normal display; 1 bold; 4 underlined; reverse display 7; 27 normal display.
--282--
7.5 console.c program
614 * Reads the information preserved by setup.s to determine the current display
615 * Type and sets everything accordingly.
616 * /
/*
* void con_init (void);
* The console initialization routines interrupted, the other does nothing. If you want to clean the screen, then use
* Appropriate escape sequence to call tty_write () function.
*
* Setup.s reading information stored procedure to determine the current display type, and provided all relevant parameters.
*/
617 void con_init (Void)
618 {
619 register unsigned char a;
620 char * display_desc = "????";
621 char * display_ptr;
622
623 video_num_columns = ORIG_VIDEO_COLS ; // display shows the number of characters in the column.
624 video_size_row = video_num_columns * 2; // need to use the number of bytes per row.
625 video_num_lines = ORIG_VIDEO_LINES ; // display shows the number of characters in the line.
627 video_erase_char = 0x0720; // erase character (0x20 character display, 0x07 is the attribute).
628
// If the original display mode is equal to 7, then a monochrome display.
632 video_port_reg = 0x3b4; // Set the index register substantially single port.
// According to the information display mode BIOS interrupt 0x12 int 0x10 function obtained judgment monochrome display card or display card color display card. // If the above-described
interrupt register BX function obtained return value is not equal to 0x10, it indicates that the EGA card. Therefore the initial display types EGA // monochrome; memory mapped address used
for the terminal 0xB8000; display description string of juxtaposed 'EGAm'. // display during system initialization string will be described top-right corner of the screen.
638 display_desc = " EGAm "; // set the display character string is described.
639 }
// If the value of the BX register equals 0x10, it indicates that the monochrome display card MDA. It is set corresponding parameters.
640 else
641 {
642 video_type = VIDEO_TYPE_MDA ; // set the display type (MDA monochrome).
644 display_desc = "* MDA "; // set the display character string is described.
645 }
646 }
// If the display mode is not 7, for the color mode. At this time, the start address of the display memory is used 0xb800; // display control index register port addresses
650 video_port_reg = 0x3d4; // set the color display port index register.
651 video_port_val = 0x3d5; // set the color display port data register.
--283--
7.5 console.c program
// then judge the graphics card category. If BX is not equal to 0x10, it indicates that the EGA graphics card.
656 display_desc = " EGAc "; // set the display character string is described.
657 }
// If the value of the BX register equals 0x10, it indicates that the CGA graphics card. It is set corresponding parameters.
658 else
659 {
660 video_type = VIDEO_TYPE_CGA ; // set the display type (CGA).
661 video_mem_end = 0xba000; // set the display end address memory.
662 display_desc = "* CGA "; // set the display character string is described.
663 }
664 }
665
666 / * Let the user known what kind of display driver we are using * /
/ * Let the user know that we're using what kind of display driver * /
667
// in the upper right corner of the screen displays the description string. The method used is to directly write the string at a position corresponding to the display memory. // first the pointer is
displayed to the screen of the first row display_ptr means 4 characters at the right end of the differential (2 bytes required for each character, so minus 8).
673 }
674
675 / * Initialize the variables used for scrolling (mostly EGA / VGA) * /
/ * Initialize variables used for scrolling (mainly for EGA / VGA) * /
676
677 origin = video_mem_start ; // start scrolling display memory address.
678 scr_end = video_mem_start + video_num_lines * video_size_row ; // Scroll to end the memory address.
679 top = 0; // the top row of numbers.
681
682 gotoxy ( ORIG_X , ORIG_Y ); // initialize the cursor position x, y and the corresponding memory location pos.
683 set_trap_gate (0x21, & keyboard_interrupt ); // set the keyboard interrupt trap door.
684 outb_p ( inb_p (0x21) & 0xfd, 0x21); // cancel the 8259A keyboard interrupt masking, allowing IRQ1.
685 a = inb_p (0x61); // delay reading the keyboard port 0x61 (8255A port PB).
--284--
7.5 console.c program
698
// opened the beep.
Bit 1 is used as a speaker opening signal 8255A chip @ PB port; Timer bit 0 as 8253 is a gate signal 2, the output pulse of the timer // sent to the speaker, as
the speaker sound frequency. So make the speaker beeps two steps: first open port PB // bit 0 and bit 1 (bit set), then set the timer transmission timing
frequency can be constant.
Just to give instructions and instructions compatible display card port. Described MDA , CGA , EGA with VGA Display control card common programming ports, which are
related to CGA in use MC6845 Compatible chip, and uses the name table 7-5 Fig. Among them,
CGA / EGA / VGA Ports ( 0x3d0-0x3df) As an example, MDA The port is 0x3b0 - 0x3bf .
The basic steps of the display control card is programmed: firstly to write register index card, select one set of the internal registers of the display control
( r0-r17) , Which is then written to parameter port data register. I.e. the port data register card can only display a card internal register operation. Table internal
0x3d4 write CRT (6845) Index register. For selection by the port 0x3b5 Each accessed data register ( r0-r17) .
CRT (6845) Data register. Wherein the data register r12-r15 It can also be read. Each data
0x3d5 write
register function described below.
Mode control register. Place 7-6 Unused; bits 5 = 1 Allow flashing; bits 4 *
CGA Palette register. Select the color used. Place 7-6 Unused;
0x3d9 Read / Write
--285--
7.5 console.c program
Place 5 = 1 Set to activate color: green ( cyan) ,purple( magenta) ,White( white) ;
= 0 Set to activate color: red ( red) ,green( green) ,blue( blue) ; Bit 4 = 1 Enhanced display graphics, text
background color; bit 3 = 1 Enhanced display 40 * 25 Border, 320 * 200 Background, 640 * 200 Foreground
color; bit 2 = 1 Red: 40 * 25 Border, 320 * 200 Background, 640 * 200 Prospects; bit 1 = 1 Green: 40 * 25 Border, 320
* 200 Background, 640 * 200 Prospects; bit 0 = 1 Blue: 40 * 25 Border, 320 * 200 Background, 640 * 200 Prospects;
CGA Display state register. Place 7-4 Unused; bits 3 = 1 In the vertical retrace phase; Bit 2 = 1 Light pen switch is
turned off; = 0 Light pen switch is turned on; bit 1 = 1 Valid strobe light pen; Bit 0 = 1 Display may not interfere
with access to the display memory; = 0 Do not use this time to display memory.
0x3da read
0x3db write Clear latch light pen (light pen register reset).
0x3dc Read / Write Latch preset light pen (light pen strobe active force).
table 7-6 MC6845 Inside Ministry data register And the initial value register
r3 horizontal position of the horizontal sync pulse width Character 0x0a 0x0a 0x0a
r7 character
the vertical position of the vertical synchronizing the number of line character
characters line
displayed 0x1c 0x1c 0x70
r9 The maximum number of scanning lines Write scan lines 0x07 0x07 0x01
r10 End position the cursor Scan line Write 0x06 0x06 0x06
r11 start position of the cursor scan lines 0x07 0x07 0x07
r12 Display memory start position (high) Write 0x00 0x00 0x00
It refers to an operation of scrolling text contents of the specified start and ending lines in the upward movement (scroll up scroll up) Or downward movement (scroll down scroll
down) If the screen is viewed as a window displayed on the screen corresponding to the contents of the memory, then the contents of the screen window that is moved upward along
the display memory is moved downward; screen content that is moved downwardly move the window down. Display start position of the memory is re-set in the program in the
display controller origin And adjusting the corresponding variables in the program. For both operations each have two cases.
--286--
7.5 console.c program
For Scroll up, when the display memory corresponding to the screen displayed in the window is still within the memory range where after the downward movement, i.e., the
position corresponding to the memory block in the current screen display memory is always the starting position ( video_mem_start) And terminal position video_mem_end Between,
then only need to adjust the position of the display memory controller can start display. However, when the memory block corresponding to a position beyond the end of the
screen is actually displayed when the memory is moved downward ( video_mem_end) This case, it is necessary to move the display data corresponding to the memory, the current
screen to ensure that all the data fall within the display memory range. In this second case, the program is moved to the data memory corresponding to the screen at the start
The actual program process carried out in three steps. First, adjust the screen display start position origin ; Screen memory is then judged whether the corresponding
display memory data exceeds the lower bound ( video_mem_end) Start position, if the data out of memory corresponding to the screen will move to the actual display memory ( video_mem_start)
; Finally, after moving to a new line appears on the screen is filled with space characters. See Fig. 7-7 Fig. Wherein FIG. ( a)
The first corresponds to a simple case, in FIG. ( b) It corresponds to the case when the data memory needs to be moved.
origin
New origin
blanks
Content display screen
corresponding to the memory block
After scrolling the display
screen corresponding to the contents of memory New scr_end fill in
Copy block
scr_end
(A) on a volume generally (B) moving the screen where required data
Scroll down operation screen similar to the upward scrolling, both will encounter a similar situation, but since the shift windows on the screen, so there will be a blank line
at the top of the screen, and beyond the display memory content on the screen corresponding to the memory screen data memory block needs to be moved to the end position of
Terminal usually has two functions, namely as a computer input device information (keyboard) and the output settings (display). The terminal may have a number of
control commands, so that the terminal to perform certain operations instead of just a character displayed on the screen. This way, the computer can instruct the mobile terminal to
perform the cursor, switching the display mode and the ringing operation. In order to understand the processing execution program, the terminal control command following simple
Control characters are ASCII Code at the beginning of table 32 Characters ( 0x00 - 0x1f or 0-31) And character DEL (0x7f or 127) See Appendix ASCII Code table. Typically a
specific type of terminal which will be adopted as a subset of the control characters, the control characters and the other will not work. For example, for VT100 Terminal control
--287--
7.5 console.c program
NUL 000 0x00 Ignored on input (not stored in the input buffer).
BS 010 0x08 Move the cursor to the left at a character position. If the cursor is already at the left edge, no motion.
HT 011 0x09 Move the cursor to the next tab stop. If the right side has no tab stops, then moves to the right edge.
LF 012 0x0a This code causes a carriage return or line feed operation (see wrap mode).
CR 015 0x0d Move the cursor to the left edge of the current line.
SO 016 0x0e Used by SCS Design of the control sequences G1 character set.
XOFF 023 0x13 In addition to sending the interrupt XOFF with XON Other than off all the other codes.
If sent during the control sequence, the sequence will not be executed immediately terminated. And it will display an error
CAN 030 0x18
characters.
DEL 177 0x7f Ignored on input (not stored in the input buffer).
It has been controlled by the sequence ANSI ( American National Standards Institute American National Standards Institute) The development of the standard:
X3.64-1977 . Control sequence refers to a special character sequence of control characters consisting of non-terminal upon receiving them directly This sequence is not displayed
on the screen, but take a certain control operation, for example, moving the cursor, deleting the character, deleting row, insert a character row or insert operation. ANSI The control
The control code sequence is introduced ( Control Sequence Introducer - CSI) : Indicates a transfer sequence, provide additional control and influence in itself is a prefix
followed by a series of consecutive characters to explain the meaning of. Typically, general CSI Use ESC [ .
parameter( Parameter) : Zero or more characters of a numeric value. The numerical parameters ( Numeric Parameter) : Represents a number of parameters, use n Representation.
Select parameter ( Selective Parameter) : A sub-function for selecting a function from a subset, generally used s Representation. Typically, the role of a control sequence
having a plurality of selected parameters generated, as several separate control sequence. E.g: CSI sa; sb; sc F The role and CSI sa F CSI sb F CSI sc F exactly the same.
Parameter string ( Parameter String) : Semicolon ';' parameter string separated. Defaults( Default) : When not explicitly specify a value or a value 0 It would specify a value
associated with the function. The last character ( Final character) : For terminating an escape or control sequence. Map 7-8 Is an example of a control sequence: Cancel
property of all the characters, then turned and underscore the highlighted property. ESC [0; 4; 7m
--288--
7.5 console.c program
delimiter
Delimiter
ESC [0; 4; 7 m
Select Parameters
Parameter string
CSI character
table 7-8 Are some of the commonly used control sequences lists. among them E Show 0x1b ,in case n Yes 0 Then, it can be omitted: E [0J == E [J
E [nA Move Cursor n Row E [nK Delete part or the entire line:
E [nB Cursor down n Row n = 0 Point to the end of the row from
E [nC Cursor right n Character position n = 1 From the beginning to the cursor line
E [n` Move the cursor to the character n position E [nX delete n Characters
E [na Cursor right n Character position E [nS Scroll up screen n Line (screen down)
E [nd Move the cursor to the line n on E [nT Scroll down the screen n Line (move on screen)
E [nF Move Cursor n OK, stop at the beginning of the line n = 0 General Property (no property)
E [nE Cursor down n OK, stop at the beginning of the line n = 1 Crude( bold )
E [H Move the cursor to the upper left corner of the screen n = 5 flicker( blink )
E [nZ Cursor backward n Tab stops n = 3X Set the foreground color display
E [nJ Sassafras part or all of the display character except: X = 6 green cyan X = 7 White white
n = 0 From the cursor to the bottom of the screen; Semicolon plurality of attributes may be provided at the same time,
n = 1 From the top of the screen to the cursor; E.g: E [0; 1; 33; 40m
--289--
7.6 serial.c program
This program distribution system, the serial port initialization, ready to work using a serial terminal. in rs_init () Initialization function, set the default serial communication
parameters, and sets the serial port interrupt trap door (interrupt vector). rs_write () Function terminal device for the serial write buffer queue character is sent to the remote terminal
rs_write () Will be used to be called when the operation character device file in the file system. When a serial device to program / dev / tty64 File performs a write operation,
it will perform system calls sys_write () (in fs / read_write.c In), and this system call when it is judged that the read file is a character device file that will call rw_char () Function (in fs
/ char_dev.c ), The function of which will be based on the read device information of the sub-device number and the like, the device is called by the character reader function table
(device switch table) rw_tty () Final call here to write a serial terminal function rs_write () .
rs_write () Function is actually just open the serial transmit holding register empty interrupt flag, in UART The data is sent an interrupt signal to allow hair. Specific operation
1/*
2 * Linux / kernel / serial.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
8* serial.c
9*
10 * This module implements the rs232 io functions
11 * void rs_write (struct tty_struct * queue);
12 * void rs_init (void);
13 * And all interrupts pertaining to serial IO.
14 * /
/*
* serial.c
* Input and output functions of the program for realizing rs232
*/
1516 #include <linux / tty.h>
// tty header file, which defines tty_io, aspects of the serial communication parameters constant.
17 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
18 #include <asm / system.h> // operating segment header files. For embedded segment register defines the operation assembly function.
19 #include <asm / io.h> // io header files. Defined hardware port I / O macro assembler statements.
2021 #define WAKEUP_CHARS ( TTY_BUF_SIZE / 4) when the write queue // contains WAKEUP_CHARS characters, starts transmitting.
twenty two
--290--
7.6 serial.c program
twenty three extern void rs1_interrupt (Void); // serial port interrupt handler (rs_io.s, 34) 1 a.
twenty four extern void rs2_interrupt (Void); // 2 serial port interrupt handler (rs_io.s, 38).
25
//// initialize the serial port
// port: Serial 1 - 0x3F8, Serial 2 - 0x2F8.
26 static void init (Int port)
27 {
28 outb_p (0x80, port + 3); / * Set DLAB of line control reg * /
/ * Set DLAB bit line control register (bit 7) * /
29 outb_p (0x30, port); / * LS of divisor (48 -> 2400 bps * /
/ * Low byte transmit baud rate factor, 0x30-> 2400bps * /
30 outb_p (0x00, port + 1); / * MS of divisor * /
/ * Baud transmission factors high byte, 0x00 * /
43 outb ( inb_p (0x21) & 0xE7,0x21); // master 8259A chip allows IRQ3, IRQ4 interrupt request signal.
44 }
4546 / *
47 * This routine gets called when tty_write has put something into
48 * The write_queue. It must check wheter the queue is empty, and
49 * Set the interrupt register accordingly
50 *
51 * void _rs_write (struct tty_struct * tty);
52 * /
/*
* In tty_write () has been data output (write) will call the following subroutine queue. Must first
* Write checks whether the queue is empty, and set the interrupt register.
*/
//// output serial data transmission.
// really just open the serial transmit holding register empty interrupt flag, allowing the hair UART interrupt signal after the data sent.
// If the write queue is not empty, from 0x3f9 (or 0x2f9) first read the interrupt enable register contents, add Transmit Holding Register interrupt enable flag after // (1 bit), and then
write back to the register. This will allow serial devices due to write (send) the character and cause disruption.
--291--
7.6 serial.c program
59 }
60
PC Asynchronous serial communication using the serial communication chip microcomputer is INS 8250 or NS16450 Compatible chips, collectively referred to as UART ( Universal
Asynchronous Receiver Transmitter). Correct UART Programming is actually read and write operations of its internal registers. It can be UART It sets as a set of registers,
comprising sending, receiving, and the control of three parts. UART Internal 10 Registers for CPU by IN / OUT Instructions to access it. Table port and uses these registers 7-9 Fig.
Which port 0x3f8-0x3fe A microcomputer COM1 Serial port, 0x2f8-0x2fe correspond COM2 port. condition DLAB (Divisor Latch Access Bit) It is the Divisor Latch Access Bit, bit line
table 7-9 UART Use the corresponding port and internal registers
0x3f8 (0x2f8) write DLAB = 0 Write Transmit Holding Register. Containing the character to be sent.
read DLAB = 0 Reading the receive buffer register. It contains characters received.
Read / Write DLAB = 1 Read / write low byte baud factor ( LSB ).
0x3f9 (0x2f9) Read / Write DLAB = 1 Read / Write Byte high baud rate factor ( MSB ).
Read interrupt identification register. The interrupt handler is used to determine the break 4
0x3fa (0x2fa) read 11 = Wrong interrupt receive status, the highest priority;
Bit 1 6 = Allow intermittent; bit 5 = 1 To maintain parity; bit 4 = 1 Even parity; = 0 Odd
parity; bit 3 = 1 Allow parity; = 0 No parity; bits 2 = 1 1 Stop bit; = 0 None Stop bit;
0x3fb (0x2fb) write
bit 1-0 Data bit length:
--292--
7.7 rs_io.s program
write modem Control register. Place 7-5 all 0 Reserved; bit 4 = 1 Chip diagnostic mode of
To the system; bit 2 = 1 Auxiliary user-specified output 1 , PC Machine is not used; bit 1
0x3fc (0x2fc) write = 1 That the request RTS Effective; Bit 0 = 1 The Data Terminal Ready DTR effective.
Reading the line status register. Place 7 = 0 Reserved; bit 1 6 = Transmit shift
the conditions; bit 3 = 1 A frame format error; Bit 2 = 1 Parity Error; Bit 1 = 1 Beyond
0x3fd (0x2fd) read coverage error; Bit 0 = 1 The receiver data is ready, the system can read.
Detect ( CD) Effective; Bit 1 6 = Ring Indicator ( RI) Effective; Bit 5 = 1 Data
Set Ready ( DSR) Effective; Bit 4 = 1 Clear to Send ( CTS ) Valid; bits 3 = 1 detected
δ Carrier; bit 2 = 1 Ring detected signal edge; bit 1 = 1 δ Data Set Ready ( DSR)
The assembler achieve rs232 Serial communication interrupt processing. During transit and storage of the character, the interrupt process mainly terminal read, write
buffer queue operation. Read it received from the serial line to the serial terminal into character buffer queue read_q
In the write buffer or queue write_q Characters to be sent out to the remote serial transmission terminal device through a serial line.
Serial interrupt occurs causing the system has 4 Species: a. due to modem The state has changed; b. Since the line status changes; c. Since the character is received; d. Since
the interrupt enable flag register is set Transmit Holding Register interrupt enable flag needs to send characters. Processing of the first two cases caused the interrupt by reading a
register value corresponding to the status, so that it is reset. For the case where the result of receiving a character, the program first reads the character into buffer queue read_q Then
call copy_to_cooked () Converted into a function to regulate the behavior of the character mode in units of character into the auxiliary queue secondary in. In the case of the
characters to be sent, the program first from the write buffer queue write_q At the end of the pointer is taken out a character is sent out, and then determines whether the write
--293--
7.7 rs_io.s program
Therefore, before reading this program, the best look at include / linux / tty.h head File. Wherein the data structure is given character buffer queue tty_queue The data
structure of the terminal tty_struct And some of the value of the control characters. There are also a number of macro definition buffer queue operation. Its schematic buffer queue
1/*
2 * Linux / kernel / rs_io.s
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
8* rs_io.s
9*
10 * This module implements the rs232 io interrupts.
11 * / / *
// offset corresponding to each variable defined in the include / linux / tty.h tty_queue file structure.
twenty one rs_addr = 0 // offset serial port number field (or a port number is 0x3f8 0x2f8).
twenty two head = 4 // offset buffer pointer field header.
twenty three tail = 8 // offset buffer tail pointer field.
twenty four proc_list = 12 // wait for the buffering process field offset.
* These are the actual interrupt program. Program first checks the interrupt source, and then perform the appropriate
* Processing.
*/
--294--
7.7 rs_io.s program
33 .align 2
1 //// serial port interrupt handler entry point.
34 _rs1_interrupt:
35 pushl $ _table_list + 8 // tty serial read and write buffer corresponding to the table address of the stack pointer 1 (tty_io.c, 99).
36 jmp rs_int // character buffer queue structure format See include / linux / tty.h, line 16.
37 .align 2
//// 2 serial port interrupt handler entry point.
38 _rs2_interrupt:
39 pushl $ _table_list + 16 // tty Table 2 corresponding serial read and write pointer of the buffer queue address stack.
40 rs_int:
41 pushl% edx
42 pushl% ecx
43 pushl% ebx
44 pushl% eax
45 push% es
46 push% ds / * As this is an interrupt, we can not * /
47 pushl $ 0x10 / * Know that bs is ok. Load it * /
48 pop% ds / * Since this is an interrupt routine, we do not know the correct ds * /
49 pushl $ 0x10 / * So load them (let ds, es pointing to the kernel data segment * /
50 pop% es
51 movl 24 (% esp),% edx // pointer address is stored in the buffer queue register edx, i.e. // address on line 35 or
52 movl (% edx),% edx // fetch buffer queue structure pointer (address) edx. // For the serial terminal, data field stores the
53 movl rs_addr (% edx),% edx // taken serial 1 (2 or serial) port number edx.
54 addl $ 2,% edx / * Interrupt ident. Reg * / / * edx points to the interrupt identification register * /
55 rep_int: // interrupt identification register port is 0x3fa (0x2fa), list information on the festival see.
58 testb $ 1,% al // first determine the presence or absence of the interrupt pending (bit 0 = No interrupt 1; 0 = interrupt).
59 jne end // If there is no pending interrupt, it jumps to exit the process at the end.
60 cmpb $ 6,% al / * This should not happen, but ... * / / * this will not happen, but ... * /
61 ja end // al values> 6? Is a jump to the end (there is no such state).
62 movl 24 (% esp),% ecx // then take the buffer queue pointer address ecx.
63 pushl% edx // interrupt identification register port number 0x3fa (0x2fa) stack.
0 = 0, bits 2-1 are the interrupt type, and thus corresponds to the type of interrupt has been multiplied by the @ 2, then by 2 here, the jump table is obtained (line 79) corresponding to
each interrupt type address, and jump go there to be treated accordingly. // There are four interrupt sources: modem status changes; write (send) character; to read (receives)
character; line status changes. // To send a character is interrupted by setting the transmit holding register mark achieved. rs_write in serial.c program () function, // write buffer when
there is data in the queue, it will modify the interrupt enable register such that when the content, adding the transmit holding register interrupt enable flag, the system needs to send
66 popl% edx // pop interrupt identification register port number 0x3fa (or 0x2fa).
67 jmp rep_int // Jump, continue to determine whether the pending interrupts and continue processing.
68 end: movb $ 0x20,% al // send complete interrupt instruction to the interrupt controller EOI.
--295--
7.7 rs_io.s program
76 addl $ 4,% esp # jump over _table_list entry # discard buffer queue pointer address.
77 iret
78
// address each type of interrupt handlers jump table, there are four types of interrupt sources: // modem status change interrupt, the interrupt
character to write, read character interrupt, the interrupt line status in question.
79 jmp_table:
80 . long modem_status, write_char, read_char, line_status
81
// Since modem state changes triggered by the interruption. Modem reset operation is performed by reading the status register thereof.
82 .align 2
83 modem_status:
84 addl $ 6,% edx / * Clear intr by reading modem status reg * /
85 inb% dx,% al / * Reset (0x3FE) by reading the modem status register * /
86 ret
87
// because the line state changes caused by the serial interrupt. Reset operation is performed by reading the line status register thereof.
88 .align 2
89 line_status:
90 addl $ 5,% edx / * Clear intr by reading line status reg. * /
91 inb% dx,% al / * Reset (0x3FD) by reading the Line Status Register * /
92 ret
93
// Because the serial device (chip) received characters caused the outage. The received character is read into the buffer queue pointer // read_q head (head) at a
forward pointer and so that character position. If the head pointer has reached the end of the buffer, the buffer is allowed to the beginning of the // folded. Finally, call
C functions do_tty_interrupt () (i.e. copy_to_cooked ()), the read characters into // after a certain processing mode specification into buffer queue (buffer queue
94 .align 2
95 read_char:
96 inb% dx,% al / * Read characters al.
97 movl% ecx,% edx / * Current serial buffer queue pointer address edx.
98 subl $ _table_list,% edx // buffer queue pointer table first site - the current serial queue pointer address edx,
104 andl $ size-1,% ebx // modulo the buffer size head pointer manipulation. Pointer can not exceed the buffer size.
105 cmpl tail (% ecx),% ebx // buffer head pointer and a tail pointer comparison.
106 je 1f // If equal, indicates that the buffer is full, a jump to the label.
107 movl% ebx, head (% ecx) // save the modified head pointer.
108 1: pushl% edx // The serial number onto the stack (1, 2 serial - port 2), as a parameter,
109 call _do_tty_interrupt // C function call tty interrupt handling (tty_io.c, 242,145).
110 addl $ 4,% esp // discard stack parameters, and return.
111 ret
112
// the provision of the Transmit Holding Register interrupt flag allows caused the interruption. DESCRIPTION serial terminal corresponding to character buffer write queue // there are
characters to send. So to calculate the write current number of characters contained in the queue, if the number of characters is less than 256 then waits for the write operation // wake-up
process. A character transmitted was then removed from the tail of the queue write buffer, and adjust and save the tail pointer. If the write buffer queue is empty, then jump to
113 .align 2
114 write_char:
115 movl 4 (% ecx),% ecx # write-queue # fetch address write buffer queue structure ecx.
116 movl head (% ecx),% ebx // get the write queue head pointer ebx.
--296--
7.8 tty_io.c program
117 subl tail (% ecx),% ebx // Pointer head - tail pointer = number of characters in the queue.
120 cmpl $ startup,% ebx // number of characters in a queue more than 256?
122 movl proc_list (% ecx),% ebx # wake up sleeping process # wakeup process is waiting. // wait to take the process
of the queue pointer, and determines whether the air.
123 testl% ebx,% ebx # is there any? # have to wait for the process of it?
124 je 1f // is empty, forward jump to number 1.
125 movl $ 0, (% ebx) // Otherwise, the process is set to be operational state (wake-up process). .
127 movb buf (% ecx,% ebx),% al // al take a character from the buffer tail pointer.
128 outb% al,% dx // fed to the holding register to a port 0x3f8 (0x2f8).
129 incl% ebx // tail pointer forward.
130 andl $ size-1,% ebx // If the tail pointer to the end of the buffer, is folded back.
131 movl% ebx, tail (% ecx) // save the modified tail pointer.
132 cmpl head (% ecx),% ebx // head pointer and tail pointer comparison,
133 je write_buffer_empty // If equal, indicates that the queue is empty, then jump.
134 ret
// write buffer processing the queue write_q already empty. If waiting for write the serial terminal processes the wake-up, then the shield sent // Holding Register Empty interrupt, an
135 .align 2
136 write_buffer_empty:
137 movl proc_list (% ecx),% ebx # wake up sleeping process # wakeup process is waiting. // wait to take the process
of the queue pointer, and determines whether the air.
138 testl% ebx,% ebx # is there any? # have to wait for the process of it?
139 je 1f # No, jump to the forward reference numeral 1.
140 movl $ 0, (% ebx) # Otherwise, the process is set to be operational state (wake-up process).
Each tty Equipment 3 A buffer queues, each queue is a read buffer ( read_q ), Write buffer queue ( write_q ) And an auxiliary buffer queue ( secondary ), As defined in tty_struct
Structure ( include / linux / tty.h ). For each buffer queue, the read operation is to take the characters from the left end of the buffer queue, and the buffer queue tail ( tail ) Pointer
moves to the right. While the write operation is added to the right end of the character buffer queue, and also head ( head) Pointer moves to the right. These two pointers, when any
one of moving beyond the end of the buffer queue, the left end is folded back again. See Fig. 7-9 Fig.
--297--
7.8 tty_io.c program
character
This program includes an upper layer device interface function characters. The main terminal containing a read / write function tty_read () with tty_write () . Read line function
tty_read () with tty_write () Will be used to be called when the operation character device file in the file system. For example, when a program read / dev / tty
When the file, it will execute a system call sys_read () (in fs / read_write.c In), and this system call when it is judged that the read file is a character device file that will call rw_char () Function
(in fs / char_dev.c ), The function of which will be based on the read device information of the sub-device number and the like, the device is called by the character reader function
table (device switch table) rw_tty () Final call here a read operation of the terminal function tty_read () .
copy_to_cooked () Keyboard interrupt function is called by the process (by do_tty_interrupt () ), According to the terminal termios Structure is provided a character input /
output flag (e.g. INLCR , OUCLC )Correct read_q Characters in the queue are processed, converting the character pattern into a canonical sequence of characters in units of
characters, and the characters stored in the secondary buffer queue (buffer queue specification mode) ( secondary ), And into which the tty_read () Read. During the conversion
process, if the terminal flag echo L_ECHO Set, the character will be put into the write queue
write_q And calls the write function to end the character displayed on the screen. If a serial terminal, then write function will be rs_write () (in
serial.c , 53 Row). rs_write () Serial terminal will write queue serial character is sent to the terminal over the serial link, and displayed on the screen of the serial terminal. copy_to_cooked
() The last function will wake auxiliary buffer queue waiting for the process. Step to achieve the function as follows:
1. If the read queue is empty or auxiliary queue is full, go to the last step (the first 10 Step), otherwise perform the following operations;
2. Reading from the queue read_q The tail pointer to take a character, and the tail pointer forward one character position;
3. If the carriage return ( CR ) Or line ( NL ) Character, according to the terminal termios Configuration input flag ( ICRNL , INLCR ,
INOCR ) State, the character conversion accordingly. For example, if the read character is a carriage return and ICRNL Flag is set, and put it into the replacement
line character;
4. If uppercase lowercase sign turn IUCLC Is set, the characters are replaced put into corresponding lowercase characters;
5. If the specification mode flag ICANON Is set, then the character mode processing to regulate:
a. If the deleted line character (^ U ), Delete secondary A row of characters (queue head pointer is decremented, until it encounters a carriage return or
b. If an erasable character (^ H ), Delete secondary A character pointer at the head, the head pointer back one character position;
c. If the stop character (^ S ), Then set the terminal stop sign stopped = 1 ;
6. If the received signal symbol keyboard ISIG Is set to, for the process to generate a corresponding signal type control character;
7. If the line ending characters (for example, NL Or ^ D ), The secondary queue secondary The number of rows statistics data increase 1 ;
8. If the local echo flag is set, the characters are also put into the write queue write_q And calls the write function terminal noticeable on the screen
9. Put the character into the auxiliary queue secondary , The return of the above 1 Step continue processing the read cycle queue other characters;
When reading the following procedures can not help but look at first include / linux / tty.h head File. In the header file defines tty Character buffer queue
--298--
7.8 tty_io.c program
Data structures, and macros defined operation. It also defines the control characters ASCII Code value.
1/*
2 * Linux / kernel / tty_io.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
*
* Kill-line, thanks John T Kahl.
*/
13 #include <ctype.h> // character type header files. It defines some judgment about the character type and converting macros.
14 #include <errno.h> // error number header files. The system comprises various error number. (Linus imported from the minix).
15 #include <signal.h> // signal header files. Defined symbolic constant signal, the signal structure and the operation function prototype signal.
16
// The following presents a respective signal corresponding to the signal bits in the bitmap.
17 #define ALRMMASK (1 << ( SIGALRM -1)) // alert (Alarm) mask bit signal.
18 #define KILLMASK (1 << ( SIGKILL -1)) // terminated (the kill) mask bit signal.
19 #define INTMASK (1 << ( SIGINT -1)) // keyboard interrupt (int) signal mask bits.
20 #define QUITMASK (1 << ( SIGQUIT -1)) // keyboard to exit (quit) signal mask bits.
twenty one #define TSTPMASK (1 << ( SIGTSTP -1)) // stop the process (tty stop) tty emitted signal mask bit.
2223 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
twenty four #include <linux / tty.h> // tty header file, which defines tty_io, aspects of the serial communication parameters constant.
25 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
26 #include <asm / system.h> // system header files. Set or modify the defined descriptors / interrupt gate or the like embedded macro assembler.
2728 #define _L_FLAG (Tty, f) ((tty) -> termios .c_lflag & f) // get local mode flag termios structure.
29 #define _I_FLAG (Tty, f) ((tty) -> termios .c_iflag & f) // takes input mode flag termios structure.
30 #define _O_FLAG (Tty, f) ((tty) -> termios .c_oflag & f) // Take output mode flag termios structure.
31
// get a flag termios structure local mode flag set.
32 #define L_CANON (Tty) _L_FLAG ((Tty), ICANON ) // get local mode flag centralized specification (cooked) mode flag.
33 #define L_ISIG (Tty) _L_FLAG ((Tty), ISIG ) // take the signal flags.
34 #define L_ECHO (Tty) _L_FLAG ((Tty), ECHO ) // retrieve significant character flags.
35 #define L_ECHOE (Tty) _L_FLAG ((Tty), ECHOE ) // When the mode specification, explicit struck retrieved flag.
36 #define L_ECHOK (Tty) _L_FLAG ((Tty), ECHOK ) When // specification mode, take KILL erase the current line flag.
37 #define L_ECHOCTL (Tty) _L_FLAG ((Tty), ECHOCTL ) // retrieve significant control character flags.
38 #define L_ECHOKE (Tty) _L_FLAG ((Tty), ECHOKE ) When // specification mode, take KILL erase lines and echo flag.
--299--
7.8 tty_io.c program
39
// termios structure take a flag bit in the input mode flag.
40 #define I_UCLC (Tty) _I_FLAG ((Tty), IUCLC ) // get input mode flag Concentrated written lowercase conversion flag.
41 #define I_NLCR (Tty) _I_FLAG ((Tty), INLCR ) // back to take a carriage CR newline NL flag.
42 #define I_CRNL (Tty) _I_FLAG ((Tty), ICRNL ) // retrieve a carriage CR turn line feed NL flag.
43 #define I_NOCR (Tty) _I_FLAG ((Tty), IGNCR ) // Ignore take carriage CR flag.
44
// termios structure take a flag bit in the output mode flag.
45 #define O_POST (Tty) _O_FLAG ((Tty), OPOST ) // Take output centralized execution mode flag output processing flag.
46 #define O_NLCR (Tty) _O_FLAG ((Tty), ONLCR ) // get the vehicle back newline newline NL CR-NL flag.
47 #define O_CRNL (Tty) _O_FLAG ((Tty), OCRNL ) // retrieve a carriage CR turn newline NL flag.
48 #define O_NLRET (Tty) _O_FLAG ((Tty), ONLRET ) // function to take the carriage return line breaks mark NL execution.
49 #define O_LCUC (Tty) _O_FLAG ((Tty), OLCUC ) // Take lowercase uppercase characters turn sign.
50
// tty_table tty array data structure. Wherein the initialization comprises three data items, corresponding to the console, the initialization serial data terminal 1 and the
terminal 2 // port.
78 }, {
79 {0, / * no translation * / // input mode flag. 0, without conversion.
80 0, / * no translation * / // output mode flag. 0, without conversion.
81 B2400 | CS8 , // control mode flag. Baud rate is 2400bps, 8 data bits.
82 0 // local mode flag is 0.
83 0 0 // line discipline.
84 INIT_C_CC }, // control character array.
--300--
7.8 tty_io.c program
91 }
92 };
9394 / *
* Pseudo-tty terminal or other terminal types. We have not yet done so.
*/
// tty buffer queue address table. rs_io.s assembler uses, for obtaining a read address buffer queue.
(Reception) process mask signal group transmitted in all processes to the specified // specified tty structure, typically the signal is SIGINT. // Parameters: tty - tty terminal
// When pgrp = 0, it indicates that the process is the initial process init, it has no control terminal, and therefore should not be issued interrupt character.
118 if ( task [I] && task [I] -> pgrp == tty-> pgrp)
119 task [I] -> signal | = mask;
120 }
121
//// If the queue is empty buffer so that the process can be interrupted to enter the sleep state. // parameters:
queue - Specifies the queue pointer. // This function is called when the process of taking the character in the
queue buffer.
--301--
7.8 tty_io.c program
// If the current process does not signal to be processed and the specified queue buffer is empty, then let the process becomes interrupted sleep, and let the process // pointer to
128 }
129
//// If the queue buffer is full then let the process go to sleep can be interrupted. // parameters: queue
- Specifies the queue pointer. // This function is called when the process is written to the queue
buffer.
// If the process does not require the signal processing and the remaining area of the free queue buffer length <128, so that the process can be interrupted to enter the sleep state, and let //
138 }
139
//// waiting for keys.
// If the console is read queue buffer is empty so that the process can be interrupted to enter the sleep state.
// Specify the tty terminal character queue buffer copied into the specification (cooked) and stored in secondary queue character mode (mode specification queue). // Parameters: tty - tty
149 while (! EMPTY (Tty-> read_q) &&! FULL (Tty-> secondary)) {// read queue taken from the tail of a
character to c, and a tail pointer forward.
150 GETCH (Tty-> read_q, c);
// below to enter characters using the input mode flag set processing.
// If the character is a carriage return CR (13), then: if the transport line conversion flag is set, the conversion CRNL the newline character NL (10); // Ignore CR flag NOCR otherwise if
151 if (c == 13)
152 if ( I_CRNL (Tty))
153 c = 10;
154 else if ( I_NOCR (Tty))
155 continue;
156 else;
// If the character is a newline NL (10) and wraps back to a yield sign NLCR set, it is converted to a carriage CR (13).
157 else if (c == 10 && I_NLCR (Tty))
--302--
7.8 tty_io.c program
158 c = 13;
// If uppercase lowercase turn UCLC flag is set, then the characters are converted to lowercase.
executed cyclically.
character erase ERASE, and calls the write function of the tty, the function will write the output queue // write characters to the screen of the terminal. Further, since the
control characters when the write queue is placed (e.g., ^ V) with two characters, // require special control characters into a plurality ERASE.
176 }
// If the character is deleted control characters ERASE (^ H), then:
into a character erase ERASE, and calls the write function of the tty.
--303--
7.8 tty_io.c program
194 }
// If the character is the beginning character (^ Q), then reset tty stop sign, continue processing other characters.
in the queue. In tty_read () if the character line removed, its value will be decremented by 1, see line 264.
queue buffer tty region; if the character is a control character (character value <32) and echo control characters // ECHOCTL flag is set, '^', and c + 64 characters into
character tty will write queue (i.e. displayed ^ C , ^ H, etc.); otherwise, directly into the character @ tty write buffer queue. Finally, call the write function of the tty.
sub-device number; buf - User buffer pointer; nr - the number of bytes to be read. // returns the number of bytes read.
--304--
7.8 tty_io.c program
231 {
232 struct tty_struct * Tty;
233 char c, * b = buf ;
234 int minimum, time , Flag = 0;
235 long oldalarm;
236
This version // linux kernel only three sub-terminal device, respectively, the console (0), a serial terminal (1) and a serial terminal 2 (2). // so any child device number greater
than 2 is illegal. Number of bytes read, of course, can not be less than zero.
noncanonical mode, the two values is the value of the timeout timer. MIN that in order to satisfy the read operation, the minimum number of characters to be read. // TIME is a tenth of a
second timer count value. // first save of the current process (alarm) timing values (ticks).
to receive a timing signal SIGALRM //, indicates that the timing has been set to time herein, the timing signal SIGALRM reset process and interrupt // cycle.
buffer queue free space> 20, the process proceeds interruptible sleep, returns to continue deal with.
261 do {
// fetch buffer queue auxiliary character c, and you buffer queue secondary-> tail pointer is moved one character position (tail ++) to the right.
--305--
7.8 tty_io.c program
267 else {
268 put_fs_byte (C, b ++);
269 if (-! nr)
270 break;
271 }
272 } While (nr> 0 &&! EMPTY (Tty-> secondary));
// If the timeout timer value is not 0 and the time specification mode flag is not set (noncanonical mode), then:
current system time and set the flag logo, to read the next character to do Timing preparation. Otherwise, the process shows that when the scheduled time // wait timer time a character is read
is smaller, may not have to wait until the scheduled time to process the characters come to than others. Therefore, at this time // It should be scheduled for a time when the recovery process
(oldalarm).
288 }
289
//// tty write function. The user buffer of characters written in the write queue tty. // Parameters: channel - the sub-device
number; buf - buffer pointer; nr - the number of bytes written. // Returns the number of bytes written.
2 is illegal. Of course, the number of bytes written can not be less than zero.
--306--
7.8 tty_io.c program
// pointer to the tty device number corresponding to the sub-tty structure ttb_table table. The same effect as the first 238 lines of the statement.
a newline character '\ n' (NL, 10) and wraps back cart functionality ONLRET set flag, then the @ character is replaced by a carriage return '\ r' (CR, 13).
write a carriage return queue. Then continue processing the next character.
326 }
327 328 /
*
329 * Jeh, sometimes I really like the 386.
330 * This routine is called from an interrupt,
331 * And there should be absolutely no problem
332 * With sleeping even in an interrupt (I hope).
--307--
7.9 tty_ioctl.c program
*
* I do not think under normal environment will sleep in here, so good, because the task sleep is completely arbitrary.
*/
//// tty interrupt handler calls the function - perform tty interrupt processing. //
// Specify the tty terminal character queue buffer copied into the specification (cooked) and stored in secondary queue character mode (mode specification queue). // character in the
serial port interrupt (rs_io.s, 109) and keyboard interrupt (kerboard.S, 69) call.
In the non-canonical mode, these two values is the number of the timeout timer value and the minimum reading characters. MIN That in order to satisfy the read operation,
the minimum number of characters to be read. TIME It is a tenth of a second timer count value. When both are set, the read operation will wait until it reads at least one character,
and then to read MIN Characters or the time TIME Out after reading the last character. If you set only MIN Then read MIN Read will not return before the characters. If you set only TIME
, The read returns immediately after reading at least one character, or when the timer expires. If both are not set, the read will return immediately, only gives the number of bytes
This document apparatus for controlling operation of the character, to achieve a function (system call) tty_ioctl () . You can modify the function by using a specified terminal termios
--308--
7.9 tty_ioctl.c program
1/*
2 * Linux / kernel / chr_drv / tty_ioctl.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #include <errno.h>
// error number header files. The system comprises various error number. (Linus imported from the minix).
8 #include <termios.h> // function header file input and output terminal. The main terminal interface asynchronous communication define the control port.
910 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
11 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
12 #include <linux / tty.h> // tty header file, which defines tty_io, aspects of the serial communication parameters constant.
15 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
16 #include <asm / system.h> // system header files. Set or modify the defined descriptors / interrupt gate or the like embedded macro assembler.
17
// This is the baud rate factor array (or an array called the divisor). The baud rate corresponding to the baud rate factor. See also the list of instructions.
twenty three
// DLAB divisor latch flag (Line Control Register bit 7) is set the case, the write // baud rate factor to the low and high bytes, respectively, through the UART port and
0x3f8 0x3f9.
32 outb_p (0x80, port + 3); / * Set DLAB * / // First set the divisor lock flag DLAB.
33 outb_p (Quot & 0xff, port); / * LS of divisor * / // Low byte of the output factor.
34 outb_p (Quot >> 8, port + 1); / * MS of divisor * / // High byte output factors.
35 outb (0x03, port + 3); / * Reset DLAB * / // reset DLAB.
36 sti (); // open the interruption.
37 }
38
//// refresh tty buffer queue.
// Parameters: gueue - specified buffer queue pointer.
--309--
7.9 tty_ioctl.c program
// make the buffer queue head pointer is equal to the tail pointer, so as to achieve the purpose of emptying the buffer (null characters).
// Parameters: tty - tty structure pointer designated terminal; termios - termios structure buffer pointers user data area. // return 0.
// Parameters: tty - tty structure pointer designated terminal; termios - termios structure pointer user data area. // return 0.
--310--
7.9 tty_ioctl.c program
// return 0.
76 static int get_termio (Struct tty_struct * Tty, struct termio * termio )
77 {
78 int i;
79 struct termio tmp_termio;
80
// first test whether the user's buffer pointer memory area is sufficient, such as not enough memory is allocated.
*/
//// termio structure information terminal is provided.
// Parameters: tty - tty structure pointer designated terminal; termio - termio structure pointer user data area. // copy information
to the user buffer termio termios structure terminal. Return 0.
97 static int set_termio (Struct tty_struct * Tty, struct termio * termio )
98 {
99 int i;
100 struct termio tmp_termio;
101
// First copy user data area termio structure information to a temporary termio structure.
--311--
7.9 tty_ioctl.c program
indicating that the process does not control the terminal, i.e. the ioctl calls can not be issued, the error crash.
122 } Else
123 dev = MINOR (Dev);
// the sub-device number may be 0 (console terminal), 1 (serial terminal 1), 2 (second terminal port). // point to make tty tty
--312--
7.9 tty_ioctl.c program
143 if (! arg) {
144 wait_until_sent (Tty);
145 send_break (Tty);
146 }
147 return 0;
148 case TCXONC :
// start / stop control. If the parameter value is 0, the output is suspended; If 1, then reopen the suspended output; if is 2, then the Suspend
151 if (arg == 0)
152 flush (& Tty-> read_q);
153 else if (arg == 1)
154 flush (& Tty-> write_q);
155 else if (arg == 2) {
156 flush (& Tty-> read_q);
157 flush (& Tty-> write_q);
158 } Else
159 return - EINVAL ;
160 return 0;
161 case TIOCEXCL :
// set the terminal mode dedicated serial line.
--313--
7.9 tty_ioctl.c program
// analog input terminal. In the command pointer to a character as a parameter, and pretend to be the character typed on the terminal. // user must have superuser privileges or
Baud Rate = 1.8432MHz / (16 * Baud rate factor). Program relation table corresponding to the baud rate and the baud rate factor 7-10 Fig.
table 7-10 Baud rate and wave Special rate because Table of correspondences
--314--
7.9 tty_ioctl.c program
--315--
8.1 Overview
8.1 Outline
Math coprocessor emulation file handling code in kernel directory kernel / math directory, but the program has not yet truly simulation code for a math
coprocessor, contains only a shell program, see the list 8-1 Fig.
1#
2 # Makefile for the FREAX-kernel character device drivers.
3#
4 # Note! Dependencies are done automagically by 'make dep', which also
5 # Removes any old dependencies. DO NOT put your own dependencies here
6 # Unless it's something special (ie not a .c file).
7#
# Makefile file FREAX (Linux) kernel device driver characters.
# note! Dependency is performed by the 'make dep' automatically, which will automatically remove the original dependency information. Do not put your own
# Dependency information on here, unless it is (that is not a message .c file) special file.
89 AR
= Gar # GNU binary file processing program for creating, modifying and extracting files from the archive.
10 AS = Gas # GNU assembler.
11 LD = Gld # The GNU linker.
12 LDFLAGS = -s -x # connection program all the parameters, -s omitted all symbols output file information. -x Delete all local symbols.
# The frame pointers; -fcombine-regs merge register, reduce the use of register class; -finline-functions all Jane
# Single short code embedded function calls the program; -mstring-insns Linus own filling optimization options, will no longer use;
--317--
8.2 Makefile file
# - nostdinc -I ../ include not using the default path contains the file, and use the specified directory (../../include).
14 CFLAGS = -Wall -O -fstrength-reduce -fomit-frame-pointer -fcombine-regs \
15 - finline-functions -mstring-insns -nostdinc -I ../../ include
# C pre-processing options. -E C only run pre-treatment, pre-treatment and the results for all of the specified program is output to the standard output C
# Refers gcc CFLAGS using the specified options compiled C code is compiled without stops (-S), thereby generating
# C each corresponding to the input file assembler code file. Assembler default file name is generated by the original file name C
# Remove .c and .s suffix plus. -o represented followed by the name of the output file. Of which $ *. S (or $ @ ) is automatic target variable,
33 clean:
34 rm -f core * .o * .a tmp_make
35 for i in * .c; do rm -f `basename $$ i .c`.s; done
36
# Here was the objective or rules for checking dependencies between files. Methods as below:
# Sed string editing program for the Makefile (i.e. are files), and outputs for deletion Makefile
# File '### Dependencies' all rows behind, and generates a temporary file tmp_make. Then the kernel / math /
# Each file in the directory C gcc perform preprocessing operations.
# - M flag tells the preprocessor output description of the rules relating to each target file, and make compliance with these rules syntax.
# For each source file, the output of preprocessor make a rule, the result is a certain form of the corresponding source file
# File name plus its dependencies - lists all the header files included in the source file. The pretreatment results are added to the temporary
# Tmp_make file, and then copy the temporary file into a new file Makefile.
37 dep:
38 sed '/ \ # \ # \ # Dependencies / q' <Makefile> tmp_make
39 (For i in * .c; do echo -n `echo $$ i | sed '.. S, \ c, \ s,'` ""; \
40 $ (CPP) -M $$ i; done) >> tmp_make
41 cp tmp_make Makefile
4243 ### Dependencies:
--318--
8.3 math-emulation.c program
Math coprocessor emulation processing code files. The program has not yet achieved simulation code for a math coprocessor. Only realized two called when the
coprocessor exception interrupt occurs C function. math_emulate () When only contains coprocessor instructions in the user program, the coprocessor is provided an abnormality
1/*
2 * Linux / kernel / math / math_emulate.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
*/
1112 #include <signal.h>
// signal header files. Defined symbolic constant signal, the signal structure and the operation function prototype signal.
1314 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
15 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
16 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
17
//// coprocessor emulation functions.
// C interrupt handler function call, see (kernel / math / system_call.s, 169 lines).
18 void math_emulate (Long edi, long esi, long ebp, long sys_call_ret,
19 long eax, long ebx, long ecx, long edx,
20 unsigned short fs, unsigned short es, unsigned short ds,
twenty one unsigned long eip, unsigned short cs, unsigned long eflags,
twenty two unsigned short ss, unsigned long esp)
twenty three {
// selector 0x000F represents a local descriptor table descriptor index value = 1, i.e. code space. If the segment register is not equal to 0x000F @ cs cs must be said selector
kernel code, the code in the kernel space, error display in this case cs: eip value and display information // "Mathematical simulation kernel needs" then enter the crash state.
27 if (cs! = 0x000F) {
28 printk ( ' math_emulate:% 04x:% 08x \ n \ r ", cs, eip);
29 panic ( ' Math emulation needed in kernel ");
30 }
--319--
8.3 math-emulation.c program
// get user data area stack data first and second, displays the data, and to the process set floating point exception signal SIGFPE.
40 if ( last_task_used_math )
41 last_task_used_math -> signal | = 1 << ( SIGFPE -1);
42 }
43
--320--
9.1 Overview
9.1 Outline
This chapter deals linux File system implementation code kernel and device for the block buffer cache manager. In the development linux 0.11
When the kernel file system, Linus Referring mainly to the Andrew S.Tanenbaum Significant " MINIX Operating Systems Design and Implementation, "a book, which was used MINIX File
system 1.0 Version. Therefore, in this chapter, you can refer to the book about MINIX The relevant sections of the file system. The works can be found in the buffer cache MJBach of"
This chapter of the amount of notes is large, but we can divide them into four parts from the function. The first part is related to a high speed buffer management program,
mainly realizes the function of the hard disk device block data cache access. This part focused on the buffer.c Program implemented; the second part function code describes the
general low level file system. Describes the inode file management, allocates disk blocks and release as well as the file name and i Conversion algorithm node; a third part of the
--321--
9.2 Overall Functional Description
Character devices, pipes, blocks access to read and write data in the file; implementation of the interface portion of the fourth program relates the file system calls, mainly related
to the file open, close, create directory, and system files related to the call operation.
The following first introduce MINIX The basic structure of the file system, and then were to illustrate these four sections.
Currently MINIX Version is 2.0 File system used is 2.0 Edition, which with its 1.5 Different versions of the previous version of the system, its capacity has been expanded.
But because the book comments linux Kernel is MINIX File system 1.0 Version, so here it is only 1.0
MINIX File system standard UNIX Basically the same file system. It consists of 6 Parts. For a 360K Floppy disk, see the distribution of its parts 9-1 Fig.
Data Area
Map 9-1 Has MINIX A file system 360K Schematic layout of various parts of the diskette file system
Drawing, by the guide block is started when the computer is powered ROM BIOS Automatically read execution code and data. However, not all disks are used as the boot
device, it is not used for guiding the disk, the disk can be free of the code block. However, the disk must contain no guide block, in order to maintain MINIX Unified file system format.
Superblock information for file system structure on the disk storage device, and the size of each part described. Structure shown in Figure 9-2 Fig.
s_wait task_struct * wait for the process according to the present pointer superblock
--322--
9.2 Overall Functional Description
Seen from the figure, the most logical block bitmap using 8 Block buffer block ( s_zmap [8] ), And each block may represent a block buffer 8192 A disk block, therefore, MINIX
File system 1.0 The maximum supported block device capacity (length) is 64MB .
i Bitmap node for explaining i If the node is used, each bit represents a i node. for 1K In terms of disk block size, the block can be represented by a disc 8191 More
i Usage node.
Logic block bitmap for usage of each data block on the disk tray is described, a disk block data representative of each bit in the data area on the disc. Thus, one bit
represents a logical first block of bit map data on the disc area of the first data block of the disc. When a data block is occupied by the disc, the logic block bitmap corresponding
bit is set.
On the disc i The node portion of the file system to store the file (or directory) inode, each file (or directory) has a i
node. Each i Node structure stored in the corresponding related information files, such as files host id (uid) , File owning group id ( gid ), File access and modify the length of time.
The entire structure were used 32 Bytes, see FIG. 9-3 Fig.
i_zone [9] short Occupied by the file on the disk array of logical block numbers. Wherein: zone
[0] -zone [6] is a direct block number; zone [7] is a number of indirect block;
zone [8] is a second (double) indirect block number. Note: zone area is meant,
i_mode Field is used to save the file types and access to property. Which bits 15-12 To save the file type, bit 11-9 Information set when saving execute files,
bitmaps 8-0 It represents access to files. See specific information file include / sys / stat.h with
include / fcntl.h .
The data file is placed in the data area of the disk blocks, and a file name through the corresponding i Node associated with the data disk blocks, which blocks on the disk
numbers stored in i Logic block array node i_zone [] in. among them, i_zone [] Array used to store i Disk block number corresponding to the node of the file. i_zone [0] To i_zone [6] For
storing files started 7 Disk block number, known as direct block. If the document length or less 7K Bytes, according to which i Node can use it to find the disk blocks soon. If the file
is larger, the need to use a indirect block the ( i_zone [7] ), The disk block stored in the additional disk block number. for MINIX It can be stored in the file system 512 A disk block
number, thus addressing the 512 A disk block. If the file is larger, you need to use a secondary indirect disk block ( i_zone [8] ). A secondary effect of the indirect blocks similar to
block a disc tray indirect blocks, thus indirectly using a secondary disk blocks may be addressed 512 * 512 A disk block. Referring to FIG. 9-4 Fig.
--323--
9.2 Overall Functional Description
Other fields
Once indirect block
node i
i_zone [0]
i_zone [1]
i_zone [2]
i_zone [4]
i_zone [5]
i_zone [6]
Map 9-4 i The functional logic block node (block) of the array
When all i When nodes are used to find idle i Function returns the value of the node 0 ,therefore, i Bitmap node and Least Significant Bit i node 0 Both when
for PC Machine is concerned, generally one sector length ( 512 Bytes) length data block as a block device. and MINIX The file system will be continuous 2 Data sectors ( 1024
Bytes) as a data processing block, called a disk block or disk blocks. The length of the buffer in the buffer cache block length the same. A disk block number is counted from the
first plate, i.e. boot blocks are 0 Disk block number. And said logic blocks or the block, the block is a disc 2 The power of multiples. A logical block length may be equal to 1 , 2 , 4 or 8 Disks
block length. For discussed in this book linux Core, the length of the logical block equal to the disk block length. Thus the same code comments both terms meaning. The term
logical blocks of data (or block data disks) device refers to the data portion on the disc, the disc from the first data block begins disk block numbers.
UNIX Class operating system files are usually divided into 6 class. If the shell Under execution " ls -l " Command, we can know the type of file from the file status
Group Permissions
User rights
FIG., The first byte indicates the type of command to display the file list. '-' indicates that the file is a regular (general) file. Regular files ( '-') is a type of file system
is a file for not be explained, with any length of the byte stream. For example source file,
--324--
9.2 Overall Functional Description
contained in a directory, and how they are organized together to form a hierarchical file system.
Symbolic link ( ' s' ) For using a different file name to refer to another document. Across a symbolic link file system, a file is connected to another file system. To
delete a symbolic link does not affect files that are linked. Another called "hard-wired", but it is the same as the file status to be connected, are treated as a general
document, but can not cross the file system (or device) is connected, and increments the count value of the file connected with here. Description link below face
counts.
Named Pipes ( ' p ' ) File is a file created when the system creates a named pipe. It can be used for communication between unrelated processes. Character device ( ' c ' ) File
is used in file access character operated device, e.g. tty Terminal, a memory device and a network device. Block device ( ' b ' ) File is used to access the device as hard disk,
floppy disk or the like. in UNIX Based operating system, a character block device file and the device file system are generally stored in / dev Directory.
in linux Kernel, file type information stored in the corresponding i Node i_mode Field, use high 4 Bit to indicate, using a number of macro file type is
determined, e.g. S_ISBLK , S_ISDIR Etc. These macros include / sys / stat.h Defined.
In the drawing after the file type of characters per set of three characters a set of three attributes configuration file permissions. Is used to represent the host file, the same
group and other users access to the file. ' rwx ' Respectively, a file is readable, writable and executable permissions. For catalog files, executable representation can enter the
directory. When to file permissions to operate, it is generally used to represent octal them. E.g' 755 ' It indicates that the file on the host file read / write / execute the same set of
users and others can read and execute files. in linux 0.11 Source code, file permissions information is also stored in the corresponding i Node i_mode Field, the field is used low 9 The
bit indicates three sets of permissions. And often use variables mode
FIG apos connection count "indicates the number of times the file is referenced hardwired. When the count reaches zero, the file is deleted. 'Username' indicates the file
name of the host, 'Group name' is the name of the user belongs.
Buffer cache block device is accessing data in a file system go through arteries. In order to access data on a block device file system, the kernel can access every piece of
equipment, a read or write operation. But each time I / O Time and memory operations and CPU The processing speed is very slow in comparison. In order to improve the
performance of the system, the kernel has opened up a high-speed data buffer (pool) in memory ( buffer cache ), And divides it into a number equal to the disk block size of the
buffer management block and used, in order to reduce the number of accesses to the block device. in linux
The kernel, the kernel code is located between the buffer cache and the main memory area, see Fig. 2.6 Fig. The cache data blocks stored in the respective block device recently
been used in. When the need to read data from a block device, the program first looks for buffer management in the cache. If the corresponding data is already in the buffer, you will
not have to read from the block device. If the data is not in the cache, a read command is issued block device, to read data in the cache. When it is desired to write data to a block
device, the system will apply a high-speed idle buffer block buffer to temporarily store these data. As for when the data is actually written to the device, it is through the device data
synchronization to achieve.
Linux Kernel implementation of the program is a high-speed buffer buffer.c . The file system to other programs calling block read and write functions by device number and
logical block number of data to be accessed is specified. These interface functions are: block read function bread () , Advance pre-reading function block breada () And a page read
function block bread_page () . Page block read function reads a buffer memory to hold a block ( 4 Piece).
Layer processing function of the file system contained in the following 4 A file:
bitmap.c Program includes i Bitmap node and the logical block bitmap release and occupied handlers. operating i Bitmap node is a function of
free_inode () with new_inode () , A logical operation function block bitmap is free_block () with new_block () .
inode.c Program includes distribution i Node function iget () And the release of the memory i Access nodes function iput () And according to i Take node information in the
data block corresponding to the logical block number on the device function bmap () .
namei.c The main function of the program include namei () . This function uses iget () , iput () with bmap () Given its file path name is mapped to i node.
--325--
9.2 Overall Functional Description
super.c A program designed to process the file system superblock, including functions get_super () , put_super () with free_super () Wait. Also includes several file
system load / offload processing functions and system calls, such as sys_mount () Wait. These documents are hierarchical relationship between the function shown in
About file data access operation code, mainly related 5 Files: block_dev.c , file_dev.c , char_dev.c , pipe.c
with read_write.c . before 4 Documents can be considered as a block device, character device, plumbing and general interface program files and read and write system call, which
together achieve a read_write.c middle read () with write () System call. Determining by the operation of the file attributes, which are two system call calls these files correlating
block_dev.c The function block_read () with block_write () Is a special file read and write data in the block device. The parameters used to specify a device number to be
file_dev.c middle file_read () with file_write () Function is a formal document for access in general. By specifying a file corresponding i Nodes and file structure, which can
read and write pointers to know the current file number and the file is on a device.
pipe.c File read and write functions implemented in the pipeline read_pipe () with write_pipe () . It also enables the creation of system calls unnamed pipes pipe () . The main
conduit for transmitting data in a FIFO manner between processes, can also be used to perform the synchronization process. There are two types of pipes: anonymous pipes and
named pipes. Named pipes that use the file system open Call establishment, and the unnamed pipe system call is used pipe () To create. When using the pipe, then have a regular
Call the offspring, in order to share access to anonymous pipes, and as long as all processes Licenses, you can access a named pipe.
For write pipeline it can be seen as a process of writing data from the end of the pipe, while another process reads data from the other end of the pipe. Kernel access data
from the pipeline access mode generally normal manner exactly as the data file. For the distribution pipeline and storage space is different from the regular file allocation of space
is to use only the pipeline i Direct block of the node. The kernel i Direct block node as a circular queue is managed by a read-write pointer for FIFO order.
For the character device file system calls read () with write () Will call char_dev.c middle rw_char () Function to operate. Character devices include console terminal ( tty ),
In addition, the kernel file structure file And file table file_table [] To access to the file management operations. File Structure file As follows.
--326--
9.3 Makefile file
struct file {
unsigned short f_mode; // file operation mode (RW bit)
unsigned short f_flags; // File Open and sign control.
unsigned short f_count; // the corresponding file handle (file descriptor) number.
off_t f_pos; // read and write files in the current pointer location.
};
For the file handle and i Establish a relationship between the nodes. File table is an array of file structure, in linux 0.11 The kernel file table can have a maximum 64 Item,
so the whole system up to simultaneously open 64 Files. While at the same time open up to each process 20 Files.
Upper implement the relevant file system calls, basically includes map 9-8 in 5 Files.
exec.c fcntl.c
ioctl.c stat.c
open.c
open.c Files used to implement file-related operating system calls. There are file was created, opened and closed, modify modified file access permissions of the file's
owner and attributes, file modification time operating system and file system root Changes and so on.
exec.c Program to achieve binary executable files and shell Load and execute the script file. One of the major function is a function
do_execve () It is a system interrupt call ( int 0x80) Function No. __ NR_execve () Call C Handler is exec () The main function of the realization function clusters.
fcntl.c Achieve the document control system call fcntl () And two file handles (descriptor) replication system call dup () with dup2 () . dup2 ()
Specify the value of the new handle, and dup () Current minimum value of unused handle is returned. Handle copy operation is mainly used in the standard input file I / O
ioctl.c File implements the input / output control system call ioctl () . The main call tty_ioctl () Function of the terminal I / O Control.
stat.c Take file status information file for implementing the system call stat () with fstat () . stat () Natori is the use of file information, fstat () Using a file handle (descriptor) to
extract information.
makefile File System subdirectory is compiled administrative configuration file for compiling software management tools make use.
--327--
9.3 Makefile file
1 AR = Gar # GNU binary file processing program for creating, modifying and extracting files from the archive.
2 AS = Gas # GNU assembler.
3 CC = Gcc # GNU C language compiler.
4 LD = Gld # The GNU linker.
# C compiler options. -Wall display all warnings; -O optimization option, to optimize code size and execution time;
# - fstrength-reduce execution code optimization cycle, excluding iteration variable; -fomit-frame-pointer will be omitted to save unnecessary
# The frame pointers; -fcombine-regs merge register, reduce the use of register class; -mstring-insns Linus own
# Filling optimization options, will no longer use; -nostdinc -I ../ include not using the default path contains documents, the
# Here with the specified directory (../include).
5 CFLAGS = -Wall -O -fstrength-reduce -fcombine-regs -fomit-frame-pointer \
6 - mstring-insns -nostdinc -I ../ include
# C pre-processing options. -E C only run pre-treatment, pre-treatment and the results for all of the specified program is output to the standard output C
# Refers gcc CFLAGS using the specified options compiled C code is compiled without stops (-S), thereby generating
# C each corresponding to the input file assembler code file. Assembler default file name is generated by the original file name C
# Remove .c and .s suffix plus. -o represented followed by the name of the output file. Of which $ *. S (or $ @ ) is automatic target variable,
15 .so:
16 $ (AS) -o $ *. O $ <
17
# Define the target file variable OBJS.
18 OBJS = open.o read_write.o inode.o file_table.o buffer.o super.o \
19 block_dev.o char_dev.o file_dev.o stat.o exec.o pipe.o namei.o \
20 bitmap.o fcntl.o ioctl.o truncate.o
twenty one
# Use the following prerequisites have after OBJS command to connect to the target fs.o
# The following rules for the cleanup. When performing 'make clean', will execute commands on the 26-27 line, remove all compiled
# Connection file generated. 'Rm' command is to delete the file, meaning -f option is to ignore the file does not exist, and does not delete the information.
25 clean:
26 rm -f core * .o * .a tmp_make
27 for i in * .c; do rm -f `basename $$ i .c`.s; done
28
# Here was the objective or rules for checking dependencies between files. Methods as below:
# Sed string editing program for the Makefile (where that is their own) for processing, the output is deleted Makefile
# File '### Dependencies' all rows behind the row (row 35 starting from below), and generates tmp_make
# Temporary files (for 30 lines). Gcc then performs a preprocessing operation on each file in the C fs / directory.
# - M flag tells the preprocessor output description of the rules relating to each target file, and make compliance with these rules syntax.
--328--
9.3 Makefile file
# For each source file, the output of preprocessor make a rule, the result is a certain form of the corresponding source file
# File name plus its dependencies - lists all the header files included in the source file. The pretreatment results are added to the temporary
# Tmp_make file, and then copy the temporary file into a new file Makefile.
29 dep:
30 sed '/ \ # \ # \ # Dependencies / q' <Makefile> tmp_make
31 (For i in * .c; do $ (CPP) -M $$ i; done) >> tmp_make
32 cp tmp_make Makefile
3334 ### Dependencies:
--329--
9.4 buffer.c program
buffer.c Procedure for cache area (cell) to operate and manage. Located between the kernel buffer cache and main memory area block, see FIG. 9-9 In FIG. Buffer cache
plays a role of a bridge between the device and the core block other programs. In addition to the device driver blocks, if the kernel needs to access data blocks in the device, you
Map 9-9 Located throughout the physical memory location in buffer cache
FIG starting position from the last paragraph of buffer cache kernel module end Label start, end During the kernel module is linked by the linker ( ld ) A value of the kernel
code symbol is not defined. When generating the connection system Module, ld Program digest_symbols ()
This function will generate symbol. This function is mainly used for assigning reference global variables, and calculates the size of each of which are connected to the start and the file,
--330--
9.4 buffer.c program
Which also set end Value, which is equal to data_start + datasize + bss_size , That the last paragraph of kernel modules.
Entire buffer cache is divided into 1024 -Byte cache block, just the same as the logical block size on disk block device. Cache using hash Table and an idle buffer block
queue management operations. In the buffer initialization process, from both ends of the buffer, while the buffer header structure are provided and divided into blocks
corresponding buffer. High-end buffer is divided into one 1024 Byte buffer block, respectively, to establish the low end of the buffer structure corresponding to each header block
buffer buffer_head ( include / linux / fs.h , 68 Line), for buffering attribute description of a corresponding block and the connector to list all buffers. Until they can no longer be divided
between the blocks until the buffer, see 9-10 Fig. And each
buffer_head It is linked into a doubly linked list of free buffer block structure. Detailed structure shown in Figure 9-11 Fig.
Buffer block
division. Abandoned
free_list
b_data b_data b_data b_data
other fields other fields other fields other fields
b_prev b_prev b_prev b_prev
Hash table entry pointer
b_next b_next b_next b_next
b_prev_free b_prev_free b_prev_free b_prev_free
b_next_free b_next_free b_next_free b_next_free
Map 9-11 Free way circular linked list structure buffer block
Cushion Structure "Other Fields" device includes a block number, a logical block number of the buffered data, the two fields uniquely identify the data corresponding to the
block buffer block device and data blocks. There are also several status flags: valid data (updated) flag, modify flag, the number of processes to be used and the present data
When using the kernel buffer block in the buffer cache, the device number is designated ( dev) And the logical block number of data to be accessed by the device
--331--
9.4 buffer.c program
(Block) By calling bread () , bread_page () or breada () Function operates. These functions use the search buffer management function getblk () The function will be highlighted
below. When the system releases the buffering block, call brelse () function. These calls hierarchy buffer data access and management functions available map 9-12 To
describe.
(Getblk)
brelse
get_hash_table, find_buffer etc.
In order to quickly find the data block in the buffer if the request has been read into the buffer, buffer.c Program uses has
307 More buffer_head Pointer items hash Table Structure. The figure above buffer_head Pointer Structure b_prev , b_next It is used hash
Hash table bidirectional connection between a plurality of blocks on the same one buffer. Hash Hash function table used in combination with the device number and logical block
number from. DETAILED function used in the program is the device number :( ^ logical block number) Mod 307 . For dynamic hash Structural states of a time table can be found in
Hash array
Hashed Entry 2
Buffer head Buffer head
Hashed Entry 3
free_list
Wherein the double arrow lines represent the same hash hash Entry pointer buffer bidirectional link between the block header structure. Dashed line indicates the current
connection in the free block list an idle buffer pointer link between the buffer block, free_list Is the head of the free list pointer. For operation on the hash queue buffer block, can be
The above-mentioned three functions are performed when the search function is called buffer block getblk () To obtain suitable buffer block. This function first calls get_hash_table
() Function, in hash Table queue buffer block searches whether the specified device number and logical block number exists. If there immediately returns the corresponding buffer
pointer head structure; if not, start over from the free list, the free list is scanned to find a free buffer block. In the process of looking also find an idle buffer block for comparison,
the compositions according to the modification flag and imparting the lock flag
--332--
9.4 buffer.c program
As weights, which compares the most suitable free block. If the free block found neither modified nor locked, do not continue to look up. If the free block is not found, the current
process to sleep, when to be looking again to continue. If the free block is locked, the process also need to go to sleep and wait for other processes to unlock. If in the process of
waiting for sleep, the buffer block has been used by another process, then start over again as long as the search buffer block. Otherwise, determine whether the buffer block has
been modified, and if so, then the block write disk, and wait for the block to unlock. At this point if the buffer block has been occupied by another process, then do give full power
again, we had to start over again executed getblk () . After a more than toss, then there may be another unforeseen circumstances, that is, when we sleep, we may have other
processes needed to add the buffer block hash Queue, so there needs to last search hash queue. If you really hash Queue buffering block find we need, then we have to find the
block of the buffer is above determination process, and therefore, needs to start over again performed getblk () . Finally, we found a considered process is not used, is not locked,
but is clean (modified flag is not set) free buffer block. So we set the number of reference in block 1 And several other flag is reset, the block buffer was then removed from the free
list head structure. After setting the device number and logical number corresponding to the buffer block belongs, put it in hash A first correspondence table and the free end of the
queue entries. Finally, return the buffer pointer to the block header. entire getblk () See Figure process 9-14 Fig.
getblk
Yes
Block in the cache in?
no
Search idle queue
no
Find the right block?
Yes
Yes
But to somebody else?
no
Yes
The block has been modified?
Set occupying the block number of the block number of the device
--333--
9.4 buffer.c program
We can see from the above process, getblk () Buffer block may be returned to a new free block, also contain buffer block may be just what we need the data, it is already
present in the buffer area. Therefore, for reading data blocks operation ( bread ()) , Then we must update flag of the cache block is determined to see if valid data is contained, it is
effective if the data block can be directly returned to the application program. Otherwise, you need to call the low-level block device to read and write function ( ll_rw_block () ), And at
the same time let yourself go to sleep, waiting for the data to be read into the buffer block. In the wake of the then determine whether the data is valid. If so, this data can be returned
to the application program, or the device description of the read operation fails, the data is not taken. Thus, the release of the buffering block and returns NULL value. Map 9-15 Yes bread
bread
Yes
Block data is valid?
no
Yes
Block data is valid?
no
Releasing the buffer block Return header buffer pointer
Return NULL
When a program is no longer required to use a data buffer block, is called brelse () Function to release the buffer block and wakes up the process of waiting for the buffer
block and goes to sleep. Note that, the free buffer block buffer block in the linked list, are not free. Only when the disc is written refreshed, unlocked and when no other process
In summary, the buffer cache plays an important role in improving the efficiency of the block device access and increased data sharing. In addition to the driver, the kernel
of the other upper layer programs read and write operations to the block device requires a high-speed buffer achieved indirectly through the hypervisor. The main link between
them is a high-speed buffer management program bread () And the low-level function block device interface functions ll_rw_block () to realise. To access the program the upper
block through the device data is bread () Apply to the buffer management program. If the required data is already in the buffer cache, the data management program will be
returned directly to the program. If the required data is not yet in the buffer, then the manager will pass
ll_rw_block () Apply to the block device drivers, while allowing the process to sleep waiting for the corresponding program. Wait until the block device drivers specified data into the
cache area, the management program will not return to the upper layer. See Fig. 9-16 Fig.
--334--
9.4 buffer.c program
bread () ll_rw_block ()
Read and write operations
1/*
2 * Linux / fs / buffer.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
*/
1415 / *
* The best place to place the program, because it is necessary to replace the diskette buffer has failed.
*/
2021 #include <stdarg.h>
// standard parameter header. In the form of macro variables defined parameter list. Mainly it described
- a type // (the va_list) and three macros (va_start, va_arg and va_end), for // vsprintf, vprintf, vfprintf
function.
2223 #include <linux / config.h> // kernel configuration file header. Define the keyboard language and hard disk type (HD_TYPE) option.
twenty four #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
25 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
26 #include <asm / system.h> // system header files. Set or modify the defined descriptors / interrupt gate or the like embedded macro assembler.
27 #include <asm / io.h> // io header files. Defined hardware port I / O macro assembler statements.
28
--335--
9.4 buffer.c program
29 extern int end ; // ld by a linker to generate a variable indicating the end of the kernel code.
39 while (bh-> b_lock) // If you have been locked, the process goes to sleep, waiting to unlock it.
42 }
43
//// system call. Data synchronization apparatus and the cache memory.
50 bh = start_buffer ;
51 for (i = 0; i < NR_BUFFERS ; I ++, bh ++) {
52 wait_on_buffer (Bh); // Wait for buffer unlocked (if the case is locked).
53 if (bh-> b_dirt)
54 ll_rw_block ( WRITE , Bh); // generates a write block request apparatus.
55 }
56 return 0;
57 }
58
//// device specified cache data synchronization with the data on the device.
59 int sync_dev (Int dev)
60 {
61 int i;
62 struct buffer_head * Bh;
6364
bh = start_buffer ;
65 for (i = 0; i < NR_BUFFERS ; I ++, bh ++) {
66 if (bh-> b_dev! = dev)
67 continue;
68 wait_on_buffer (Bh);
69 if (bh-> b_dev == dev && bh-> b_dirt)
70 ll_rw_block ( WRITE , Bh);
71 }
72 sync_inodes (); // the data written in the cache node i.
73 bh = start_buffer ;
74 for (i = 0; i < NR_BUFFERS ; I ++, bh ++) {
75 if (bh-> b_dev! = dev)
76 continue;
--336--
9.4 buffer.c program
77 wait_on_buffer (Bh);
78 if (bh-> b_dev == dev && bh-> b_dirt)
79 ll_rw_block ( WRITE , Bh);
80 }
81 return 0;
82 }
83
//// make the specified device data in a high speed buffer is invalid.
// all scan buffer block in the cache, the buffer for a given device, resets its active (Update) flag and the flags have been modified.
100 * This routine checks whether a floppy has been changed, and
101 * Invalidates all buffer-cache-entries in that case. This
102 * Is a relatively slow routine, so we have to try to minimize using
103 * It. Thus it is called only upon a 'mount' or 'open'. This
104 * Is the best way of combining speed and utility, I think.
105 * People changing diskettes in the middle of an operation deserve
106 * To loose :-)
107 *
108 * NOTE! Although currently this is only for floppies, the idea is
109 * That any additional removable block-device will use this routine,
110 * And that mount / open need not know that floppies / whatever are
111 * Special.
112 * /
/*
* The subroutine checks whether the floppy disk has been replaced, it has been replaced in the cache so that the floppy
* All buffers corresponding invalid. This subroutine is relatively slow, so we have to try to use it less.
* So only in the implementation of 'mount' or 'open' when to call it. I think this is the combination of speed and practicality
* The best approach. If you replaced the floppy disk in the process of operation, it will lead to loss of data, which is to blame ☺ .
*
* note! Although only floppy this subroutine, block after any removable media device will use the
* Program, mount / open operation does not need to know whether any special floppy disk or other media.
*/
//// check whether to replace the disk, if it has been changed so that the corresponding high speed buffer is invalid.
--337--
9.4 buffer.c program
--338--
9.4 buffer.c program
--339--
9.4 buffer.c program
197 198 /
*
199 * Ok, this is getblk, and it is not very clear, again to hinder
200 * Race-conditions. Most of the code is seldom used, (ie repeating),
201 * So it should be much more efficient than it looks.
202 *
203 * The algoritm is changed: hopefully better, and an elusive bug removed.
204 * /
/*
* OK, Here is getblk function, the function logic is not very clear, it is also because of concerns
* Competitive conditions problem. Most of the code is rarely used, (for example, repeat the statement), so it should
*
* Algorithm has been changed: I hope to be better, but an elusive error has been removed.
*/
// The following macro definitions used to simultaneously determine the modification flag buffer and lock flag, and the right to modify the definition of vital signs larger than the lock flag.
205 #define BADNESS (Bh) (((bh) -> b_dirt << 1) + (bh) -> b_lock)
//// take the cache buffer specified.
// Check whether the specified buffer, if not, you need to create a new item in the corresponding cache in the cache. // returns the corresponding buffer head
pointer.
// search hash table, if the specified block is already in the cache, the buffer corresponding to the head pointer is returned, exit.
head. If the header indicates that the buffer tmp buffer neither modified nor locked flag is set, indicating that it has acquired the // corresponding to a block on the specified device buffer
--340--
9.4 buffer.c program
the process.
/ * And has not been used (b_count = 0), not locked (b_lock = 0), and is clean (unmodified) * / // So let us take up this buffer.
Reference count is set to 1, the reset modify flag and valid (updated) flag.
243 bh-> b_count = 1;
244 bh-> b_dirt = 0;
245 bh-> b_uptodate = 0;
// out of the head from the buffer hash linked list of free blocks and queues, so that the buffer is used to specify the specified device and thereon.
256 return;
257 wait_on_buffer ( buf );
258 if (! ( buf -> b_count--))
259 panic ( ' Trying to free free buffer ");
260 wake_up (& buffer_wait );
261 }
262 263 /
*
264 * Bread () reads a specified block and returns the buffer that contains
265 * It. It returns NULL if the block was unreadable.
266 * /
/*
* Reading the specified block of data from the device and returns the buffer contains data. If the specified block does not exist
--341--
9.4 buffer.c program
* NULL is returned.
*/
//// reads the specified device from the specified data block.
*/
//// read the content on a device page (4 buffer blocks) to the specified memory address.
296 void bread_page (Unsigned long address, int dev, int b [4])
297 {
298 struct buffer_head * Bh [4];
299 int i;
300
// loop executes four times, reading a content.
--342--
9.4 buffer.c program
311 if (bh [i] -> b_uptodate) // If the buffer data is valid, then the copy.
312 COPYBLK ((Unsigned long) bh [i] -> b_data, address);
313 brelse (Bh [i]); // release the buffer.
314 }
315 }
316 317 /
*
318 * Ok, breada can be used as bread, but additionally to mark other
319 * Blocks for reading as well. End the argument list with a negative
320 * Number.
321 * /
/*
* OK, breada as bread can be used as, but some of the blocks would be further pre-read. The function parameter list
* You need to use a negative number to indicate the end of the argument list.
*/
//// reading some of the blocks specified from the specified device.
It returns a pointer to the first buffer header // When successful, otherwise NULL.
should tmp. Until this bug in version 0.96 of the kernel code was only rectified.
--343--
9.4 buffer.c program
high-divided buffer size 1K buffer block, while the lower end in the buffer is developed to describe the structure buffer_head // buffer block, and the composition of these doubly linked
list buffer_head.
// h is a pointer to the buffer head structure, and h + 1 consecutive memory address pointing to the next buffer header address, it can be said outer terminal point h // buffer head. In
order to ensure sufficient length of the memory buffer to store a first configuration, required block of memory pointed b // address> head end cushioning = h, i.e. to> = h + 1.
360 h-> b_dirt = 0; // dirty flag, that modifications to the buffer flag.
365 h-> b_next = NULL ; // point to the same hash value having a buffer head.
366 h-> b_prev = NULL ; // point before the same hash value having a buffer head.
367 h-> b_data = (char *) b; // points to a buffer of data blocks (1024 bytes), respectively.
368 h-> b_prev_free = h-1; // point to the list in the previous item.
372 if (b == (void *) 0x100000) If the address b // decrement equal to 1MB, skip 384KB,
373 b = (void *) 0xA0000; // leaving b pointing to address 0xA0000 at (640KB).
374 }
375 h--; // let the h points to the last valid buffer head.
376 free_list = start_buffer ; // Let the free list head pointing to head a buffer header.
377 free_list -> b_prev_free = h; A former head of the list // b_prev_free point (ie, the last one).
378 h-> b_next_free = free_list ; // h under a pointer to the first, forming a chain.
// initialize the hash table (hash table, the hash table), entry in the table all pointers to NULL.
--344--
9.5 bitmap.c program
Function and role of this procedure is simple and clear, it is mainly used for i Bitmap node and the logical block bitmap up processing and release. operating i Bitmap node is
a function of free_inode () with new_inode () , A logical operation function block bitmap is free_block () with new_block () .
function free_block () For the release of the specified device dev Logical block on a data region block . Specific operation is the reset logic block designated block
Bits corresponding to the logical block bitmap. It was first to take the specified device dev Superblock, and the device according to the range of logical blocks of data given on the
super block, the logical block number determined block Effectiveness. Then look in the high-speed buffer to see whether the specified logical block is now a high-speed buffer, and
if so, then the corresponding buffer block released. Then calculate block Logic block number of data from the data area start date (from 1 Counting), and the logical block (sector)
bitmap operation, corresponding to the reset bits. Finally a buffer block bitmap corresponding to the respective logical blocks in the buffer according to a logical block number flag
function new_block () For the equipment dev Apply a logical block, the logical block number returns. And sets the specified logical block block Corresponding logical block
bitmap bits. It was first to take the specified device dev Superblock. Then the entire logic block bitmap is then searched for a first 0
The bits. If not found, then the disk device runs out of space, return 0 . Otherwise, the bit position 1 It indicates data corresponding to the logical blocks occupied. And buffer block
where the bit flag is set has been modified. Then, it calculates the logical disk block number block, and apply the corresponding buffer area in the buffer block, and the block of the
buffer is cleared. Then set the buffer block has been updated and modified flags. Finally, releasing the buffer block, for use by other programs, and return the disk block number
function free_inode () Designated for release i Node, and resets the corresponding i Bit bitmap node; new_inode () For the device
dev Establish a new i node. The new return i Pointer node. The main operation is in memory i Get a free node table i Node entries, and from i Find a node bitmap idle i node.
Processing the two functions of the above-described two similar functions, and therefore no need to repeat here.
1/*
2 * Linux / fs / bitmap.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / * Bitmap.c contains the code that handles the inode and block bitmaps * /
/ * Program containing code that handles bitmap.c node i and disk block bitmap * /
8 #include <string.h> // string header file. Mainly defines the built-in functions related to operation of the string.
11 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
12
//// specify a clear memory address (addr) at. Embedded assembler macros. // Input: eax = 0, ecx
= block size BLOCK_SIZE / 4, edi = addr.
13 #define clear_block (Addr) \
14 __asm __ ( " cld \ n \ t "\ // clear direction bit.
--345--
9.5 bitmap.c program
Nr bits of the bit at offset //// set the specified address (nr may be greater than 32!). Return to the original bit (0 or 1). // Input:% 0 - eax
(return value),% 1 - eax (0);% 2 - nr, bit offset;% 3 - (addr), the contents of addr.
19 #define set_bit (Nr, addr) ({\
20 register int res __asm __ ( " ax "); \
twenty one __asm__ __volatile __ ( " btsl% 2,% 3 \ n \ tsetb %% al ": \
twenty two "= A" ( res): "" (0), " r "( nr), " m "(* ( addr))); \
twenty three res;})
twenty four
//// reset of nr bits specified bit offset address begins. Return to the original bit inverse code (0 or 1). // Input:% 0 - eax (return value),% 1
- eax (0);% 2 - nr, bit offset;% 3 - (addr), the contents of addr.
25 #define clear_bit (Nr, addr) ({\
26 register int res __asm __ ( " ax "); \
27 __asm__ __volatile __ ( " btrl% 2,% 3 \ n \ tsetnb %% al ": \
28 "= A" ( res): "" (0), " r "( nr), " m "(* ( addr))); \
29 res;})
30
//// starting at addr to find values of a 0 bit.
// Input:% 0 - ecx (return value);% 1 - ecx (0);% 2 - esi (addr).
// start address specified in the bitmap to find the first bit is a 0, and a distance addr bit offset value is returned in addr.
31 #define find_first_zero (Addr) ({\
32 int __res; \
33 __asm __ ( " cld \ n "\ // clear direction bit.
block block bitmap bits. // parameters: dev is the device number, block is a logical block number
purpose is that if the current logical block is present in the cache, the corresponding cache block is released.
--346--
9.5 bitmap.c program
58 if (bh-> b_count! = 1) {
59 printk ( ' trying to free block (% 04x:% d), count =% d \ n ",
60 dev, block, bh-> b_count);
61 return;
62 }
63 bh-> b_dirt = 0; // reset dirty (modified) flag.
64 bh-> b_uptodate = 0; // reset update flag.
65 brelse (Bh);
66 }
// calculation data logical block number (counting from 1) Block in the data area begins counting. Then logic block (block) bitmap operation, // reset the corresponding bit.
83 j = 8192;
84 for (i = 0; i <8; i ++)
85 if (bh = sb-> s_zmap [i])
86 if ((j = find_first_zero (Bh-> b_data)) <8192)
87 break;
// If not found all scanned (i> = 8 or j> = 8192) or bitmap buffer block where invalid (bh = NULL) return 0, // exit (no free logical blocks).
the device is not present on the corresponding //. Application fails, it returns 0, quit.
92 bh-> b_dirt = 1;
93 j + = i * 8192 + sb-> s_firstdatazone-1;
94 if (j> = sb-> s_nzones)
95 return 0;
// read the new logical block data on a device (verification). If it fails then it crashes.
--347--
9.5 bitmap.c program
98 if (bh-> b_count! = 1)
99 panic ( ' ! New block: count is = 1 ");
// the new logical block is cleared, and the update flag is set and modified flags. Then release the corresponding buffer, returns a logical block number.
// Get a free entry in the i-node table memory node i, and find a node i from node i idle bitmap.
--348--
9.6 inode.c program
147 j = 8192;
148 for (i = 0; i <8; i ++)
149 if (bh = sb-> s_imap [i])
150 if ((j = find_first_zero (Bh-> b_data)) <8192)
151 break;
// If all the scanned not found, or the buffer where the invalid block bitmap (bh = NULL) return 0, exit (no free node i).
152 if (! bh || j> = 8192 || j + i * 8192> sb-> s_ninodes) {
153 iput (Inode);
154 return NULL ;
155 }
Bitmap node i // i correspond to the new set of nodes corresponding bit, if the bit is already set, then an error.
162 inode-> i_uid = current -> euid; // i node belongs to a user id.
163 inode-> i_gid = current -> egid; // set id.
164 inode-> i_dirt = 1; // modified flag.
165 inode-> i_num = j + i * 8192; // corresponding to the i-node number of the device.
166 inode-> i_mtime = inode-> i_atime = inode-> i_ctime = CURRENT_TIME ; // set the time.
167 return inode; // returns the i-node pointer.
168 }
169
The program includes processing i Function Node iget () , iput () And a block mapping function bmap () As well as some other auxiliary functions. iget () ,
iput () with bmap () Mainly used namei.c Path name to the program i Node mapping function namei () .
iget () Function is used from the device dev Reading the specified node number nr of i node. Which is below the operation flow of FIG. 9-17 Fig. The first function
--349--
9.6 inode.c program
First determine the parameters dev Effectiveness, and from i Take an idle node table i node. Then scan i Node table for the specified node number nr
of i Node, and the increment i A reference to the number of nodes. If the current scan i Device number is not equal to the specified node number or node number of the device is
not equal to the specified node number, scanning continues. Otherwise, it explained that it had to find the specified device number and node number i Node, the node will wait for
unlock (if the case is locked). Waiting for the unlocking phase node, the node table may change, at this time if the i Device number is not equal to the specified node number or
node number of the device is not equal to the specified number of nodes, the need to rescan the entire i Node table. Next, determine whether the i Whether the node is the mount
If the i Node is the mount point of a file system, the super block table installed in this search i Superblock node. If the respective superblock is not found, an error message is
displayed, and the release of free nodes begin acquiring function returns the i Node pointer. If found respective superblock, then the i Node write disk. From then installed in this i The
device unit number on the super block node of the file system, and let i Node number 1 . Then again to re-scan the entire i Node table to take the root file system is mounted. If the i Installation
point node is not other file systems, then you have found a corresponding i Node, then you can give up idle provisional application i Node, and returns to find i node.
If the i Specifies the node table not found i Node, then the front idle use application i Node i Node table created in the node. And reading the corresponding device from the i
iput () The function coincided with the completion of the function iget () Instead, it is used to release a specified i Node (written back device). The operation flow performed
--350--
9.6 inode.c program
nr)
no
inode <= end table entry?
no
The return node i the inode number = nr?
Yes
an inode points to the i-node table
Wait inode unlock (if locked)
Yes
no
the inode number = nr?
Yes
i-node table entry points to inode 1
the inode reference count by 1
no
inode is the installation section
Yes
node releases Provisional Application
Looking superblock mounted in the
whether
Find the corresponding superblock?
_bmap () Function is used to process the data block is mapped to the disk block operations. Brought parameter inode File is i Node pointer, block
It is a data block in the document, create Is to create a flag indicating the corresponding file in the case of a data block that does not exist, the need to establish a corresponding
disk blocks on the disk. The return value of this function is the data block corresponding to the logical block number on the device (disk block number). when create = 0 When the
Regular data file is placed in the data area of the disk blocks, and a file name through the corresponding i Node associated with the data disk blocks, which blocks on the
disk numbers stored in i Node logic block array. _ bmap () The main function is i Node logic block (block) array i_zone [] Processes, and in accordance with i_zone [] Logical block
number (disk block number) set in the logic block to set the occupancy of the bitmap. See "Overall Functional Description" section of Figure 9.x . As previously described, i_zone [0] to
i_zone [6] For direct logical block number corresponding to the stored document; i_zone [7] Indirect for storing a logical block number; and i_zone [8] For storing a secondary indirect
logical block number. When the file is small (less than 7K ), The disc can be used by the file block number stored in the direct i Node 7 Direct block entries; number when the file is
slightly larger (up to 7K + 512K ), You need to use a indirect block items i_zone [7] ; When larger files, you need to use the quadratic term indirect block
i_zone [8] A. Therefore, hours compare files, linux Speed disk block addressed relatively faster.
--351--
9.6 inode.c program
1/*
2 * Linux / fs / inode.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #include <string.h>
// string header file. Mainly defines the built-in functions related to operation of the string.
8 #include <sys / stat.h> // File Status header file. Containing configuration file or system state stat {} and constants.
910 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
11 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
12 #include <linux / mm.h> // memory management header files. It contains the defined page size and page number of the release function prototypes.
13 #include <asm / system.h> // system header files. Set or modify the defined descriptors / interrupt gate or the like embedded macro assembler.
// if i node is locked, the current task is set to uninterruptible wait state. The i-node until unlocked.
20 static inline void wait_on_inode (Struct m_inode * Inode)
twenty one {
--352--
9.6 inode.c program
49 for (i = 0; i < NR_INODE ; I ++, inode ++) { All nodes i // i-node table scanning array of pointers.
50 wait_on_inode (Inode); // wait for the i-node is available (unlocked).
65 for (i = 0; i < NR_INODE ; I ++, inode ++) { // array of pointers scan i-node table.
67 if (inode-> i_dirt &&! inode-> i_pipe) // if the node i has been modified and the node is not a pipe,
68 write_inode (Inode); // write the disk.
69 }
70 }
71
//// mapped to the data block processing operation of the disk block. (Block Bitmap handler, bmap - block map) // Parameters: inode - i node file; block - the data
block in the document; create - create a logo. // If you create a flag is set, then the corresponding disk blocks when you apply for a new logical block does not
exist. // returns the block corresponding to the logical block number of the data block (disk block number) on the device.
72 static int _bmap (Struct m_inode * Inode, int block, int create)
73 {
74 struct buffer_head * Bh;
75 int i;
76
// If the block number is less than 0, then the crash.
77 if (block <0)
78 panic ( "_ bmap: block <0 ");
// If the block number is larger than the number of direct indirect block number + + A second indirect block number of blocks, outside the file system indicates a range, the crash.
81 if (block <7) {
// If the flag is set to create, and i-node in a logical block to be a block (sector) field is 0, the corresponding device to apply a magnetic disk // block (logical block, block), the logical
block and the disc number (disk block number) into logical blocks field. Then set the i-node modification time,
--353--
9.6 inode.c program
// set the i-node has been modified flag. Finally returned logical block number.
// If the block number> = 7, and less than + 7 512, then the block is a indirect. Next, a process of indirect block.
89 block - = 7;
90 if (block <512) {
// If it is created, indirect block and the corresponding field of the node i is 0, indicates that the file is the first time the use of indirect blocks, // need to apply a disk block for
storing information indirect block, and this block number filled in the actual disk indirect blocks field. Then set the i-node // modified logo and modification time.
new logical block number. Then the set flag indirect block has been modified.
// this run, indicates that the data block is a second indirect blocks, and a process similar to the indirect block. The following is the treatment of secondary indirect block. // block minus the
block number indirect blocks field. Thereafter, the i-node set have been modified preparation and modification time.
--354--
9.6 inode.c program
block of the two secondary level block, and so that a second indirect block item block (block / 512) equal to the number of two block // block. Then a second set of indirect block has been
modified block flag. And releases an indirect block of the second block.
126 if (! i)
127 return 0;
// read two blocks of the second indirect block.
And let the two block item block is equal to the new logical block number (i). // set two then the block mark has been modified.
--355--
9.6 inode.c program
occupied by the page, and reset the node's reference count, the modified logo and pipeline signs and returns. // For pipe node, inode-> i_size kept the physical
--356--
9.6 inode.c program
197 static struct m_inode * Last_inode = inode_table ; // last_inode first point i-node table.
198 int i;
199
200 do {// scan
i-node table.
201 inode = NULL ;
202 for (i = NR_INODE ; I; i--) {
// If after last_inode already pointing to the last one i-node table, then allowed to re-point the beginning of the i-node table.
use. // The resulting reference count of node i is set to 2 (readers and writers), the type of pipe conduit initialization header and trailer, opposite the i-node representation.
--357--
9.6 inode.c program
239 PIPE_HEAD (* Inode) = PIPE_TAIL (* Inode) = 0; // reset the pipe head and tail pointer.
240 inode-> i_pipe = 1; // set the node as a symbol of pipeline use.
242 }
243
//// specified node number i is read from the device. // nr - i
node number.
244 struct m_inode * iget (Int dev, int nr)
245 {
246 struct m_inode * Inode, * empty;
247
248 if (! dev)
249 panic ( ' iget with dev == 0 ");
// i take an idle node i from node table.
250 empty = get_empty_inode ();
// i-node table scan. I find the specified node number. And increments the node number of citations.
and the release of the free node function start getting returns the i-node pointer.
--358--
9.6 inode.c program
279 continue;
280 }
// i have found the appropriate node, give up provisional application of the free node, the node returns i found.
281 if (empty)
282 iput (Empty);
283 return inode;
284 }
// if i do not find the specified node in the i-node table, the use of free applications in front of the establishment of the i-node node in the i-node table. // i and the node information
285 if (! empty)
286 return ( NULL );
287 inode = empty;
288 inode-> i_dev = dev;
289 inode-> i_num = nr;
290 read_inode (Inode);
291 return inode;
292 }
293
//// i read information specified node from the device into memory (buffer).
294 static void read_inode (Struct m_inode * Inode)
295 {
296 struct super_block * Sb;
297 struct buffer_head * Bh;
298 int block;
299
// first lock the i-node, the node is located superblock device.
300 lock_inode (Inode);
301 if (! (sb = get_super (Inode-> i_dev)))
302 panic ( ' trying to read inode without dev ");
// = number of the logical block (boot block superblock +) of the node i + i-node is located bitmap + the number of blocks occupied by a logic block bitmap occupied @ + (i-node number -1) /
--359--
9.7 super.c program
no ☺ .
This document describes the function of the superblock file system operations, the low-level function functions belonging to the file system, the file name and directory
manipulation functions for the upper layer use. There are get_super () , put_super () with read_super () . Moreover 2 A related file system load / unload system calls sys_umount () with sys_mount
() As well as the root file system load function mount_root () . And some other auxiliary functions buffer.c A similar role in helper functions.
Super block is stored in the main information about the entire file system structure information which refer to "general functional description" in FIG. 9.x .
get_super () Function is used under the conditions specified device, search superblock superblock corresponding memory array, and returns the corresponding pointer
superblock. Therefore, when the function is called, the corresponding file system must already be loaded ( mount ), Or at least the super block has been occupied by a super block
put_super () SuperBlock for releasing the specified device. It corresponds to the super block of the file system i Bitmap node and the logical block bitmap buffer blocks
occupied freed. Calling umount () This function will be called when unloading a file system or replace the disk.
read_super () For the file system superblock specified device read into the buffer, and registers the super block array, but also the file system i Bitmap node and the logical
block is read into memory bitmap array corresponding to the superblock structure. Finally, and returns the pointer to the superblock structure.
sys_umount () Unloading system calls for a specific device file name of the file system, sys_mount () It is used to a directory
--360--
9.7 super.c program
prompted to insert the root disk and press the Enter key The statistics logic block bitmap and displays the
display
And reading the superblock structure information
return
This function is used to install the system in addition to the root file system, they also function as initializing the kernel file system. It superblock memory array is
initialized, the file descriptor array table also file_table [] It is initialized, and the root file system and the number of free disk blocks Idle i Nodes were counted and displayed.
mount_root () Function is executed in the system initialization procedure main.c In the process 0 Created the first sub-process (process 1 ) After the call, and the system
where it is called only once. The specific location is in the initialization function calls init () of setup () Function. setup ()
1/*
2 * Linux / fs / super.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
11 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
12 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
13 #include <asm / system.h> // system header files. Set or modify the defined descriptors / interrupt gate or the like embedded macro assembler.
16 #include <sys / stat.h> // File Status header file. Containing configuration file or system state stat {} and constants. mount_root
--361--
9.7 super.c program
/ * Set_bit () command using the setb, because gas does not recognize the assembler instruction setc * / //// specified value of the test bits at bit offset (0 or
1), and returns the bit value. (It should be named test_bit () more appropriate) // embedded assembler macros. Bitnr parameters are bit offset value, addr is
the address of the start bit test operation. //% 0 - ax (__ res),% 1 - 0,% 2 - bitnr,% 3 - addr
34 while (sb-> s_lock) // If the superblock has been locked, then wait for sleep.
38 }
39
//// unlock the specified superblock. (If you use this name even more ulock_super appropriateness).
46 }
47
//// sleep waiting for superblock to unlock.
51 while (sb-> s_lock) // If the superblock is already locked, then wait for sleep.
54 }
55
//// super block to take the specified device. Returns a pointer to the superblock structure.
--362--
9.7 super.c program
60 if (! dev)
61 return NULL ;
// s pointing to the beginning of the super block array. Search the entire array of super blocks, looking for superblock specified device.
62 s = 0+ super_block ;
63 while (s < NR_SUPER + super_block )
// if the current search term is specified equipment superblock, first waiting for the superblock unlocked (if already locked by another process, then). // In the meantime, the
superblock may be used by other equipment, so this time to be determined once again whether or not the specified device superblock, superblock // if the pointer is returned.
Otherwise, re-search again for the super block array, so it s again point to the start of the superblock array //.
69 } Else
70 s ++;
71 return NULL ;
72 }
73
//// release superblock specified device.
// release super block array entry equipment used (set s_dev = 0), and releasing the device node i and the logical block bitmap cache block bitmap // occupied. If a
corresponding file system superblock is the root file system, or it has been installed on the i-node // other file systems, the superblock can not be released.
80 if (dev == ROOT_DEV ) {
81 printk ( ' root diskette changed: prepare for armageddon \ n \ r ");
82 return;
83 }
// If you can not find the superblock specified equipment is returned.
86 if (sb-> s_imount) {
87 printk ( ' Mounted disk changed - tssk, tssk \ n \ r ");
88 return;
89 }
// find the super block after the specified device, lock the first super block, and the device number field is set corresponding to the super block is 0, i.e., @ soon abandon the superblock.
90 lock_super (Sb);
91 sb-> s_dev = 0;
// then release the buffer block device node i and the logical block bitmap in the bitmap buffer occupied.
--363--
9.7 super.c program
96 free_super (Sb);
97 return;
98 }
99
//// superblock is read from the buffer to the device.
// If the superblock and device is already in the cache is valid, the process directly returns a pointer to the superblock.
106 if (! dev)
107 return NULL ;
// first check whether the apparatus can replace the disc (i.e. whether the device is a floppy disk), the disk replaced if the high speed cache block buffers of all the relevant failure //
devices are required for failure processing (release original loading the file system).
above superblock array, and unlock the entry, exit returns a null pointer.
selected above superblock array, and unlock the item, exit returns a null pointer. // For the linux kernel version, only support minix file system version 1.0, whose magic
number is 0x137f.
--364--
9.7 super.c program
141 block = 2;
142 for (i = 0; i <s-> s_imap_blocks; i ++)
143 if (s-> s_imap [i] = bread (Dev, block))
144 block ++;
145 else
146 break;
147 for (i = 0; i <s-> s_zmap_blocks; i ++)
148 if (s-> s_zmap [i] = bread (Dev, block))
149 block ++;
150 else
151 break;
// If the bitmap is read is not equal to the number of logical blocks of the logical block number of the bit of FIG should occupy described bitmap information file system in question, the
superblock // initialization failed. It can only apply for the release of all the resources front, returns a null pointer and exit.
152 if (block! = 2 + s-> s_imap_blocks + s-> s_zmap_blocks) {// release bitmap node i and
the logical block bitmap occupied buffer cache.
153 for (i = 0; i < I_MAP_SLOTS ; I ++)
154 brelse (S-> s_imap [i]);
155 for (i = 0; i < Z_MAP_SLOTS ; I ++)
156 brelse (S-> s_zmap [i]);
// release the selected item above superblock array, and unlock the super block entry, exit returns a null pointer.
0 i node is not used, so there will be the least significant bit in the bitmap is set to 1, to prevent the file system assigns numbers 0 i // node. Similarly, also the minimum
--365--
9.7 super.c program
187 for (inode = inode_table +0; inode < inode_table + NR_INODE ; Inode ++)
188 if (inode-> i_dev == dev && inode-> i_count)
189 return - EBUSY ;
// reset flag mounting node i is attached to the release of the node i.
190 sb-> s_imount-> i_mount = 0;
191 iput (Sb-> s_imount);
// set is mounted in the super block i node the field is empty, the node i and the release of the root file system device is mounted // set the root system superblock i-node pointer is
NULL.
directory name, and the i-node corresponding not occupied by other programs.
block special device file, the device number i i_zone node [0].
--366--
9.7 super.c program
212 }
// release the device file i-node dev_i.
213 iput (Dev_i);
// find the i-node dir_i corresponding to the given directory file name.
--367--
9.7 super.c program
269 free = 0;
270 i = p-> s_nzones;
// then the statistics of the number of free block bitmap according to the logical block corresponding bits of occupancy. Here SET_BIT macro function () // test bit only, and not set
bits. "I & 8191" for obtaining the offset value in the i-node number of the current block. "I >> 13" is divided by i // 8192, i.e. in addition to the number of bits contained in a disk block.
275 free = 0;
276 i = p-> s_ninodes + 1;
// then calculated according to the nodes i i idle node bitmap corresponding bits of occupancy.
--368--
9.8 namei.c program
The file is linux 0.11 The longest kernel function, but only 700 Multi-line ☺ . This document is mainly achieved in accordance directory to find the corresponding name or file
name i Function Node, and establish and delete something about the directory, the directory entry to establish and delete operations and other functions and system calls. Due to
the previous program in several major functions have more detailed comments in English, and various functions and system function calls and clear, so not repeat them here.
1/*
2 * Linux / fs / namei.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
// Some parameters related descriptors set and get embedded assembly function macro statement.
12 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
13 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
16 #include <fcntl.h> // control file header. Operable control descriptor file and constants defined symbols.
17 #include <errno.h> // error number header files. The system comprises various error number. (Linus imported from the minix).
18 #include <const.h> // constant symbol header file. Currently only defines each flag i node i_mode field.
19 #include <sys / stat.h> // File Status header file. Containing configuration file or system state stat {} and constants.
20
// Access macro mode. x is a file access flags include / fcntl.h line 7 defined at the beginning. // The x value corresponding to the index (the value
twenty one #define ACC_MODE ( x ) ( "\ 004 \ 002 \ 006 \ 377 "[( x ) & O_ACCMODE ])
2223 / *
twenty four * Comment out this line if you want names> NAME_LEN chars to be
25 * Truncated. Else they will be disallowed.
26 * /
/*
* If you want the file name length> NAME_LEN characters are truncated, the following definitions will be commented out.
*/
27 / * #Define NO_TRUNCATE * /
28
--369--
9.8 namei.c program
34 * permission ()
35 *
36 * Is used to check for read / write / execute permissions on a file.
37 * I do not know if we should look at just the euid or both euid and
38 * Uid, but that should be easily changed.
39 * /
/*
* permission ()
* This function is used to detect read a file / write / execute permissions. I do not know if just check euid, or
* You need to check both euid and uid, but it is easy to modify.
*/
//// detect file access permissions.
// Parameters: inode - i node corresponding to the file; mask - the mask access attributes. // returns: access
4344 / * Special case: not even root can read / write a deleted file * /
/ * Special case: even by the superuser (root) can not read / write a file has been removed * / // if the node i has a corresponding
57 * Ok, we can not use strncmp, as the name is not in our data space.
58 * Thus we'll have to use match. No big problem. Match also makes
59 * Some sanity tests.
60 *
61 * NOTE! Unlike strncmp, match returns 1 for success, 0 for failure.
62 * /
/*
* ok, we can not use strncmp string comparison function, because the name is not in our data space (not kernel space).
* So we can only use the match (). Not a big problem. match () also deal with some complete test.
*
* note! The difference is that with strncmp match () returns 1 if successful, 0 is returned on failure.
*/
--370--
9.8 namei.c program
// Parameters: len - the length of the string comparison; name - the name of the file pointer; de - directory entry structure. // Returns: 1 return
63 static int match (Int len, const char * name, struct dir_entry * De)
64 {
65 register int same __asm __ ( " ax ");
66
// null pointer if the directory entry, the directory entry or node i is equal to 0, or to compare the string is longer than the length of the file name, 0 is returned.
//% 0 - eax (comparison same);% 1 - eax (eax initial value 0);% 2 - esi (name pointer);% 3 - edi (name of the directory entry pointer); //% 4 - ecx ( Comparative byte
72 "Fs; repe; cmpsb \ n \ t" // user space execution cycle comparison [esi ++] and [edi ++] operation,
78 }
7980 / *
81 * find_entry ()
82 *
83 * Finds an entry in the specified directory with the wanted name. It
84 * Returns the cache buffer in which the entry was found, and the entry
85 * Itself (as a parameter - res_dir). It does NOT read the inode of the
86 * Entry - you'll have to do that yourself if you want to.
87 *
88 * This also takes care of the few special cases due to '..'- traversal
89 * Over a pseudo-root and a mount point.
90 * /
/*
* find_entry ()
* Looking for a directory entry with a name that matches the specified directory. Returns a directory entry contains a high-speed find
* Buffers and directory entry itself (as a parameter - res_dir). Read directory entry is not i-node - as
* If required need their own operations.
*
* '..' directory entries, also during operation of several special cases were treated - such as a pseudo-root to traverse
*/
//// find the directory entry specifies the directory and file name.
// Parameters: dir - i node pointer of the directory; name - the name of the file; namelen - File name length; // Return: high speed buffer
--371--
9.8 namei.c program
103 #else
104 if (namelen> NAME_LEN )
105 namelen = NAME_LEN ;
106 #endif
The number of directory entries entries entries // calculate this catalog. Back blanking directory entry structure pointer.
112 if (namelen == 2 && get_fs_byte (Name) == '.' && get_fs_byte (Name + 1) == '.') {
113 / * '..' in a pseudo-root results in a faked '.' (Just change namelen) * /
/ * Pseudo-roots '..' as a fake. '' (Just change the name length) * / // if the root node pointer of the current process that is
note! Since the flag is set mounted, so we can take out the new directory * /
119 sb = get_super ((* Dir) -> i_dev);
// If the node i is attached to the present, the first release of the original node i, then node i to be processed is mounted. Let i // * dir point which is
--372--
9.8 namei.c program
131 i = 0;
132 de = (struct dir_entry *) Bh-> b_data;
133 while (i <entries) {
// If the current directory entry data blocks have been searched, yet find the matching directory entry, then release the current directory entry data block.
entry data block. If the block is not empty, let de directory entry points to the data block, to continue the search.
148 de ++;
149 i ++;
150 }
// If all catalog items are specified directory has not been searched to find the corresponding directory entry, directory entry data block is released, returns NULL.
* In calling the function and can not be added to the directory entry information between sleep, since sleep so if other
* People (process) may have been used for the directory entry.
*/
//// add directory entry for the specified directory and file name.
// Parameters: dir - i node specified directory; name - the name of the file; namelen - File name length; // Return: high speed buffer
--373--
9.8 namei.c program
176 #else
177 if (namelen> NAME_LEN )
178 namelen = NAME_LEN ;
179 #endif
// If the file name length is equal to 0, it returns NULL, exit.
180 if (! namelen)
181 return NULL ;
// If the first direct disk block number in the directory pointed to node i is 0, NULL is returned exit.
directory entry.
186 i = 0;
187 de = (struct dir_entry *) Bh-> b_data;
188 while (1) {
// If the current directory entry discrimination beyond the current data block, the data block is released, re-apply for a disk block block. // If the application fails, it
used, we can use it. So setting (node pointer i is set to the directory entry is empty) the directory entry. When the length value, and updates the directory // (plus a length of the directory entry, the
directory i-node set have been modified flags, and then update the changes to the directory
--374--
9.8 namei.c program
entry of the file name field, sets the appropriate flag has been modified cache block from the user data area. // return the directory entry pointer and a pointer to the buffer cache and quit.
215 de ++;
216 i ++;
217 }
// unreachable here. Maybe Linus when writing code to make a copy of the above find_entry () code, and then modify the ☺ .
218 brelse (Bh);
219 return NULL ;
220 }
221 222 /
*
223 * get_dir ()
224 *
225 * Getdir traverses the pathname until it hits the topmost directory.
226 * It returns NULL on failure.
227 * /
/*
* get_dir ()
* The search function is based on the path name given until it reaches the top of the directory.
--375--
9.8 namei.c program
// If the first character a user-specified path name is '/', then the path name is absolute pathname. I from the root node starts to operate.
246 else
247 return NULL ; / * Empty name is bad * / / * Empty pathname is wrong * /
// The reference count acquired node i is incremented by one.
// length of the directory names. If the last name is a directory, but then did not add '/', i will not return to the last node directory! // example: / var / log /
httpd, node i will only return log / directory.
255 for (namelen = 0; (c = get_fs_byte (Pathname ++)) && (c = '/');! Namelen ++)
256 / * Nothing * /;
// If the character is the end symbol NULL, the show has reached the specified directory, the i-node pointer is returned to exit.
257 if (! c)
258 return inode;
// call the function lookup directory entry specified directory and file names, looking for subdirectory entries in the current process directory. If none is found, then release the i // node, and
--376--
9.8 namei.c program
* dir_namei ()
* dir_namei () function returns the name of the directory i-node pointer, and the name at the top level directory.
*/
// Parameters: pathname - directory path name; namelen - path name length. // Returns: i pointer specifies the node name of the topmost
directory.
* Their respective functions, but as such a modified mode command 'chmod', etc., this function has been sufficient.
*/
//// i nodes take the path name specified. //
--377--
9.8 namei.c program
// find the i-node to specify the filename directory entry in the return of top-level directory. Because if the last name is a directory, but then there is no // add '/', i will
not return to the last node directory! For example: / var / log / httpd, node i will only return log / directory. // So dir_namei () will not be a '/' last name as the end of a
file name to look at. It should therefore separately // this case use the search function FIND_ENTRY directory entry node i () for processing.
an error code; res_inode - i node pointer returned by the corresponding file path name of.
337 int open_namei (Const char * pathname, int flag, int mode,
338 struct m_inode ** res_inode)
339 {
340 const char * basename;
341 int inr, dev, namelen;
342 struct m_inode * Dir, * inode;
343 struct buffer_head * Bh;
344 struct dir_entry * De;
345
// If the file is read-only access permission mode flag (0), but the file was truncated 0 O_TRUNC flag is set, the flag will be changed to write only.
--378--
9.8 namei.c program
361 if (! bh) {
// create the file if it is not, then release the i-node directory, returns an error number to exit.
connected i count by 1; i node and release of the directory and i-node, return error code to exit.
379 if (! bh) {
380 inode-> i_nlinks--;
381 iput (Inode);
382 iput (Dir);
383 return - ENOSPC ;
384 }
// initial settings to the new directory entry: the i-node number is set as a number of new applications to node i; high-speed counter and flag buffer has been modified. // then release the
buffer cache, the release of the i-node directory. Returns the i-node pointer to the new directory entry and exit.
--379--
9.8 namei.c program
which it is taken out of the directory entry, and releases the cache area and i node directory.
pathname; mode - specifies the license and the type of node creation; dev - device number. // Returns: 0 for success, otherwise it returns an error code.
412 int sys_mknod (Const char * filename, int mode, int dev)
413 {
414 const char * basename;
415 int namelen;
416 struct m_inode * Dir, * inode;
417 struct buffer_head * Bh;
418 struct dir_entry * De;
419
// If it is not super-user, access permission error code is returned.
424 if (! namelen) {
--380--
9.8 namei.c program
connection reference count is reset, and release the i node. Returns an error code to exit.
returns 0 (success).
--381--
9.8 namei.c program
464 {
465 const char * basename;
466 int namelen;
467 struct m_inode * Dir, * inode;
468 struct buffer_head * Bh, * dir_block;
469 struct dir_entry * De;
470
// If it is not super-user, access permission error code is returned.
475 if (! namelen) {
476 iput (Dir);
477 return - ENOENT ;
478 }
// If you do not have permission to write in that directory, the directory i-node is released, returning an error code access permission to exit.
i-node connection count reset a new application; i releasing the new node, return error code is no space to exit.
--382--
9.8 namei.c program
// read the disk block new application. If the error is released directory corresponding to the node i; release applications disk blocks; reset node i // new application connection count; i
514 de ++;
515 de-> inode = dir-> i_num;
516 strcpy (De-> name, "..");
517 inode-> i_nlinks = 2;
// then set the high-speed buffer has been modified mark and release the buffer.
520 inode-> i_mode = I_DIRECTORY | (Mode & 0777 & ~ current-> umask );
521 inode-> i_dirt = 1;
// Add a new directory in a directory entry, if it fails (buffer cache directory entry that contains the pointer is NULL), node i is released // directory; i node the requested
connection reference count is reset, and release the i node. Returns an error code to exit.
returns 0 (success).
--383--
9.8 namei.c program
the warning message "on device dev directory wrong" return 0 (failure).
field name is not equal to "." and "..", a warning message is displayed error "on the device dev directory wrong" // and returns 0.
562 nr = 2;
563 de + = 2;
// loop detects all directory entries (len-2 th) in the directory, i-node to see if the directory entry number field is not 0 (is used).
corresponding block is not used (or already do, such as files have been deleted, etc.), then continue to read the next one, if not read, then the // error, return 0. Otherwise, let de directory
--384--
9.8 namei.c program
// Otherwise, if the query has not finished all the directory entry in the directory, continue testing.
580 de ++;
581 nr ++;
582 }
// here described is not found in the directory of the directory entry is used (of course, except for the first two), the buffer is released, a return.
599 if (! namelen) {
600 iput (Dir);
601 return - ENOENT ;
602 }
// If you do not have permission to write in that directory, the directory i-node is released, returning an error code access permission to exit.
// returns an error code file already exists, quit. Otherwise, dir is the directory that contains the name to be deleted directory i-node, de // directory entry is to be deleted directory
structure.
--385--
9.8 namei.c program
// In addition to the directory, then release the i-node that contains the directory you want to delete the directory name of the directory you want to delete and the i-node, high-speed buffer is
617 if ((dir-> i_mode & S_ISVTX ) && current -> euid &&
618 inode-> i_uid! = current -> euid) {
619 iput (Dir);
620 iput (Inode);
621 brelse (Bh);
622 return - EPERM ;
623 }
// If the device number i of the node to be deleted is not equal to the directory entry contains the device number of the directory entry of the directory or the directory is deleted // connection
reference count is greater than 1 (expressed symbolic link, etc.), can not be delete the directory, then release contains the name of the directory you want to delete a directory node // i want to
delete the directory and the i-node, high-speed buffer is released, it returns an error code.
i-node contains the directory you want to delete the directory name of the directory you want to delete and the i-node, the release of high-speed buffer // return an error code.
the directory and // i-node, high-speed buffer is released, returns an error code.
--386--
9.8 namei.c program
modify flag.
673 if (! namelen) {
674 iput (Dir);
675 return - ENOENT ;
676 }
// If you do not have permission to write in that directory, the directory i-node is released, returning an error code access permission to exit.
// returns an error code file already exists, quit. Otherwise, dir is the directory that contains the name to be deleted directory i-node, de // directory entry is to be deleted directory
structure.
--387--
9.8 namei.c program
690 }
// If the directory has restricted deletion flag and the user is not the superuser and the effective user id of the process is not equal to the deleted file // user id of the i-node, and the effective user
id of the process does not mean i node directory user id, you do not have permission to delete the file // name. Then release the i-node directory and the file name of the i-node directory entry,
the release of the buffer that contains the directory entries, returns an error number.
(success).
path name; newname - new path name. // Returns: Returns 0 if successful, otherwise it returns an error number.
--388--
9.8 namei.c program
// i take oldinode node corresponding to the original file path name. If 0, then the error, returns an error number.
741 if (! namelen) {
742 iput (Oldinode);
743 iput (Dir);
744 return - EPERM ;
745 }
// If the number of the new device pathname of the directory path name and device number is not the same as the original, you can not establish a connection, then release the i-node i
node name of the new path // directory path and original name, returns an error number.
new i-node path name of the directory path name and the original i-node , returns an error number.
--389--
9.9 file_table.c program
// modified logo, release the buffer, the release of the i-node directory.
The program currently is empty, only defines the file table array.
1/*
2 * Linux / fs / file_table.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #include <linux / fs.h>
// file system header files. Table structure definition file (file, buffer_head, m_inode, etc.).
89 struct file file_table [ NR_FILE ]; // file table array (64).
10
From here 4 Programs: block_dev.c , char_dev.c , pipe.c with file_dev.c Are for subsequent proceedings read_write.c
Services. read_write.c Program achieved a major system calls write () with read () . This 4 Programs can be seen as a system call and block devices, character devices, pipes "device"
and file system "device " The interface driver. The relationship between them can be used in FIG. 9-19 Representation. System calls write () or read () Based on the provided parameter
file descriptor attributes, it is determined what type of file, and then calls the appropriate interface program read / write function, respectively, which will then execute the
--390--
9.10 block_dev.c program
Map 9-19 Interface functions with all types of file systems and file system calls
block_dev.c Program file device belonging to the block type of program data access operations. The file includes block_read () with block_write () Two block devices read
and write functions. These two functions are for system calls read () with write () It calls, where there is no other references.
Since the block is read with each disk device tray units of blocks (in the same buffer buffer block length), so the function block_write ()
First, the parameter file pointer pos Location mapping into data blocks and block offset value, and then use the function block reads bread () Or pre-reading function block breada () The
file pointer location data block read into a buffer block buffer, and then need to write the data according to the block length chars Copy the user data in the data from the buffer to
the beginning of the current buffer offset location in the block. If there is need to write data, then the next block is read into the buffer in the buffer block, and copy the user data to
the buffer block, the write data in the second time and thereafter, the offset offset Are 0 . Referring to FIG. 9-20 Fig.
count
Map 9-20 Read and write data block schematic diagram of a hand position
User buffer is assigned by the system user program at the start of execution, or dynamically during execution of the application. Linear virtual address of the user by the
buffer, before calling this function, the system will map the virtual address to a linear memory area corresponding main memory page.
function block_read () Mode of operation and block_write () The same, just copy the data from the buffer to the place specified by the user.
--391--
9.10 block_dev.c program
1/*
2 * Linux / fs / block_dev.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #include <errno.h>
// error number header files. The system comprises various error number. (Linus imported from the minix).
89 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
10 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
11 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
12 #include <asm / system.h> // system header files. Set or modify the defined descriptors / interrupt gate or the like embedded macro assembler.
13
//// block write function - byte data specified length is written from a given offset to the specified device. // parameters: dev - device number; pos - the
device file offset pointer; buf - the user address space buffer address; //
// For the kernel, a write operation is to write data to a high-speed buffer, when data is written to the device is ultimately determined by the cache management program // and processed.
Further, because the device is read in units of blocks, so that writing starting position for the data block is not in the start // at the start of the block requires the entire first byte read is located,
and the need to write from the write fill that the beginning of the block, then the entire block of data // complete write disk (i.e., referred to cache a program processing).
14 int block_write (Int dev, long * pos , Char * buf , Int count )
15 {
// pos converted from block start address to a block number of the block read. And determine the need to read the first byte offset position offset in the block.
// count for the number of bytes to be written, do the following cycle until all write.
twenty three while ( count > 0) {
The number of bytes in the block can be written // calculated. If the number of bytes to be written less than a fill, you can simply write count bytes.
incremented by one.
27 if (chars == BLOCK_SIZE )
28 bh = getblk (Dev, block);
29 else
30 bh = breada (Dev, block, block + 1, block + 2, -1);
31 block ++;
// If buffer block operation fails, it returns the number of bytes have been written, if not write any byte error number (negative number) is returned.
32 if (! bh)
33 return written written:? - EIO ;
// p points to read data block start writing position. If the last written data is less than one, the block starts from the need to fill in (modified) // bytes required, so there
--392--
9.10 block_dev.c program
36 * pos + = Chars;
37 written + = chars;
38 count - = chars;
// Copy chars bytes from the buffer to the user buffer area pointed to by p start writing.
39 while (chars -> 0)
40 * (P ++) = get_fs_byte ( buf ++);
// set the flag buffer block has been modified, and releases the buffer (i.e. the buffer reference count is decremented by 1).
41 bh-> b_dirt = 1;
42 brelse (Bh);
43 }
44 return written; // returns the number of bytes that have been written, the normal exit.
45 }
46
//// data block read function - device read from the specified location and the specified number of bytes into the cache.
47 int block_read (Int dev, unsigned long * pos , Char * buf , Int count )
48 {
// pos converted from block start address to a block number of the block read. And determine the need to read the first byte offset position offset in the block.
65 * pos + = Chars;
66 read + = Chars;
67 count - = chars;
// start position is copied from buffer area pointed to by p chars bytes of data to the user buffer, and releases the buffer cache.
73 }
--393--
9.11 file_dev.c program
74
The file includes file_read () with file_write () Two functions. Also calls for the system to function read () with write () It calls, where there is no other references. And on a file block_dev.c
Similarly, the file is used to access the file data. But the function of this program is carried out by specifying the file pathname manner. Function parameters is given in the
document i Node and file structure information, by i Node information corresponding to the acquired device numbers from file Structure, we can get read and write files in the
current cursor position. And the function on a file is directly read and write the parameters specified in the device number and location of the file, a block device is designed for file
operations, e.g.
1/*
2 * Linux / fs / file_dev.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #include <errno.h>
// error number header files. The system comprises various error number. (Linus from the introduction of minix)
8 #include <fcntl.h> // control file header. Operable control descriptor file and constants defined symbols.
910 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
11 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
12 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
15 #define MAX (A, b) (((a)> (b))? (A) :( b)) // get a, b is the maximum value.
16
//// file read function - The i-node and file structure, the data reading device.
// node may know that the device number i, a filp file structure may know the current position of the read and write pointers. buf // specified position in the user-mode buffer, count the
number of bytes to be read. The return value is the number of bytes, or an error number (less than 0) actually read.
17 int file_read (Struct m_inode * Inode, struct file * Filp, char * buf , Int count )
18 {
19 int left, chars, nr;
20 struct buffer_head * Bh;
twenty one
from the specified device to read the logical block, the read operation fails if the loop is exited. If nr is 0, indicating specified
--394--
9.11 file_dev.c program
// data block does not exist, block buffer pointer is set to NULL.
// read, wherein the smaller value is the number of bytes required to read chars. If (BLOCK_SIZE-nr) // This large then the data block is the last one to be read, otherwise needed
current position of the read and write pointers. buf // specified position in the user-mode buffer, count the number of bytes to be written. The return value is the number of bytes, or an
48 int file_write (Struct m_inode * Inode, struct file * Filp, char * buf , Int count )
49 {
50 off_t pos ;
51 int block, c;
52 struct buffer_head * Bh;
53 char * p;
54 int i = 0;
5556 / *
57 * Ok, append may not work when many processes are writing at the same time
58 * But so what. That way leads to madness anyway.
59 * /
/*
* ok, when many processes simultaneously write, append operation may not work, but so what. Either way will do so
* Resulting in a mass of confusion.
*/
// If you are adding data, the file is read and write pointers To move a file after the tail. Otherwise it will be written in the file read and write pointer.
--395--
9.11 file_dev.c program
62 else
63 pos = Filp-> f_pos;
Ruoyi i // number of bytes written to be written is smaller than the number of bytes for the count, the following cycle.
69 c = pos % BLOCK_SIZE ;
70 p = c + bh-> b_data;
71 bh-> b_dirt = 1;
// read from the start position to the end of the block co-writable c = (BLOCK_SIZE-c) bytes. If c is larger than the number of bytes // (count-i) needs to write the
72 c = BLOCK_SIZE -c;
73 if (c> count -i) c = count -i;
// number of bytes in the file read and write pointer advances to be written. If the current file pointer position value read exceeds the size of the file, then the node i // modify the
file size field and i-node set have been modified flag.
74 pos + = C;
75 if ( pos > Inode-> i_size) {
76 inode-> i_size = pos ;
77 inode-> i_dirt = 1;
78 }
// number of bytes written byte count c accumulated in the writing. C copy bytes to a location in the buffer cache p // points to the start of the user from the buffer
79 i + = c;
80 while (c -> 0)
81 * (P ++) = get_fs_byte ( buf ++);
82 brelse (Bh);
83 }
// Change the file modification time to the current time.
--396--
9.12 pipe.c program
Pipeline operation is the most basic way of inter-process communication. This program includes a function of reading and writing files conduit read_pipe () with write_pipe () ,
While achieving a piping system calls sys_pipe () . These two functions are also system calls read () with write () The realization of low-level function, it is only in
read_write.c Use.
At initialization pipes, pipe i Node i_size Field is set to point to the pipeline buffer pointer, the head pointer stored in the data pipeline i_zone [0] Field, and the tail pointer
stored in the data pipeline i_zone [1] Field. For read operations the pipeline, the data is read out from the tail pipe, and the pipe advances the tail pointer bytes are read a plurality
of positions; for the write operation to the pipeline, the data is written to the head pipe, the head pipe and write byte pointer forward several positions. See illustration below conduit 9-21
Fig.
read_pipe () For data read pipeline. If there is no data in the pipeline, the pipeline will wake up the process of writing, while he goes to sleep. If the read data, the head
pointer correspondingly adjusting pipe, and transmit the data to the user buffer. When all the data in the pipe are removed, they must wake up waiting for a write pipeline process,
and returns the number of data bytes read. When the writing process has exited the pipeline pipeline operations, functions immediately withdraw and return the number of bytes
read.
write_pipe () The read operation of the function and the function is similar to the pipe. System calls sys_pipe () For creating unnamed pipe. It first acquires the file system
table two entries, then also find two descriptor table entry in the file descriptor table is not used in the current process, to save the corresponding file structure pointer. Then
apply a system idle i Node, while obtaining a pipe used buffer block. Then the corresponding file structure is initialized, the file structure is set to a read-only mode, the other
set to a write-only mode. Finally, the two file descriptors to the user.
1/*
2 * Linux / fs / pipe.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #include <signal.h>
// signal header files. Defined symbolic constant signal, the signal structure and the operation function prototype signal.
--397--
9.12 pipe.c program
89 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
11 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
12
//// conduit read function.
// parameters are inode corresponding to the i-node conduit, buf is the buffer pointer data, count the number of bytes read.
current size of data contained in the pipe, so that it is equal to the size.
29 count - = chars;
30 read + = Chars;
// size so point to the tail pipe, the pipe to adjust the current tail pointer (forward chars bytes).
// parameters are inode corresponding to the i-node conduit, buf is the buffer pointer data, count is the number of bytes written to the pipe.
--398--
9.12 pipe.c program
number of bytes that have been written and drop out. When the address byte 0, -1 is returned. // otherwise sleep on the i-node, waiting for the pipeline to make room.
than the current free space in the length size, so that it is equal to the size.
59 count - = chars;
60 written + = chars;
// size so point data of the head pipe, the head pipe data pointer adjustment current (forward chars bytes).
78 j = 0;
79 for (i = 0; j <2 && i < NR_FILE ; I ++)
80 if (! file_table [I] .f_count)
81 (F [j ++] = i + file_table ) -> f_count ++;
// If there is only one free item, then release the (reference count is reset).
82 if (j == 1)
--399--
9.13 char_dev.c program
86 j = 0;
87 for (i = 0; j <2 && i < NR_OPEN ; I ++)
88 if (! current -> filp [i]) {
89 current -> filp [fd [j] = i] = f [j];
90 j ++;
91 }
// If there is only one free file handle, the handle is released.
92 if (j == 1)
93 current -> filp [fd [0]] = NULL ;
// If the handle is not find two free, releasing two file structures above item acquired (reference count is reset), and returns -1.
94 if (j <2) {
95 f [0] -> f_count = f [1] -> f_count = 0;
96 return -1;
97 }
// Application conduit node i, and allocates a buffer (a memory) for the pipeline. If unsuccessful, the file handle corresponding release two piece structure and file // item, and returns
-1.
char_dev.c File includes character device file access functions. There are rw_ttyx () , rw_tty () , rw_memory () with rw_char () . There is also a read-write device function pointer
rw_ttyx () Serial read and write functions is a terminal device, which is a major number 4 . By calling tty The driver implements the serial read and write operations of the
terminal.
--400--
9.13 char_dev.c program
rw_tty () Console terminal is read and write functions, major number 5 . The principle and rw_ttyx () The same, but the process can console for operating restrictions.
rw_memory () File is a memory device read and write functions, major number 1 . Achieved byte operations for image memory. but linux 0.11
Version of the kernel minor number 0 , 1 , 2 The operation has not been achieved. until 0.96 Version began to implement minor number 1 with 2 Read and write operations.
rw_char () It is a character read-write device interface function operation. Other characters device operating device characters corresponding character reader apparatus by
the function pointer table function. Operating functions of the file system open () , read () So it was operated by all its character device file.
1/*
2 * Linux / fs / char_dev.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #include <errno.h>
// error number header files. The system comprises various error number. (Linus imported from the minix).
8 #include <sys / types.h> // type of header files. System defines the basic data types.
910 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
11 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
1213 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
14 #include <asm / io.h> // io header files. Defined hardware port I / O macro assembler statements.
1516 extern int tty_read (Unsigned minor, char * buf , Int count );
// read terminal.
17 extern int tty_write (Unsigned minor, char * buf , Int count ); // write terminal.
18
// Define the function pointer type character reader apparatus.
19 typedef (* crw_ptr ) (Int rw, unsigned minor, char * buf , Int count , off_t * pos );
20
//// serial terminal to read and write functions.
// Parameters: rw - read and write commands; minor - the terminal sub-device number; buf - buffer; cout - the number of bytes read; //
pos - the current pointer read and write operations, for operating the terminal, the pointer is useless. //
twenty one static int rw_ttyx (Int rw, unsigned minor, char * buf , Int count , off_t * pos )
twenty two {
// Ibid rw_ttyx (), only increased detect whether there is control terminal of the process.
27 static int rw_tty (Int rw, unsigned minor, char * buf , Int count , off_t * pos )
28 {
// If the process does not correspond to the control terminal, an error number is returned.
--401--
9.13 char_dev.c program
34 static int rw_ram (Int rw, char * buf , Int count , off_t * pos )
35 {
36 return - EIO ;
37 }
38
//// memory data read and write functions. Unrealized.
39 static int rw_mem (Int rw, char * buf , Int count , off_t * pos )
40 {
41 return - EIO ;
42 }
43
//// kernel data area read and write functions. Unrealized.
44 static int rw_kmem (Int rw, char * buf , Int count , off_t * pos )
45 {
46 return - EIO ;
47 }
48
// function port read and write operations.
// Parameters: rw - read and write commands; buf - buffer; cout - the number of bytes read; pos - port address. // Returns: the number of bytes
actually read.
49 static int rw_port (Int rw, char * buf , Int count , off_t * pos )
50 {
51 int i = * pos ;
52
// number of bytes read for the request address and the port is less than 64K, the loop is executed a single byte write operations.
56 else
57 outb ( get_fs_byte ( buf ++), i);
// forward a port. [??]
58 i ++;
59 }
// calculate the number of bytes read / write, and read and write pointers corresponding adjustment.
60 i - = * pos ;
61 * pos + = I;
// returns the number of bytes read / written.
62 return i;
63 }
64
//// memory read and write functions.
65 static int rw_memory (Int rw, unsigned minor, char * buf , Int count , off_t * pos )
66 {
// The sub-device number of memory devices, each memory read and write calls different functions.
67 switch (minor) {
68 case 0:
69 return rw_ram (Rw, buf , count , pos );
--402--
9.14 read_write.c program
70 case 1:
71 return rw_mem (Rw, buf , count , pos );
72 case 2:
73 return rw_kmem (Rw, buf , count , pos );
74 case 3:
75 return (rw == READ ?) 0: count ; / * Rw_null * /
76 case 4:
77 return rw_port (Rw, buf , count , pos );
78 default:
79 return - EIO ;
80 }
81 }
82
// define several types of equipment systems.
94
//// character device read and write functions.
// Parameters: rw - read and write commands; dev - device number; buf - buffer; count - the number of bytes read; pos - read and write pointers. // Return: The actual read /
write bytes.
95 int rw_char (Int rw, int dev, char * buf , Int count , off_t * pos )
96 {
97 crw_ptr call_addr;
98
// If the device number exceeds the number of system device, an error code is returned.
This file implements the file operating system call read () , write () with lseek () . read () with write () According to the different file types,
--403--
9.14 read_write.c program
Respectively call the front 4 Corresponding file read and write functions implemented. Therefore, this document is in front of 4 Files in function of the upper interface. lseek ()
read () System call first to determine the effectiveness of the parameters, then according to the file i Determining the type of node information file. If the caller pipe file pipe.c
The read function; if the character device file, the call char_dev.c middle rw_char () Character read function; if the file is a block device, is executed block_dev.c Program block
reading the device, and returns the number of bytes read; if it is a directory file or a regular file in general, is called file_dev.c The document read function file_read () . write () Implementation
lseek () The system will call configuration file handle corresponding to the file in the current read and write pointers to be modified. For the read and write pointers can not
move files and file duct, it will give an error number, and return immediately.
1/*
2 * Linux / fs / read_write.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #include <sys / stat.h>
// File Status header file. Containing configuration file or system state stat {} and constants.
8 #include <errno.h> // error number header files. The system comprises various error number. (Linus imported from the minix).
9 #include <sys / types.h> // type of header files. System defines the basic data types.
1011 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
12 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
13 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
14
// character device read and write functions.
15 extern int rw_char (Int rw, int dev, char * buf , Int count , off_t * pos ); // read pipeline operation function.
16 extern int read_pipe (Struct m_inode * Inode, char * buf , Int count ); // write pipeline operation function.
17 extern int write_pipe (Struct m_inode * Inode, char * buf , Int count ); // read function block device.
18 extern int block_read (Int dev, off_t * pos , Char * buf , Int count ); // write function block device.
19 extern int block_write (Int dev, off_t * pos , Char * buf , Int count ); // read file manipulation functions.
twenty two extern int file_write (Struct m_inode * Inode, struct file * Filp,
twenty three char * buf , Int count );
twenty four
//// relocatable file read and write system calls the function pointer.
// Parameter fd is the file handle, offset is the new offset value file read and write pointers, Origin offset is the starting position, is SEEK_SET // (0, from the beginning of the file), SEEK_CUR
(1, from the current read and write position), SEEK_END (, from the end of the file), one of the three 2.
--404--
9.14 read_write.c program
// open file handle if the program value is greater than a maximum number of files NR_OPEN (20), or a pointer to the file structure of the handle is null, or the node I // file structure
corresponding to the field is empty, a specified device or file pointer is not positioned, error code is returned and exit.
30 if (fd> = NR_OPEN ||! ( file = current -> filp [fd]) || (! file -> f_inode)
31 ||! IS_SEEKABLE ( MAJOR ( file -> f_inode-> i_dev)))
32 return - EBADF ;
// If the file corresponding to the i-node is a pipe node, an error code is returned, exit. Head and tail pointers are not free to move pipe!
36 case 0:
37 if (offset <0) return - EINVAL ;
38 file -> f_pos = offset;
39 break;
// origin = SEEK_CUR, requires a file as read and write pointers at the current read and write pointers relocated origin. If the offset is added to the current pointer value is less than 0 // file,
an error code is returned to exit. Or adding the offset value to the current read and write pointers.
40 case 1:
41 if ( file -> f_pos + offset <0) return - EINVAL ;
42 file -> f_pos + = offset;
43 break;
// origin = SEEK_END, requirements as to the origin end of the file relocation read and write pointers. At this time, if the file size plus the offset value is less than zero, an error code is returned
// exit. Otherwise relocation write pointer value plus an offset file length.
44 case 2:
45 if ((tmp = file -> f_inode-> i_size + offset) <0)
46 return - EINVAL ;
47 file -> f_pos = tmp;
48 break;
// origin setting error, return an error code to exit.
49 default:
50 return - EINVAL ;
51 }
52 return file -> f_pos; // returns after relocation file read and write pointer value.
53 }
54
//// read the file system calls.
// parameter is the file handle fd, buf is the buffer, count is the number of bytes to be read.
60 if (fd> = NR_OPEN || count <0 ||! ( file = current -> filp [fd]))
61 return - EINVAL ;
For count // number of bytes read is equal to 0, 0 is returned, exit
62 if (! count )
63 return 0;
// Verify storage buffer memory limitations of the data.
--405--
9.14 read_write.c program
than the current file size, the read reset length number of bytes of the file - the current write pointer value, reads // if equal to 0, 0 is returned to exit), then performs a file read operation
84 {
85 struct file * file ;
86 struct m_inode * Inode;
87
// If the program to open the file handle is greater than a maximum number of files NR_OPEN, or the need to write a file structure pointer byte count is less than 0, // or the handle is
88 if (fd> = NR_OPEN || count <0 ||! ( file = current -> filp [fd]))
89 return - EINVAL ;
For count // number of bytes read is equal to 0, 0 is returned, exit
90 if (! count )
91 return 0;
// i take the corresponding file node. If the pipeline file, and the file is written pipeline mode, the write pipeline operation, if successful // number of bytes written is returned, otherwise it
101 printk ( "( Write) inode-> i_mode =% 06o \ n \ r ", inode-> i_mode);
--406--
9.15 truncate.c program
This procedure for releasing the specified i All nodes on the logical blocks occupied by the device, including direct blocks, indirect blocks, and a secondary indirect blocks.
Whereby a file node corresponding to the file length of cut 0 And the release of the device footprint. i Node block and schematic diagram of Figure direct indirect blocks 9-22 Fig.
node
[5] i zone
Other fields[6] i Once indirect block
zone [4] i zone
[2] i zone [3] i
zone [1] i zone
i zone [0] i
1/*
2 * Linux / fs / truncate.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
10
//// released once indirect block.
--407--
9.15 truncate.c program
17 if (! block)
18 return;
// read once indirect block, and that the use of the release on all logic blocks, and then releasing the first buffer indirect block.
twenty two if (* p)
twenty three free_block (Dev, * p); // release a specified logical block.
twenty four brelse (Bh); // release the buffer.
25 }
// indirect block on a release device.
26 free_block (Dev, block);
27 }
28
//// release second indirect block.
35 if (! block)
36 return;
// read an indirect block of the second block, and that the use of releasing all logical blocks thereon, then release the buffer of the one block.
40 if (* p)
41 free_ind (Dev, * p); // indirect block the release of all time.
- 408 -
9.16 open.c program
59 free_dind (Inode-> i_dev, inode-> i_zone [8]); // release second indirect block.
60 inode-> i_zone [7] = inode-> i_zone [8] = 0; // 7,8 logical block entry zero.
61 inode-> i_size = 0; // File size zero.
62 inode-> i_dirt = 1; // set the node has been modified flag.
63 inode-> i_mtime = inode-> i_ctime = CURRENT_TIME ; // reset node and file modification time to the current time.
64 }
6566
This document implements a number of documents related to the operation of the system call. There are file was created, opened and closed, modify modified file access
permissions of the file's owner and attributes, file modification time operating system and file system root Changes and so on.
1/*
2 * Linux / fs / open.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #include <string.h>
// string header file. Mainly defines the built-in functions related to operation of the string.
8 #include <errno.h> // error number header files. The system comprises various error number. (Linus imported from the minix).
9 #include <fcntl.h> // control file header. Operable control descriptor file and constants defined symbols.
10 #include <sys / types.h> // type of header files. System defines the basic data types.
11 #include <utime.h> // user time header. It defines the access and modification time structure and utime () prototype.
12 #include <sys / stat.h> // File Status header file. Containing configuration file or system state stat {} and constants.
1314 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
15 #include <linux / tty.h> // tty header file, which defines tty_io, aspects of the serial communication parameters constant.
16 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
17 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
18
// get file system information system calls.
19 int sys_ustat (Int dev, struct ustat * Ubuf)
20 {
twenty one return - ENOSYS ;
twenty two }
--409--
9.16 open.c program
twenty three
// filename parameter is the file name, times are access and modification time structure pointer.
// If times pointer is not NULL, the access time to information provided utimbuf structure file access and modification times. // times if the pointer is NULL, then take the time
to set the current system access and modification times domain specified file.
31 if ( times ) {
32 actime = get_fs_long ((Unsigned long *) & times -> actime);
33 modtime = get_fs_long ((Unsigned long *) & times -> modtime);
// Otherwise, set the access and modification times to the current time.
34 } Else
35 actime = modtime = CURRENT_TIME ;
I // Modify node access time field and the modification time field.
38 inode-> i_dirt = 1;
39 iput (Inode);
40 return 0;
41 }
4243 / *
44 * XXX should we use the real or effective uid? BSD uses the real uid,
45 * So as to make this call useful to setuid programs.
46 * /
/*
* File Properties XXX, we use the real user id or the effective user id? BSD systems use a real user id,
* So the call can be used for setuid programs. (Note: POSIX standards recommend the use of real user ID)
*/
//// check access to the file.
// filename is the name of the parameter, mode is a mask, a R_OK (4), W_OK (2), X_OK (1) and F_OK (0) components. // If the request is allowed access,
--410--
9.16 open.c program
// If the current process is the host of the file, then take the file host of the property.
* Real user id (temporarily), then call suser () function. If we really want to call
* suser () function, you need to finally being called.
*/
// If the current user id 0 (root) and execute mask bit is a 0 or a file can be accessed by anyone, 0 is returned.
69 if ((! current -> uid) &&
70 (! (Mode & 1) || (i_mode & 0111)))
71 return 0;
// otherwise it returns an error code.
72 return - EACCES ;
73 }
74
//// change the current working directory system calls. // filename parameter is
an error code.
'/'. // returns 0 if the operation was successful, otherwise it returns an error code.
--411--
9.16 open.c program
91 {
92 struct m_inode * Inode;
93
// If the file name corresponding to the i-node does not exist, an error code is returned.
// filename parameter is the file name, mode is the new file attributes. // returns 0 if the operation is
error code.
115 inode-> i_mode = (mode & 07777) | (inode-> i_mode & ~ 07777);
116 inode-> i_dirt = 1;
117 iput (Inode);
118 return 0;
119 }
120
//// modify the host file system calls.
// filename parameter is the file name, uid is the user identifier (user id), gid is the group id. // returns 0 if the operation is
121 int sys_chown (Const char * filename, int uid, int gid)
122 {
123 struct m_inode * Inode;
124
// If the file name corresponding to the i-node does not exist, an error code is returned.
--412--
9.16 open.c program
O_CREAT, O_EXCL, O_APPEND and some other flags, if this function creates a new file, the mode // attribute specifies the license for the use of the file, these attributes
have S_IRWXU (host file has read, write, and execute permissions), S_IRUSR // (user has read file permissions), S_IRWXG (group members have read, write, and
execute rights) and so on. For newly created files, // these attributes apply only to future access to the file, create a read-only file open call will also return a read-write file
handle. // If the operation is successful file handle (file descriptor) is returned, otherwise it returns an error code. (See sys / stat.h, fcntl.h)
138 int sys_open (Const char * filename, int flag, int mode)
139 {
140 struct m_inode * Inode;
141 struct file * F;
142 int i, fd;
143
// Set the mode mode set by the user with the process of phase mask, resulting in file mode permission.
code is returned.
151 f = 0 + file_table ;
152 for (i = 0; i < NR_FILE ; I ++, f ++)
153 (! F-> f_count) if break;
154 if (i> = NR_FILE )
155 return - EINVAL ;
// make the corresponding file handle to process file structure pointer to search the file structure, and to make the handle reference count is incremented by one.
// If the file is a character device, so if the device number is 4, then the number of the current process to set tty for the child device number i node. // set the current parent process and process
group ID tty tty corresponding entries equal to the process of the parent process group number.
--413--
9.16 open.c program
code.
file handle.
--414--
9.17 exec.c program
This source and binary executable files to achieve shell Load and execute the script file. One of the major function is a function
do_execve () It is a system interrupt call ( int 0x80) Function No. __ NR_execve () Call C Handler is exec () The main function of the realization function clusters. Its main functions
are:
• Perform initialization parameters and environmental parameters space of the page - Set initial spatial start pointer; page pointer array is initialized space ( NULl) ;
According to the execution of the execution object file Natori i Node; calculating the number of number of parameters and environment variables; check the file types,
execute permission;
• The header data structure execution start of the file, wherein the information to be processed - According to the executable file i Node reads the file header information;
if Shell Script (the first line to #! Start), the analysis Shell Program name and its parameters, and execute the file as an argument to the execution of the execution Shell
Program; execution is executable in accordance with the magic number and segment length information to determine the file;
• Calls on the current process carried out before running the new initialization file - Point to the new executable file i Node; the reset signal handler; head configuration
information is provided in accordance with local descriptor segment base address and length; and environmental parameters set page pointer; modification process
• Uehara call stack replacement execve () The return address for the new executive to run the program address, run the newly loaded program.
execve () Function may have a large number of common parameters and operations, and environmental parameters of the space environment space MAX_ARG_PAGES Pages,
with a total length of up to 128kB byte. Store data in a manner similar to the space stack operation, i.e., from the assumed 128kB Reverse stored starting at the end of the space or
environment variable parameter string. In the initial, program defines a pointer to the end space ( 128kB-4 Byte) at the inner space of the offset value p , With the increase of the
offset value data is stored and retracted, FIG. 9-23 As can be seen, p Clearly pointed out how much free space in the current environment space still remaining parameters. In the
--415--
9.17 exec.c program
012
Unallocated page Assigned page
Current offset value p The initial offset value p
.
.
create_tables () Function for a given value in accordance with the current stack pointer p Numerical variables and parameters argc And the number of environment variables
envc Creating the environment variable pointer table and parameter in the new program stack, and the return stack pointer value at this time sp . After the stack pointer is created in
Big envc + 1
NULL
changes in address
argc + 1
envp
argv
Small argc
sp (return value)
Map 9-24 The new program stack pointer indicates the intention
1/*
2 * Linux / fs / exec.c
3*
4 * (C) 1991 Linus Torvalds
5*/
6
--416--
9.17 exec.c program
7/*
8 * # -! Checking implemented by tytso.
9*/
/*
* # ! Program starts detection in part by tytso implemented.
*/
1011 / *
* The entire execution files are loaded into memory. i node executable file is placed in the current process executable field
* ( "Current-> executable"), and page exceptions actual loading operation and cleanup executable file.
*
* Once again, I can proudly say, linux can withstand modification: in less than two hours of work time to complete
*/
1920 #include <errno.h>
// error number header files. The system comprises various error number. (Linus imported from the minix).
twenty one #include <string.h> // string header file. Mainly defines the built-in functions related to operation of the string.
twenty two #include <sys / stat.h> // File Status header file. Containing configuration file or system state stat {} and constants.
twenty three #include <a.out.h> // a.out header files. It defines the a.out executable file format and some macros.
27 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
28 #include <linux / mm.h> // memory management header files. It contains the defined page size and page number of the release function prototypes.
29 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
3031 extern int sys_exit (Int exit_code); // program exits a system call.
32 extern int sys_close (Int fd); // close the file system calls.
3334 / *
* Memory 32 should be sufficient, which makes the environment parameters (env + arg) combined to achieve the total space 128kB!
*/
39 #define MAX_ARG_PAGES 32
4041 / *
--417--
9.17 exec.c program
* Create a pointer table, and put their addresses on the "stack", and then returns a pointer to the value of the new stack.
*/
//// create environment variables and parameters pointer table in the new user stack.
// Parameters: p - the data segment as a starting point offset pointer parameters and environmental information; argc - the number of arguments; envc - number of environmental
51 sp = (unsigned long *) (0xfffffffc & (unsigned long) p); // sp moved downwardly, the number of vacant space occupied by the environmental
parameters and environmental parameters so that the pointer points to where envp.
52 sp - = envc + 1;
53 envp = Sp;
// sp downward movement, the number of empty command line parameter space occupied by the pointer, and a pointer to the argv so there. // pointer plus
54 sp - = argc + 1;
55 argv = Sp;
// pointer envp environmental parameters and command-line parameters and the number of command line arguments a pointer onto the stack.
70 }
7172 / *
*/
//// count the number of parameters.
// Parameters: argv - parameter array of pointers, a pointer to the last entry is NULL. // Returns: the number of
arguments.
--418--
9.17 exec.c program
77 int i = 0;
78 char ** tmp;
7980
if (tmp = argv )
81 while ( get_fs_long ((Unsigned long *) (tmp ++)))
82 i ++;
8384
return i;
85 }
8687 / *
* These have been directly into the new user memory format.
*
* On day 1991.12.24 modified by TYT (Tytso), it increased from_kmem parameter, which indicates the character string or
*
* from_kmem argv * argv **
* 0 User-space user space
* 1 Kernel space user space
* 2 Kernel space kernel space
*
* We are through the clever handling fs segment register operations. Due to load a segment register too costly, so
* We try to avoid calling set_fs (), unless it is necessary.
*/
//// copying a specified number of the parameter string to the parameter space and the environment.
// parameters: argc - The number of parameters to be added; argv - parameter array of pointers; page - page space environment parameters and an array of pointers. //
p - offset pointer in the parameter table space, always points to the head of the string copied; from_kmem - source string flag. // in do_execve () function, p is
initialized to point to a last long word parameter table, the parameter string (128kB) space // stack operation is reverse to replicate stored, so p pointer will always point
parameters the head of the string. // Returns: the parameter space environment and the current head pointer.
104 static unsigned long copy_strings (Int argc, char ** argv , Unsigned long * page,
105 unsigned long p, int from_kmem)
106 {
107 char * tmp, * pag;
108 int len, offset = 0;
--419--
9.17 exec.c program
115 if (from_kmem == 2)
116 set_fs (New_fs);
// loop processing of each parameter is copied from the last parameter starts reverse, copied to the specified offset address.
118 if (from_kmem == 1)
119 set_fs (New_fs);
// start from the last parameter reverse operation, a fetch fs argument pointer to the last segment tmp, if it is empty, then an error crash.
122 if (from_kmem == 1)
123 set_fs (Old_fs);
// Calculation of the argument string length len, tmp and end points of the argument string.
136 if (from_kmem == 2)
137 set_fs (Old_fs);
// If the current offset value string space where p page pointer array entry page [p / PAGE_SIZE] == 0, indicates that the corresponding page does not exist, // need to request a new free
memory pages, the page pointer is filled pointer array, and also to enable the new page pag point, if the application is not idle // page 0 is returned.
142 if (from_kmem == 2)
143 set_fs (New_fs);
144
145 }
--420--
9.17 exec.c program
// copy argument string into a byte at a pag + offset from the segments fs.
149 if (from_kmem == 2)
150 set_fs (Old_fs);
// Finally, return parameter head space and the environment offset parameter information has been copied.
151 return p;
152 }
153
//// modify the local descriptor table descriptor segment base address and length limit, and the spatial parameters and environment data page is placed in the end section. //
Parameters: text_size - code segment executable file header length value field gives the a_text; //
154 static unsigned long change_ldt (Unsigned long text_size, unsigned long * page)
155 {
156 unsigned long code_limit, data_limit, code_base, data_base;
157 int i;
158
// The execution file header a_text value to calculate the length of a page code segment boundary indefinite length. And set the data length of 64MB.
// fs segment register into the local descriptor table data selectors (0x17).
169 __asm __ ( " pushl $ 0x17 \ n \ tpop %% fs ": :);
// parameters and environment space has been stored in the page data (there are a total of MAX_ARG_PAGES pages, 128kB) // end of the data segment into a linear
177 }
178 179 /
*
180 * 'Do_execve ()' executes a new program.
181 * /
/*
* 'Do_execve ()' function executes a new program.
*/
--421--
9.17 exec.c program
//// execve () system call interrupt function. Load and execute child process (other programs). // This function
interrupt system calls (int 0x80) function function number __NR_execve call.
// Parameters: eip - program code pointer points to the stack at eip calling system interrupts, see kernel / system_call.s // program instructions beginning portion;
tmp - the interrupt return address when calling _sys_execve system useless; / /
filename - the file name of the execution of the program; argv - command line argument pointer array; envp - environment variable array of pointers. // Returns: If the call
succeeds, not returned; otherwise setting error number and returns -1.
182 int do_execve (Unsigned long * eip, long tmp, char * filename,
183 char ** argv , Char ** envp )
184 {
185 struct m_inode * Inode; I // node pointer memory structure variables.
188 unsigned long page [ MAX_ARG_PAGES ]; // pointer to an array of environmental parameters and page string space.
Effective user ID (euid) // If the user ID mark (set-user-id) set file, then the implementation process back on // set to file a user ID, otherwise it is set to
euid the current process. Here the value temporarily stored in e_uid variable. Effective group ID (egid) // If you set group ID flag (set-group-id) set file,
then the implementation process is set to the group ID // files. Otherwise it is set to egid the current process.
processes belong to the same group, the word three is the lowest property group of users of file access permission flags. // otherwise the word three is the lowest property rights of other users
--422--
9.17 exec.c program
215 i >> = 3;
// If the user does not perform the above rights and other users do not have any authority, and not the superuser, it indicates that the file is not // be executed. Thus not
225 ex = * ((struct exec *) Bh-> b_data); / * Read exec-header * / / * Performing the read head portion * /
// If the two-byte executable file to the beginning of the '#!', And sh_bang flag is not set, then execute the script file processing.
226 if ((bh-> b_data [0] == '#') && (bh-> b_data [1] == '!') && (! sh_bang)) {
227 /*
228 * This section does the #! Interpretation.
229 * Sorta complicated, but hopefully it will work. -TYT
230 */
/*
* This part of the processing and interpretation of the '#!', Some complicated, but want to work. -TYT
*/
231232
char buf [1023], * cp, * interp, * i_name, * i_arg;
233 unsigned long old_fs;
234
// copy the program execution head his characters '#!' Behind the string to buf, which contains a script handler name.
248 i_arg = 0;
249 for (; * cp && (* cp = '! ') && (* cp! =' \ t '); cp ++) {
250 if (* cp == '/')
251 i_name = cp + 1;
252 }
// If there are characters in the file name, then it should be the parameter string, so i_arg points to the string.
--423--
9.17 exec.c program
253 if (* cp) {
254 * Cp ++ = '\ 0 ';
255 i_arg = cp;
256 }
257 /*
258 * OK, we've parsed out the interpreter name and
259 * (Optional) argument.
260 */
/*
* OK, we have an interpreter parses the file name and (optional) parameter.
*/
// If sh_bang flag is not set, it is set, and replication environment variables and parameters specified number string to the parameter string and the environment space.
261 if (sh_bang ++ == 0) {
262 p = copy_strings (Envc, envp , Page, p, 0);
263 p = copy_strings (--Argc, argv +1, page, p, 0);
264 }
265 /*
266 * Splice in (1) the interpreter's name for argv [0]
267 * (2) (optional) argument to interpreter
268 * (3) filename of shell script
269 *
270 * This is done in reverse order, because of how the
271 * user environment and arguments are stored.
272 */
/*
* Splice (1) argv [0] in place of the name of interpreter
* (2) (optional) parameters interpreter
* Name (3) of the script
*
* This is reverse processed, due to the way users store environment and parameters caused.
*/
// copy the script file name to the arguments and environment space.
--424--
9.17 exec.c program
// the following situations, the program will not be executed: if the executable file is not an executable file desired page (ZMAGIC), or portion of code relocations a_trsize // length is not equal to
0, or data relocation information length is not equal to 0, or code segments + + heap data segment length than 50MB, // indicates that the i-node or performs symbol table file is smaller than the
sum of the length of the length of the head portion, and executive code segment data segment + +.
indicates that the script will run the program, then the environment variable page has been copied, no need to copy.
310 if (! sh_bang) {
311 p = copy_strings (Envc, envp , Page, p, 0);
312 p = copy_strings (Argc, argv , Page, p, 0);
// if p = 0, it means that the environment variable and parameter space page has been filled, to fit the. Go to the error handling.
313 if (! p) {
314 retval = - ENOMEM ;
315 goto exec_error2;
316 }
317 }
318 / * OK, This is the point of no return * /
/ * OK, let's start there would be no return to the place * /
// If the original program is a program execution, then the release of its i-node, and let the process executable program i field points to the new node.
--425--
9.17 exec.c program
itself.
// execute the program at this time is not occupied any page of the main memory area. When executed, would cause the program to perform memory management page fault processing and its
implementation of the following statements, P at this time is at the beginning of the data segment as the origin offset value, and the parameter is pointing to the beginning of the data
333 p + = change_ldt (Ex.a_text, page) - MAX_ARG_PAGES * PAGE_SIZE ; // create_tables () parameters and environment variables
to create a new user stack pointer table and returns the stack pointer.
segment tail field end_data = a_data + a_text; end of the field so that the process stack brk = a_text + a_data + a_bss.
replaced // new execution of the program. Return instruction will pop the stack data and causes the CPU to perform a new executive program, it will not return to the program // call the original
344 eip [0] = ex.a_entry; / * Eip, magic happens :-) * / / * eip, magic worked * /
345 eip [3] = p; / * Stack pointer * / / * Esp, stack pointer * /
346 return 0;
347 exec_error2:
348 iput (Inode);
349 exec_error1:
350 for (i = 0; i < MAX_ARG_PAGES ; I ++)
351 free_page (Page [i]);
352 return (retval);
353 }
354
Linux Kernel 0.11 Supports only a.out (Assembley & link editor output) Executable file format, although this format is now gradually do, and use more feature complete ELF
( Executable and Link Format ) Format, but because of its simplicity, as a material just getting started learning more applicable. The following comprehensive introduction a.out format.
--426--
9.17 exec.c program
In the header file < a.out.h> It affirmed the three data structures as well as some of the macro function. These machine code files describe the data structures (binary)
An executable file can have a total of seven sections (Section VII) components. In order, these portions are: an end effector
Execute the file header section. This portion contains a number of parameters, these parameters are used to load the kernel executable file into memory and executed,
and the linker ( ld) Using these parameters will be some combination of binary object files into an executable file. This is the only part of the necessary.
Containing program execution is loaded into memory so that the instruction code and associated data. It can be loaded as read-only. Data
This portion contains data already initialized, it is always loaded into the read-write memory. Relocations
This portion contains the linker used for recording data. The code segment for the positioning of the pointer or address in the binary object file combination. Data relocation
The effect is similar relocations section, but is a relocatable data segment pointers. Symbol table section ( simbol
table)
This part also contains the data for recording linker used for cross-reference to named variables and functions (symbol) between the binary object file.
This portion contains the symbol corresponding to the name string. Each binaries are to perform a data structure ( exec structure )Start. The form of the data
structure as follows:
struct exec {
unsigned long a_midmag; unsigned
long a_text; unsigned long a_data;
unsigned long a_bss; unsigned long
a_syms; unsigned long a_entry;
unsigned long a_trsize; unsigned long
a_drsize;};
a_midmag - The field containing the N_GETFLAG () , N_GETMID with N_GETMAGIC () Sub-section accessible by the link is loaded at runtime into the process address
space. Macros N_GETMID () Machine for returning an identifier ( machine-id) , Indicating a binary file that will run on any machine. N_GETMAGIC () Macro specified magic number,
which uniquely determines the difference between the binaries loaded with other documents. Field must contain one of the following values:
OMAGIC - It represents code and data segments and head immediately after the execution is stored in a row. The kernel code and data segments are loaded into
read-write memory.
NMAGIC - with OMAGIC Like, code and data segments and head immediately after the execution is stored in a row. However, the kernel code is loaded into a read
only memory section and load data into the code segment begins next writable memory boundaries.
ZMAGIC - Kernel loads separate page from the binary executable file if necessary. Performs a header, the code and data segments are processed blocks into a
plurality of page sizes linker. Kernel code loaded when the page is read-only, and the page data segment is writable.
a_text - The length field contains the value of the code segment, the number of bytes.
a_data - This field contains the length of the data section, the number of bytes.
--427--
9.17 exec.c program
a_bss - contain' bss Segments' length, with a core which is provided after the initial data segment break ( brk ). When the kernel loader, this memory can be written after the
a_syms - The symbol table contains the byte length of the value part.
a_entry - After the core containing the executable file is loaded into memory, the memory address of the start of program execution.
a_trsize - This field contains the code relocation table size, the number of bytes.
a_drsize - This field contains the data relocation table size, the number of bytes. in a.out.h Header file defines several macros use exec Conformance testing structure or
the positioning of each execution file portion (section) the position of the offset value. These macros are:
N_BADMAG (exec) in case a_magic Field can not be identified, a nonzero value is returned.
N_DATOFF (exec) Start position of the data segment byte offset value.
N_DRELOFF (exec) Data re-start position of the byte offset location table.
N_TRELOFF (exec) Starting position of the code byte relocation table offset.
N_SYMOFF (exec) Start position of the symbol table byte offset value.
N_STROFF (exec) Starting position of the string table byte offset value. Relocation records having a standard format, which
struct relocation_info {
int r_address;
unsigned int r_symbolnum: 24, r_pcrel: 1,
r_length: 2, r_extern: 1,
r_baserel: 1, r_jmptable: 1,
r_relative: 1, r_copy: 1;
};
r_address - This field contains the byte offset pointer link required program processing (editing) of. Relocations offset value from the beginning of the code segment is
counted, the value of the offset data relocation is calculated from the beginning of the data segment. The linker will have been stored in the offset value using the relocation
r_symbolnum - This field contains a sequence number value in the symbol table (not a byte offset) symbol structure. After the linker is calculated absolute
address of the symbol, it is added to the address pointer being relocated. (in case r_extern Bits is 0 The situation is different, see below. )
r_pcrel - If this bit is set, the linker will think is updating a pointer that use pc Relative addressing mode, machine code instruction section belongs. When
using this program is run relocated pointer that addresses are implicitly added to the pointer.
r_length - The pointer field contains the length of the 2 The power value: 0 Show 1 Bytes long, 1 Show 2 Bytes long, 2 Show 4 Bytes long.
r_extern - If the bit is set, indicating that the relocation requires an external reference; in this case must use a symbolic link to update the corresponding address pointer.
When this bit is 0 , Then relocation is "local"; the Linker pointer is updated to reflect changes in the respective segment load address, rather than reflecting a change in symbol
values (unless simultaneously provided r_baserel , See below). under these circumstances, r_symbolnum
Contents of the field is a n_type Value (see below); such field tells the linker is repositioned pointer to that segment.
r_baserel - If this bit is set, then r_symbolnum Field specifies a symbol to be relocated to Global Offset Table ( Global Offset Table) One offset value. At
runtime, the global offset table is set to the offset address of a symbol.
r_jmptable - If the bit is set, then r_symbolnum Field specifies a symbol to be relocated to the procedure linkage table ( Procedure
--428--
9.17 exec.c program
r_copy - If the bit is set, the relocation record specifies a symbol, the symbol of the content is copied to r_address designated place. The copy operation is
shared by the target modules in a suitable data items completed runtime linker.
The symbol name is mapped to an address (or, more colloquially string is mapped to a value). Because the linker to adjust the name address, a symbol must be used to
indicate its address until you have been given an absolute address value. Symbol is the name of a variable length symbol table and a fixed-length string table records the
struct nlist {
union {
char * N_name;
long
n_strx;
} N_un;
unsigned char n_type;
char n_other;
short n_desc;
unsigned long n_value;
};
n_un.n_strx - This name has signed byte offset in the string table. When the program uses nlist () Accessing a function symbol table, this field is replaced n_un.n_name
n_type - Used to link the program to determine how to update the value of the symbol. Using a bit mask ( bitmasks) can n_type Field is divided into three
sub-fields, for N_EXT Type of sign bit, the program will link them as "external" symbol, and other binary object files to allow references to them. N_TYPE The
N_UNDF - Undefined symbol. Linker must locate external symbols having the same name in the other binary object file to determine the absolute value
of the symbol data. Under special circumstances, if n_type Field is nonzero and no binary file defines this symbol, the linker in BSS The symbol resolution
Byte. If more than one binary symbol is not defined in the object file and the binary value of the target files are inconsistent its length, the linker will
N_TEXT - A code symbols. The value of this symbol is the code address, the linker when combining binary object file updates its value.
N_DATA - A data symbol; and N_TEXT Similarly, the data for the address. An offset value corresponding to the code and data symbols but the value is not the address
file; offset to find the file, it is necessary to determine the relevant portion of the load start address and subtracting it, and then add the offset portion.
N_BSS - One BSS Symbols; data symbols and code or the like, but without a corresponding shift in the binary object file.
N_FN - A file name of the symbol. When you merge binary object files, the linker will insert the symbol in binary notation before. Name of the symbol is to give the
filename linker, and its value is a binary file in the first code segment address. Symbols do not need to file name, but very useful for the transfer procedure when
N_STAB - Mask transfer procedure for selecting the symbol (e.g. gdb) Bit of interest; its value stab () Explained.
n_other - According to the field n_type Determining a segment, independent information about the symbols provide symbol relocation operation. Currently, n_other
Lowest field 4 Bits comprising one of two values: AUX_FUNC with AUX_OBJECT (For definition, see < link.h> ). AUX_FUNC
The symbol associated with the function call, AUX_OBJECT The symbols associated with the data, whether they are located in the data segment is a code segment. This field is
--429--
9.18 stat.c program
n_desc - Transfer procedure reserved for use; linker does not process it. The debugger different fields for a different purpose.
n_value - Containing the value of the symbol. For the code, data, and BSS Symbol, which is an address; for other symbols (e.g. symbols transfer procedure), the value may
be arbitrary.
String table is of length u_int32_t Followed by a null The end of the symbol strings. The length of the table is representative of the size, in bytes, so 32 Its minimum position
The program implements the system call takes the file status information stat () with fstat () , And the information is stored in the file structure of the buffer status of the user.
stat () Natori is the use of file information, fstat () Using a file handle (descriptor) to extract information.
1/*
2 * Linux / fs / stat.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #include <errno.h>
// error number header files. The system comprises various error number. (Linus imported from the minix).
8 #include <sys / stat.h> // File Status header file. Containing configuration file or system state stat {} and constants.
12 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
13 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
14
//// Copy the file status information.
// parameters are inode file corresponding to the node i, statbuf stat file status is structured pointer, for storing the acquired state information.
--430--
9.19 fcntl.c program
statbuf is a pointer to the buffer to store state information. // returns 0 if the error an error code is returned.
(descriptor), statbuf the buffer pointer is stored status information. // returns 0 if the error an error code is returned.
52 if (fd> = NR_OPEN ||! (F = current -> filp [fd]) || (inode = f-> f_inode))!
53 return - EBADF ;
// Copy the file i-node status information to the user buffer.
54 cp_stat (Inode, statbuf);
55 return 0;
56 }
57
From the beginning of this section a number of documents annotated, all belonging to the upper handlers directories and files operations.
--431--
9.19 fcntl.c program
This document fcntl.c Achieve the document control system call fcntl () And two file handles (descriptor) replication system call dup () with dup2 () .
dup2 () Specify the value of the new handle, and dup () Current minimum value of unused handle is returned. Handle copy operation is mainly used in the standard input file I / O
1/*
2 * Linux / fs / fcntl.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #include <string.h>
// string header file. Mainly defines the built-in functions related to operation of the string.
8 #include <errno.h> // error number header files. The system comprises various error number. (Linus imported from the minix).
9 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
10 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
11 #include <asm / segment.h> // operation section header. For embedded segment register defines the operation assembly function.
29 if (arg> = NR_OPEN )
30 return - EMFILE ;
// Close the figure flag bit is reset when the handle is executed. I.e. running exec () is not closed when the handle class functions.
32 ( current -> filp [arg] = current -> filp [fd]) -> f_count ++;
33 return arg; // returns the new file handle.
--432--
9.19 fcntl.c program
34 }
35
//// Copy the file handle system calls.
// copy specified file handle oldfd, the new handle value equal to newfd. If newfd is already open, close it first.
36 int sys_dup2 (Unsigned int oldfd, unsigned int newfd)
37 {
38 sys_close (Newfd); // If the handle newfd is already open, close it first.
39 return dupfd (Oldfd, newfd); // copy and return the new handle.
40 }
41
//// Copy the file handle system calls.
// copy specified file handle oldfd, the value of the new handle is currently the smallest unused handle.
47 int sys_fcntl (Unsigned int fd, unsigned int cmd, unsigned long arg)
48 {
49 struct file * Filp;
50
// If the file handle to open the process up to a value greater than the number of files NR_OPEN, or file structure pointer of the handle is empty, an error // return an error code and exit.
53 switch (cmd) {
54 case F_DUPFD : // copy the file handle.
55 return dupfd (Fd, arg);
56 case F_GETFD : // get close flag to perform file handles.
57 return ( current -> close_on_exec >> fd) & 1;
58 case F_SETFD : Close flag // set handle execution. Bit 0 is set arg is set, otherwise closed.
59 if (arg & 1)
60 current -> close_on_exec | = (1 << fd);
61 else
62 current -> close_on_exec & = ~ (1 << fd);
63 return 0;
64 case F_GETFL : // get file status flags and access modes.
65 return filp-> f_flags;
66 case F_SETFL : // set file status and access mode (set according to arg added, non-blocking flag).
71 return -1;
72 default:
73 return -1;
74 }
75 }
76
--433--
9.20 ioctl.c program
ioctl.c File implements the input / output control system call ioctl () . The main call tty_ioctl () Function of the terminal I / O Control.
1/*
2 * Linux / fs / ioctl.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #include <string.h>
// string header file. Mainly defines the built-in functions related to operation of the string.
8 #include <errno.h> // error number header files. The system comprises various error number. (Linus imported from the minix).
9 #include <sys / stat.h> // File Status header file. Containing configuration file or system state stat {} and constants.
1011 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
1213 extern int tty_ioctl (Int dev, int cmd, int arg); // terminal ioctl (chr_drv / tty_ioctl.c, 115).
14
// definition of the input and output control (the ioctl) function pointer.
30 int sys_ioctl (Unsigned int fd, unsigned int cmd, unsigned long arg)
31 {
32 struct file * Filp;
33 int dev, mode;
34
// If the file descriptor exceeds the number of files can be opened, or to a file structure descriptor pointer is empty, an error code is returned, exit.
--434--
9.20 ioctl.c program
--435--
10.1 Overview
10.1 Outline
in Intel 80x86 Architecture, Linux Kernel memory manager uses paging management. Using the page directory and page table structure of the other processing core part of
the code the application and release operations to memory. Memory management is a memory page as a unit, and a memory page is the address of a continuous 4K Bytes of
physical memory. By page directory entries and page table entries, you can use addressing and managing the specified page. in Linux 0.11 Memory management directory, there
among them, page.s Relatively short document, containing only the abnormal memory page of interrupt processing ( int 14 ). The main achievement of the processing of the
missing pages and page write-protected. memory.c It is the core memory page file management, memory for initialization, page directory and page table management and other
in Intel 80X86 CPU The program uses the address in the addressing sequence is composed of segment and offset values. This address is not directly used to address the
physical memory address, and therefore referred to as virtual addresses. In order to address the physical memory, a need for an address translation mechanism to map or transform
the virtual address to physical memory, the other one of the main function is the main function of this address conversion memory management mechanism (memory management
is seeking memory site protection mechanisms. due to space limitations, not discussed in this chapter). Virtual segment address management mechanism is first converted into a
form of intermediate address -CPU 32 Bit linear address and then use this paging management system maps linear addresses to physical addresses.
In order to clarify Linux Kernel memory management mode of operation, we need to understand how memory paging management, understand the mechanism of
addressing. Object of the paging supervisor is to map pages of physical memory to a linear address. When analyzing memory management procedures in this chapter, a clear
distinction needs to clear a given address is linear address or actual physical memory address.
in Intel 80x86 Systems, paging management table is performed by two memory page directory table and page table thereof. See Fig. 10-1
Fig.
Where the structure of the page table and page directory table is the same, the same entry structure. Each entry (referred to as the page directory entry) (page directory
table 4 Byte) is used to address a page table, and each page table entry ( 4 Byte) specifies a physical memory pages. Therefore, if you specify a page directory entry and a page
table entry, we can uniquely determine the corresponding physical memory pages. Page directory table occupied by a memory, so most
--437--
Overall 10.2 Functional Description
More than can be addressed 1024 A page table. Each page table while it occupies a memory, a page table can therefore address up to 1024 Physical memory pages. In this way 80386
All page table, a page table of contents can be addressed were addressed 1024 X 1024 X 4096 = 4G Memory space. in Linux 0.11 Kernel, all processes using a page table of
For the rest of the application process or kernel is concerned, the use of memory when applying linear address. Next we asked: "So, a linear address how to use these
tables to map to a physical address on it?." To use the paging mechanism, a 32 Bit linear address is divided into three sections, each directory entry is used to specify a page, a
page table entry and a corresponding physical memory page address offset, which can be addressed to a linear address indirectly specified physical memory location. See Fig. 10-2 Fig.
a page table entry page table entry page table entry page
The table
main memory area of physical memory
table entry of
entry page
1024 Memory
a page table
Page
table entry of
Memory page
entry page
memory page
memory page
memory page
Page directory table
memory page
directory entry directory entry entry page entry page table entry page table entry
page table memory page
directory page
entry page entry in the
memory page
1024 Page directory Page table
memory page
Map 10-1 Page directory table and page table structure diagram
Linear Address: page directory entry page table entry page offset value
CR3
Bit linear address 31-22 Altogether 10 Bits are used to determine the directory entry in the page directory, bit 21-12 Addressing page directory entry for the specified page
table page table entry, the last 12 Offset address bits of a physical memory page table entry exactly as specified in.
--438--
Overall 10.2 Functional Description
In the memory management functions, a large amount of calculation using the actual transformation from the linear address to physical address. For a given process, a
linear address through FIG. 10-2 Address conversion relationship shown, we can easily find the page directory entry corresponding to the linear address. If the directory entry is
valid (being used), then the directory entry specified in the page frame address of the page table base address in physical memory, then the combined linear page table entry
pointer address, if the page table entry is valid, the page table entry in the designated page frame address, we can determine the address specified ultimate linear address
corresponding to the actual physical memory pages. Conversely, if the physical memory page address to be used in a known, find the corresponding linear address is required for
all of the entire page directory table and page table search. If the physical memory pages are shared, we may find more corresponding linear address. Map 10-3 The method of
using the image shows a given linear addresses are mapped to physical memory pages. For the first process (task 0 ), Which is in the page table after table of contents page, a
total of 4 page. For the application process, its memory page table is used when the process of creating an application to the memory management procedures, and therefore is in
Physical Memory
16M
2
Process's page
A system can exist simultaneously multiple page directory table, but at some point there is only one page table of contents is available. The current page directory table is CPU
Register CR3 To determine which stores the physical memory address of the current page directory table. But in the book in question Linux The kernel using only one page
directory table.
In Fig. 10.1 We see that each page table entry corresponding to the physical memory pages 4G Within the address range is random and is determined by the page table
entry in page frame address of the content, that is, setting the page table entry is determined by the memory management program. Each entry in the page frame address, access
flag, dirty (has rewritten) flag and the flags and the like exist. Structure entry can be found in FIG. 10-4 Fig.
31 12 11 0
U/ R/
Page frame address bits 31..12 (PAGE Available
P
FRAME ADDRESS) (AVAIL) 0 0 DA 0 0
S W
--439--
Overall 10.2 Functional Description
Among them, the page frame address ( PAGE FRAME ADDRESS) It specifies a physical memory starting address. Because the memory pages are located 4K
On the border, so its low 12 Bit is always 0 Therefore low entry 12 Bits may be used for it. In a table of contents page, the page frame address entry is the starting address of a
page table; in a second stage page table, the page frame address of the page table entry contains the physical memory page address desired memory operations.
Bitmap exists ( PRESENT - P ) To determine whether a page table entry can be used to address the conversion process. P = 1 It indicates that the item is available. When a
directory entry or a second entry level P = 0 , Then the entry is invalid, address translation can not be used. At this time, all other bits of the entry are available to the program;
when CPU When trying to use a page table entry for address translation, if any at this time a page table entry P = 0 , The processor will send abnormal signals page. At this
page fault exception handler can put the requested page into physical memory, and the instruction that caused the exception will be re-executed.
I visited ( Accessed - A ) And modified ( Dirty - D ) Bit is used to provide information about the pages used. In addition to the modified bits of the page directory entries, these
Before a memory read or write operation, CPU The provision of the relevant bits accessed directories and secondary page table entry. Before a write to an address covered
by the page table entry two, the processor will set the two page table entry modified bit, and the page directory entry is modified bit unused. When the demand for more memory
than the actual amount of physical memory, the memory manager can use these bits to determine which page can be removed from memory to make room. The memory manager
Read / Write bit ( Read / Write - R / W ) And user / super user bits ( User / Supervisor - U / S ) Not used for address translation, but page-level mechanism to protect, by CPU In
With these concepts, we can explain Linux A method of memory management. But also you need to know Linux 0.11 Using kernel memory space. for Linux
0.11 Core, which supports up to default 16M Physical memory. In having a 16MB Memory
80x86 Computer system, Linux Physical memory occupied by the kernel part of the foremost section, FIG. end Mark the end position of the kernel module. Followed by a high-speed
buffer memory address as its highest 4M . High-speed buffer memory and is displayed ROM BIOS Divided into two sections. The remaining portion of memory called a main memory
area. Main memory area is allocated by the program management of this chapter. If the system still exist RAM When the virtual disk, the primary bank should deduct the preceding
virtual disk memory space occupied. When you need to use the primary bank would need to apply to the memory management procedures in this chapter, the application of the
basic units of memory pages. Function of each part of the entire physical memory is a schematic view of FIG. 10-5 Fig.
In the boot chapter, we already know, Linux The page directory and page tables are in the program head.s Set. head.s Program at the physical address 0 Department store
a page table of contents, followed by a 4 A page table. This 4 Page table will be used for mission 0 Other derivative process will apply for memory pages in the main memory area
to store their page tables. Chapter two is the program used to operate on these tables, thereby achieving
--440--
Overall 10.2 Functional Description
In order to save the physical memory, the call fork () When generating a new process, a new process with the original process will share the same memory area. Only
when one of the write process, the system will allocate memory for additional pages. This is the concept of copy-on-write.
page.s A program for realizing abnormal page interrupt processing ( int 14 ). The interrupt handler calls were interrupted due to the missing pages and page write-protected
due memory.c middle do_no_page () with do_wp_page () Function for processing. do_no_page () Page will need to take the device to the block from the memory at a specified
location. In the case of shared memory pages, do_wp_page () Will be written copy of the page ( copy on write , Copy-on-write), which also canceled the sharing of the page.
When the code reading this chapter, we also need to understand the distribution of a process executing program code and data in a virtual linear address space, see the
Stack Pointer
Length end_data
* Where nr is task number
Each process in the linear address are from nr * 64M The address of the start position ( nr Is task number), occupied by the linear address space is
64M . Wherein the ambient parameter data block up to the last section 128K Which left initial stack pointer. In the process of creation bss The first section of the page is initialized to
all zeros.
When the process A Use of system calls fock Create a child process B When, as a child process B In fact, it is the parent process A A copy of the parent process and therefore
will have the same physical page. That in order to achieve the goal to save memory and speed the creation of, fork () Function will let the child process B Read-only shared parent A Physical
page. At the same time the parent process A Physical access to these pages are also set to read-only. See memory.c Program copy_page_tables () function. As a result, when the
parent process A Or the child process B Either a write operation, the implementation of these will have to share the physical page of page faults abnormal ( page_fault int14) Interrupted,
this time CPU Exception handling function execution system provided do_wp_page () To try to resolve this anomaly.
do_wp_page () This will result in a write abort to cancel the shared physical page (using un_wp_page () Function), a new copy of the physical page write process, the
parent process A And child processes B Each piece of content has the same physical page. But then it really made the copy operation (only one physical copy this page). And the
piece will be performed physical page write operation can be marked write access. Finally, return from the exception handler, CPU It will just lead to re-execute the write operation
Therefore, for the write process in its own virtual address range, it will be used above the passive copy-write operation, namely: write -> Page aborted -> Write-protection
exception processing -> Re-write operation is performed. As for the system kernel, when a write operation is performed in the virtual address range for a process, for example, the
process of calling a system call, the system call will copy the data to process the buffer area, it will take the initiative to call to memory page validation function write_verify () To
determine whether there has been a shared page exists, if so, to copy a page write operation.
--441--
10.3 Makefile file
This document is mm Directory management program to compile profiles, total make Program.
# The frame pointers; -fcombine-regs merge register, reduce the use of register class; -finline-functions all Jane
# Short single function calling program code embedded; -nostdinc -I ../ include not using the default path comprises a file, and
# Here the use of the specified directory (../include).
4 AS = Gas # GNU assembler.
5 AR = Gar # GNU binary file processing program for creating, modifying and extracting files from the archive.
6 LD = Gld # The GNU linker.
7 CPP = Gcc -E -nostdinc -I ../ include
# C pre-processing options. -E C only run pre-treatment, pre-treatment and the results for all of the specified program is output to the standard output C
# Refers gcc CFLAGS using the specified options compiled C code is compiled without stops (-S), thereby generating
# C each corresponding to the input file assembler code file. Assembler default file name is generated by the original file name C
# Remove .c and .s suffix plus. -o represented followed by the name of the output file. Of which $ *. S (or $ @ ) is automatic target variable,
12 .so:
13 $ (AS) -o $ *. O $ <
14 .cs: # Similar to the above, * c file -. * .S assembler files. Not connect.
15 $ (CC) $ (CFLAGS) \
16 - S -o $ *. S $ <
1718 OBJS
= Memory.o page.o # Define the target file variable OBJS.
1920 all: mm.o
# The following rules for the cleanup. When performing 'make clean', will execute commands on the 26-27 line, remove all compiled
# Connection file generated. 'Rm' command is to delete the file, meaning -f option is to ignore the file does not exist, and does not delete the information.
25 clean:
--442--
10.4 memory.c program
26 rm -f core * .o * .a tmp_make
27 for i in * .c; do rm -f `basename $$ i .c`.s; done
28
# Here was the objective or rules for checking dependencies between files. Methods as below:
# Sed string editing program for the Makefile (where that is their own) for processing, the output is deleted Makefile
# File '### Dependencies' all rows behind the row (row 35 starting from below), and generates tmp_make
# Temporary files (for 30 lines). Gcc then performs a preprocessing operation on each file in the C mm / directory.
# - M flag tells the preprocessor output description of the rules relating to each target file, and make compliance with these rules syntax.
# For each source file, the output of preprocessor make a rule, the result is a certain form of the corresponding source file
# File name plus its dependencies - lists all the header files included in the source file. The pretreatment results are added to the temporary
# Tmp_make file, and then copy the temporary file into a new file Makefile.
29 dep:
30 sed '/ \ # \ # \ # Dependencies / q' <Makefile> tmp_make
31 (For i in * .c; do $ (CPP) -M $$ i; done) >> tmp_make
32 cp tmp_make Makefile
3334 ### Dependencies:
This program paged memory management. To achieve the main memory area and dynamically allocated memory recovery operation. For the physical memory
management kernel uses an array of bytes ( mem_map [] ) To represent the state of the main memory area of all physical memory page. Each byte describes the occupancy state of
a physical memory page. Where the value indicates the number of occupied, 0 It indicates that the corresponding physical memory is idle. When applying a physical memory, will
increase the value of the corresponding byte 1 . For management process virtual linear address of the kernel uses page directory table and page table structure to manage the
processor. The mapping relationship between the physical memory pages and the process linear address is handled by modifying the contents page directory and page table
entries. Next, several major functions provided to the procedure described in detail.
get_free_page () with free_page () These two functions are used to manage the physical memory in the main memory area of occupancy and vacancy, regardless of the
get_free_page () Function is used to apply a free memory page in the main memory area, and returns to the start address of the physical memory page. First, it scans the
memory array of FIG byte page mem_map [] , Is looking for value 0 Byte entries (corresponding to the free page). If there is no return 0 End, represents the physical memory is used
up. If the value is found 0 Byte, it is set 1 And converted to the corresponding free page start address. Then make clear operation of the memory page. Finally, return to the starting
free_page () For releasing a physical memory at the specified address. It first determines whether the memory address specified by < 1M , If it returns, because 1M Within
the kernel is specific; if the specified physical memory address is greater than or equal to the actual top-end memory address, an error message is displayed; then converted from
page number specified by the memory address: ( addr - 1M) / 4K ; Then determines the corresponding page number mem_map [] Whether byte entries 0 , If not for the 0 , It
decreases 1 Return; otherwise cleared the byte entries, and shows " Trying to release a free page " Error message.
free_page_tables () with copy_page_tables () These two functions places a physical memory page table corresponding to the block ( 4M ) Units, linear release or copies the
specified address and length (number of page table) corresponding to the physical memory page block. Not only for the items corresponding to the page directory and page table
management in linear address modification, but also take up or release operation for each page table page table entries corresponding to all pages of physical memory.
free_page_tables () And for releasing the linear address to specify the length (the number of page table) corresponding to the physical memory pages. It first determines
whether the designated address is in linear 4M On the boundary, if not, an error message and freezes the display; then determines whether the specified address value = 0 ,if,
--443--
10.4 memory.c program
Error message is displayed " Trying to free up space occupied by the core and buffer " And crash; number of directory entries in the page directory table occupied then calculates size
, I.e. the number of page table and calculates the corresponding directory entry starting number; then occupied start from a corresponding home directory entries, all released size Directory
entries; simultaneous release of all page table entries and the corresponding physical memory page corresponding to the page directory entry of the table referred to; the last page
copy_page_tables () For copying the specified linear address and length (number of page tables) corresponding to the memory page directory and page table entries so as
to be copied to the corresponding page directory and page tables are shared original area of physical memory used. This function first verify that the specified source and
destination address of the linear address are linear 4Mb The memory boundary address, otherwise an error message is displayed, and crash; start page is then converted to the
corresponding linear address specified by the directory entry ( from_dir, to_dir ); And calculates the required memory area occupied by copying the number of tables (i.e., a page
directory entry number) page; and then begins the original directory entry page table entry to the new directory entry and free the page table entry, respectively. Page directory
table is only one, and the new process's page table need to apply to hold free memory pages; thereafter then the original and the new page directory and page table entry are set
to read-only page. When a page write operation on the use of aborted calls, copy on write operation. Finally, the shared physical memory pages corresponding to the byte array in
put_page () For mapping a physical memory page to the specified address at the specified linear. It first determines the validity of the specified memory page address, to be
in 1M And the most upper memory address outside the system, or warning; then calculates the designated directory entry corresponding to the linear address of the page directory
table; at this time if the directory entry is valid ( P = 1 ), Whichever corresponds to the address of the page table; otherwise apply to the free page using the page table, and sets the
corresponding page table page table entry attributes. Finally, still returns the specified physical memory page address.
do_wp_page () Page is aborted process (in mm / page.s Page implemented) called in write-protect handlers. It is first determined whether the address code region in the
process, if the program is terminated (code can not be altered); and copy operations when the page write ( Copy on Write ).
do_no_page () Page is invoked during aborted page fault handler. It first determines whether the specified offset with respect to the length of the linear address base address
value of the process in a process space. If it is greater than the length of the code plus data, or just beginning the process of creation, then immediately apply a physical memory,
and mapped into the process linear address, and then return; then try for page sharing operation, if successful, return immediately; otherwise apply for a a page memory and reads
the information from the device; if the page information is added, to specify a linear address + 1 Page length exceeds the length of the process code plus data, it would be over in
part cleared. The page is then mapped into the linear address specified.
get_empty_page () For obtaining a free physical memory and mapped to the specified linear address. Mainly used get_free_page ()
1/*
2 * Linux / mm / memory.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
13 * Ok, demand-loading was easy, shared pages a little bit tricker. Shared
--444--
10.4 memory.c program
/*
* OK, demand load is relatively easy to write, and share the page it takes a little skill. Share page program is
* 02.12.91 start writing, it seems to work - Linus.
*
* By performing about 30 / bin / sh shared test operations: the old core needs to occupy more than among
* 6M memory, and now it does not. Now it seems to work very well.
*
* To "invalidate ()" functions have been corrected - I have done enough in this regard.
*/
2223 #include <signal.h>
// signal header files. Defined symbolic constant signal, the signal structure and the operation function prototype signal.
2627 #include <linux / sched.h> // scheduler header file, which defines the structure of the task_struct task, task 0 of the initial data,
// Some parameters related descriptors set and get embedded assembly function macro statement.
28 #include <linux / head.h> // head header file defines a simple structure segment descriptors, and several selectors constants.
29 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
3031 volatile void do_exit (Long code); // process handler exits, in kernel / exit.c, 102 rows.
32
//// display ran out of memory error message and exit.
38
// refresh the page cache conversion macro function.
@ In order to improve the efficiency of address conversion, CPU the most recently used page table data stored in the chip in the cache. After the modified page table // information, we
need to flush the buffer. The method used here to reload the page directory base register cr3 to refresh. // The following eax = 0, is the base address of the page directory.
39 #define invalidate () \
40 __asm __ ( " movl %% eax, %% cr3 "::" a "( 0))
4142 / * These are not to be changed without changing head.s etc * /
/ * Define the following needs to be changed if you need to change with head.s and other documents relevant information * / // linux 0.11 kernel by default supports a
maximum memory capacity of 16M, these definitions can be modified to fit more memory.
46 #define MAP_NR (Addr) (((addr) - LOW_MEM ) >> 12) // Specify the memory address mapping for the page number.
47 #define USED 100 // flags page is occupied, you see line 405.
48
// CODE_SPACE (addr) ((((addr) + 0xfff) & ~ 0xfff) <current-> start_code + current-> end_code).
--445--
10.4 memory.c program
// This macro is used to determine whether a given address is located in the code segment of the current process, see line 252.
53
// copy a memory (4K bytes).
54 #define copy_page (From, to) \
55 __asm __ ( " cld; rep; movsl "::" S "( from), " D "( to), " c "( 1024): " cx "," di "," si ")
56
// memory map bytes (1 byte represents a memory), each page corresponding byte flag for the current page is referenced (occupied) times.
60 * Get physical address of first (actually last :-) free page, and mark it
61 * Used. If no free pages left, return 0.
62 * /
/*
* Gets the first (in fact, is the last one :-) free pages, and marked as used. If there are no free pages,
* Return 0.
*/
//// take the free pages. If you have no memory available, and 0 is returned.
// Input:% 1 (ax = 0) - 0;% 2 (LOW_MEM);% 3 (cx = PAGING PAGES);% 4 (edi = mem_map + PAGING_PAGES-1). // Output: Returns% 0 (ax = starting
address of the page).
@ 4% above the actual point to register the mem_map [] byte memory the last byte of FIG. This function starts scanning from the forward end of FIG byte // flags of all pages
(total number of pages of PAGING_PAGES), if the free page (memory image of byte 0) page address is returned. // Note! This function simply pointed out that in a free page of
the main memory area, but is not mapped to the linear address of a process to go. // back put_page () function is used for mapping.
68 "Jne 1f \ n \ t" // If no byte is equal to 0, then the skip end (return 0).
69 "Movb $ 1,1 (%% edi) \ n \ t // position corresponding to the memory image of a page.
70 "Sall $ 12, %% ecx \ n \ t" // number of pages * 4K = opposite page start address.
71 "Addl% 2, %% ecx \ n \ t" // coupled with low memory address, that get the actual physical page start address.
72 "Movl %% ecx, %% edx \ n \ t" // start address of the actual page edx register.
73 "Movl $ 1024, %% ecx \ n \ t" // set the count value of the register ecx 1024.
74 "Leal 4092 (%% edx), %% edi \ n \ t" // The EDI 4092 + edx position (the end of the page).
75 "Rep; stosl \ n \ t" // edi within the meaning of the memory is cleared (in the opposite direction, the page is about to be cleared).
76 "Movl %% edx, %% eax \ n" // start address of the page eax (return value).
77 "1:"
78 : "= a "(__ res)
79 : "" (0) " i "( LOW_MEM ) " c "( PAGING_PAGES ),
80 "D" ( mem_map + PAGING_PAGES -1)
81 : " di "," cx "," dx ");
82 return __res; // return to idle page address (if no idle also returns 0).
83 }
8485 / *
--446--
10.4 memory.c program
88 * /
/*
* Release physical address 'addr' a beginning of memory. A function 'free_page_tables ()'.
*/
//// release a physical page of memory address addr began.
// 1MB of memory space for the kernel and buffer, not as a memory allocation page.
89 void free_page (Unsigned long addr)
90 {
91 if (addr < LOW_MEM ) Return; // If addr physical address of the memory is less than the lower end (1MB), is returned.
92 if (addr> = HIGH_MEMORY ) // If the physical address addr> = most high-end memory, the error message is displayed.
97 mem_map [Addr] = 0; // otherwise set corresponding to the page mapping byte is 0, and displays an error message, crash.
*/
//// linear address and the specified constraint length (number of page table), release the corresponding memory page of the memory block specified table entry idle juxtaposition. //
page directory physical address 0 is located at the beginning of 1024, accounting for 4K bytes. Each directory entry to specify a page table. // page table starting at physical address
0x1000 (immediately directory space), each page table have 1024, also accounted for a 4K memory. // each page table entry corresponding to a physical memory (4K). And the size of
the page table entry directory entry are four bytes. // Parameters: from - the starting base address; size - length of release.
physical address @ 0, so the actual directory entry pointer of the directory entry number << = 2, i.e. (from >> 20). And the 0xffc ensure effective // directory entry pointer range.
115 dir = (unsigned long *) ((from >> 20) & 0xffc); / * _ pg_dir = 0 * /
116 for (; size -> 0; dir ++) { // size needs to be released now is the number of directory entries memory.
117 if (! (1 & * dir)) // if the directory entry is invalid (P bit = 0), then continue.
118 continue; Bit 0 (P bits) // directory entry indicates that the corresponding page table exists.
119 pg_table = (unsigned long *) (0xfffff000 & * dir); // get directory entry in the page table address.
120 for (nr = 0; nr <1024; nr ++) {// each page table entry 1024 pages.
121 if (1 & * pg_table) // If the active page table entries (P bit = 1), then release the corresponding memory pages.
--447--
10.4 memory.c program
128 }
129 invalidate (); // refresh the page transform cache.
130 return 0;
131 }
132 133 /
*
134 * Well, here is one of the most complicated functions in mm. It
135 * Copies a range of linerar addresses by copying only the pages.
136 * Let's hope this is bug-free, 'cause this one I do not want to debug :-)
137 *
138 * Note We do not copy just any chunks of memory -! Addresses have to
139 * Be divisible by 4Mb (one page-directory entry), as this makes the
140 * Function easier. It's used only by fork anyway.
141 *
142 * NOTE 2 !! When from == 0 we are copying kernel space for the first
143 * Fork (). Then we DONT want to copy a full page-directory entry, as
144 * That would lead to some serious memory waste - we just copy the
145 * First 160 pages -. 640kB Even that is more than we need, but it
146 * Does not take any more memory - we do not copy-on-write in the low
147 * 1 Mb-range, so the pages can be shared with the kernel. Thus the
148 * Special case for nr = xxxx.
149 * /
/*
* Well, here is one of the most complicated mm memory management program. It is only by replicating memory pages
* Copying the contents to a range of linear addresses. I hope that the code does not error, because I do not want
*
* note! We are not only copy any of the memory block - a block of memory address needs to be a multiple of 4Mb (just
* Page directory entry corresponding to a memory size), because this treatment can function very simple. one way or another,
* Do not want to copy the entire page directory entry corresponding to memory, because doing so would lead to serious waste of memory - we
* Only copy the first page 160 - correspond 640kB. Even copy these pages has exceeded our needs,
* But it will not take up more memory - the copy operation is in the low range of 1Mb of memory we do not write, so
* These pages can be shared with the kernel. So this is a special case of nr = xxxx (nr number of pages in the program middle finger).
*/
//// copy specified linear address and length (number of page table) corresponding to the memory page directory and a page table entry, so that the copied page directory and page
// copy the memory corresponding to the specified address and length of the page directory entries and page table entries. To apply for a new page to hold the page table, the original memory
area is shared; // After two processes shared memory area, a write operation, was assigned to perform the process until there is a new memory page (copy-on-write mechanism).
150 int copy_page_tables (Unsigned long from, unsigned long to, long size)
151 {
152 unsigned long * from_page_table;
153 unsigned long * to_page_table;
154 unsigned long this_page;
155 unsigned long * from_dir, * to_dir;
--448--
10.4 memory.c program
160 from_dir = (unsigned long *) ((from >> 20) & 0xffc); / * _ pg_dir = 0 * /
161 to_dir = (unsigned long *) ((to >> 20) & 0xffc); // count the number of blocks of memory occupied
162 size = ((unsigned) (size + 0x3fffff)) >> 22; // start of each page table
below occupied by sequentially copy operation.
163 for (; size -> 0; from_dir ++, to_dir ++) {// if the entry specifies the destination
directory page table exists (P = 1), is an error, crash.
164 if (1 & * to_dir)
165 panic ( ' copy_page_tables: already exist ");
// If the source directory entry is not used, then do not copy the corresponding page table, skip.
175 if (! (1 & this_page)) // If the current source page is not used, then do not copy.
176 continue;
// reset the page table entry R / W flag (set to 0). (If the U / S bit is 0, the R / W has no effect. If the U / S is 1, the R / W is 0, then it can only read page // run code
in the user layer. If the U / S and R / W are set, then there is written permission.)
an index page map array entry corresponding increase in the number of references. For located below 1MB pages, the page description // kernel, there is no need for the mem_map
[] is set. Because mem_map [] only for managing the main memory area of a page using // situation. Thus, for the core moves on to task 0 and calls fork () Create Task 1 (for running
// copy the pages are also still in the kernel code region, the following statement will not execute the judgment. Only when calling fork () // the code of the parent process in the main
memory area (page position is greater than 1MB) will be performed. This situation needs to appear in a process called execve (), // load and execute the new code.
memory zone. // If one needs to write to memory, you can write pages by abnormal protection process for the write process operation // allocate a new free page, that operate
copy-on-write.
180 * from_page_table = this_page; // make the source page table entry are also read-only.
181 this_page - = LOW_MEM ;
182 this_page >> = 12;
183 mem_map [This_page] ++;
--449--
10.4 memory.c program
184 }
185 }
186 }
187 invalidate (); // refresh the page transform cache.
188 return 0;
189 }
190 191 /
*
192 * This function puts a page in memory at the wanted address.
193 * It returns the physical address of the page gotten, 0 if
194 * Out of memory (either when trying to access page-table or
195 * Page.)
196 * /
/*
* The following function will place a page memory at the specified address. It returns the physical address of the page, if
* Not enough memory (when accessing the page table or page), 0 is returned.
*/
//// mapped to a physical memory page address to the specified linear.
// main job is to set the information specified page in the page directory and page tables. If successful, the page address is returned. // function in C do_no_page missing page abnormalities ()
will call this function. For abnormalities caused by missing pages, missing pages due to any reason and // page table modification, CPU does not need to refresh the page transformation buffer
(or called Translation Lookaside Buffer, TLB), // even if the page table entry sign P It is modified from 0 to 1. Because invalid page item will not be buffered, so when modifying an invalid page
table entries do not need to refresh //. In this was manifested as without calling Invalidate () function.
197 unsigned long put_page (Unsigned long page, unsigned long address)
198 {
199 unsigned long tmp, * page_table;
200 201 / * NOTE !!! This uses the fact that _pg_dir = 0 * /
--450--
10.4 memory.c program
entry pointer.
the low end of the original page LOW_MEM (1Mb), and a value of 1 byte in the page map of FIG array (only referenced // 1, the page is not shared), then the
page in the page entry set R / W flag (write), and refresh the page cache // transform, and then returns.
// If the page is larger than the original low-end memory (it means mem_map []> 1, the page is shared), then the original page page mapping // array value is decremented by one. Then
assign the contents of the page table entry is updated to the new page, and can read and write flag is set (U / S, R / W, P). // refresh the page transform cache. Finally, copy the original
*
* If it's in the code space, we will exit with an error message segment.
*/
//// page exception interrupt handler calls the C function. Write a shared page handler. It is called page.s program. Error_code // parameter is generated
automatically by the CPU, address is a linear address of a page. // write when sharing page, the page to be copied (copy-on-write).
--451--
10.4 memory.c program
/ * We can not do this: because estdio library performs write operations in the code space * / / * really stupid. I
252 if ( CODE_SPACE (Address)) // if the address is in the code space, execution of the program is terminated.
& 0xffc): Calculates the offset address in the page address of the page table; // (0xfffff000 & * ((address >> 20) & 0xffc)): take the address value in the
directory entry of the page table, where // ((address >> 20) & 0xffc) calculates the directory entry pointer of the page on which the page table; // two
together i.e., obtain the specified address corresponding to the page table entry pointer of the page. Here to make copies of pages that are shared.
260
//// write verification page.
// If the page is not writable, the copy page. It is called in line 34 fork.c.
261 void write_verify (Unsigned long address)
262 {
263 unsigned long page;
264
// whether the specified address corresponding to the page directory entry of the page table exists (P), if present (P = 0) is returned.
265 if (! ((page = * ((unsigned long *) ((address >> 20) & 0xffc))) & 1))
266 return;
// page table fetch address, the address specified by the page's page table entry in the page offset table to obtain the corresponding page table entry pointer of the physical page.
// and get_free_page () different. get_free_page () only apply for one page of physical memory main memory area. // function which is not only to get a
physical memory pages, further calls put_page (), map the physical page to the specified linear address // place.
English meaning is: Even if you perform get_free_page () returns 0 does not matter, because put_page () // in this case also apply for free physical page again,
--452--
10.4 memory.c program
286 * To see if it exists, and if it is clean. If so, share it with the current
287 * Task.
288 *
289 * NOTE! This assumes we have checked that p! = Current, and that they
290 * Share the same executable.
291 * /
/*
* try_to_share () in the task "p" in the address of the page to check "address" at, see page exists, it is clean.
* If it is clean, then it shared with the current task.
*
* note! Here we have assumed that p! = Current task, and they share the same execution.
*/
//// attempt at a specified address on page sharing process operation.
// also verify whether the specified address has applied for a page, if it is an error, crash. // returns 1-
success, 0 failed.
292 static int try_to_share (Unsigned long address, struct task_struct * P)
293 {
294 unsigned long from;
295 unsigned long to;
296 unsigned long from_page;
297 unsigned long to_page;
298 unsigned long phys_addr;
299
// seek page directory entry specified memory address.
300 from_page = to_page = ((address >> 20) & 0xffc); // calculate the page directory entry of
301 from_page + = ((p-> start_code >> 20) & 0xffc); // calculate the current process page
// fetch page directory entries. If the directory entry is invalid (P = 0), it is returned. Otherwise, take the directory entry corresponding page table address from.
// fetch page catalog items to. If the directory entry is invalid (P = 0), then take free pages, and the directory entry update to_page referred to.
--453--
10.4 memory.c program
// set the p-process the page write protection flag (setting R / W = 0 read-only). And the corresponding page table entry in the current process point to it.
*
* First, we verify the feasibility by detecting executable-> i_count. If there are other tasks shared
* The inode, it should be greater than 1.
*/
//// Share page. See if you can share a page in the page fault processing. // returns
1 - Successful, 0 - failed.
--454--
10.4 memory.c program
354 continue;
355 if ( current == * p) // If the current task is, but also continue to look for.
356 continue;
357 if ((* p) -> executable =! current -> executable) // If the executable range, continues.
358 continue;
359 if ( try_to_share (Address, * p)) // try to share a page.
360 return 1;
361 }
362 return 0;
363 }
364
//// page exception interrupt handling function calls. Handle exceptions missing pages. It is called page.s program. Error_code // parameter is
address. i-node structure is executable process. Value of 0 indicates that the beginning of the process is provided, // required memory; the specified address is outside the linear length
code plus data indicating the new application process memory space, but also needs to be given. // therefore a direct call get_empty_page () function, an application memory and mapped
to the specified physical address can be linear. // start_code is a process code segment address, end_data is code plus data length. For Linux kernel, its code segment and data segment
processing is performed.
--455--
10.4 memory.c program
390 tmp--;
391 * (Char *) tmp = 0;
392 }
// if the physical page is mapped to the linear address specified operation is successful, it returns. Otherwise, the release of memory pages, display memory is not enough.
// Parameters: start_mem - physical memory can be used as the starting position of the paging process (RAMDISK memory space occupied has been removed, etc.). //
// In this version of the Linux kernel, can use up to 16Mb of RAM, 16Mb of memory will not be greater than to consider, not abandoned. // 0 - 1Mb of memory
404 for (i = 0; i < PAGING_PAGES ; I ++) // First of all pages set as occupied (USED = 100) states,
405 mem_map [I] = USED ; // upcoming full-page mapping array set to USED.
406 i = MAP_NR (Start_mem); // then calculated using the number of the start page of memory.
408 end_mem >> = 12; // to calculate the number of pages that can be used for paging processing.
409 while (end_mem -> 0) // Finally, the available pages corresponding page mapping array is cleared.
--456--
10.5 page.s program
The file includes page exception interrupt handler (interrupt 14 ), Mainly deal with two cases. First, because of the lack of Page abort caused by calling do_no_page
(error_code, address) To deal with; the second is the page write page protection caused by abnormal, this time calling page write-protected handlers do_wp_page (error_code,
address) For processing. Wherein the error code ( error_code) By CPU Automatically generated and pushed onto the stack, the linear address access time of abnormality from the
control register CR2 Acquired. CR2 It is designed to store the linear address of the page fault.
1/*
2 * Linux / mm / page.s
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
* page.s underlying page that contains exception-handling code. The actual work is done in the memory.c.
*/
1112 .globl _page_fault
1314 _page_fault:
16 pushl% ecx
17 pushl% edx
18 push% ds
19 push% es
20 push% fs
twenty one movl $ 0x10,% edx # Set the kernel data segment selector.
26 pushl% edx # The linear address onto the stack and error codes as arguments to the call.
27 pushl% eax
28 testl $ 1,% eax # Test flag P, if not missing pages caused abnormal jump.
29 jne 1f
30 call _do_no_page # Call the page fault handler (mm / memory.c, 365 lines).
31 jmp 2f
32 1: call _do_wp_page # Call the write-protect handler (mm / memory.c, 247 lines).
33 2: addl $ 8,% esp # Discarding two pressure parameters onto the stack.
--457--
10.5 page.s program
34 pop% fs
35 pop% es
36 pop% ds
37 popl% edx
38 popl% ecx
39 popl% eax
40 iret
When the processor is detected during the following two conditions translate the linear address to a physical address, the page fault exception occurs, the interrupt
14 . o when CPU Found that the presence of the corresponding page directory entry or page table entry bits ( Present ) Flag 0 .
o The current process does not have access to the specified page. For interrupt exception handling page, CPU It provides two pieces of
(1) On the error code on the stack. The error code indicates the anomaly is caused because the page does not exist or access rights violated due;
When an exception occurs CPU The current privilege layer; and a read or write operation. An error code format 32 Bit long word. But only the final 3 A bit. Illustrate
the cause when an exception occurs: Bit 2 (U / S) - 0 That the implementation in Supervisor mode, 1 It represents execution in user mode; bit 1 (W / R) - 0 It
- page-level
0 She represents
protection.
the page does not exist, 1 She represents the
(2) CR2 ( Control register 2) . CPU The cause abnormal for accessing stored in linear address CR2 in. Exception handler can
Use this address to locate the corresponding page directory and page table entries. If allowed to occur during another page in the page exception handler execution
--458--
11.1 Overview
11.1 Outline
Before using the function, you should first declare the function. For ease of use, the usual practice is the same type of function or data structures and constants stated
in a header file ( header file )in. Header file may also include any relevant macro and type definitions ( macros ). Is used in the preprocessing of instructions in the source code
In a typical application source code, header and library files in the development environment are inextricably close contact with each function in the library need to be
declared in the header file. Header files application development environment (typically placed in the system / usr / include / Directory) can be seen as they provide library (for
example, libc.a A part of the function), or is an explanation of the interface library functions stated. After the compiler converts the source code into object modules, the linker ( linker )
Program will target all of the modules together, including any library files used in the module. Thereby forming an executable program.
For standard C Library in terms of its basic header files have 15 A. Each header file shows a particular type of functionality or structure definition described, e.g. I / O Manipulation
functions, processing functions and other characters. Detailed description of the standard library can be referred to Plauger Edited " The Standard C Library "This book.
For kernel source code described in this book, involving the headers can be seen as a summary description of the kernel library and services provided, and related
procedures kernel-specific header files. In the header file describes all the data structures used by the kernel, initialization data, constants, and macros defined, also include a
Kernel header files used are stored in include / Under contents. Files in that directory to see the list 11.1 Fig. It should be clear: For ease of use and compatibility, Linus Naming
standard when preparing the kernel header files used C Similar naming library header files, header files and even many names, some of which are content with the standard C Library
header files is basically the same, but the kernel headers is still the kernel source code for the kernel or with a program dedicated closely linked. in a Linux System, header files,
they co-exist with the standard library. The usual practice is to place these header files in the standard library header files in the directory under the subdirectory to let the program
In addition, because of copyright issues, Linus Trying to realign some of the header files to replace with a standard copyright restrictions C Library header files. Thus these
header files kernel source code header files and development environment where there is some overlap. in Linux System, the list 11-1
middle asm / , linux / with sys / Kernel header files in three subdirectories usually need to be copied to the standard C Library header files directory (/ usr / include ), Whereas some
other documents if there is no conflict with the standard library header files can be placed directly into the standard library header files directory, or change into three subdirectories
in here.
asm / The main directory for storing header files declare functions or data structures closely related to computer architecture. linux / Directory is Linux Some kernel header
files used by the program. and sys / The store directory 5 A resource associated with the kernel headers.
Linux 0.11 A total of kernel version 32 Header file (*. h) ,among them asm / Subdirectory contains 4 A, linux / Subdirectory contains 10 A,
sys / Subdirectory contains 5 A. From the beginning of the next section, we first describe include / Directory 13 Header file, followed by the documentation for each subdirectory.
--459--
11.3 a.out.h file
a.out.h File is not part of the standard C Libraries, kernel-specific header files. But because there is no conflict with the name of the standard library header files, so
Linux The system typically can be placed / usr / include / Directory, for the program to involve the use of relevant content. The header file defines the main binaries a.out (Assembley
out) Format. Wherein the data structure comprises three functions and macros.
From Linux 0.9x Version of the kernel start (from 0.96 Start), the system uses a direct GNU Header files a.out.h . Thus causing the Linux
0.9x Under the program can not be compiled Linux 0.1x Running on the system. Analyze the following two a.out The difference at the header files, and explains how to make 0.9x Execute
This document and GNU of a.out.h The main difference is that the file exec The first field of the structure a_magic . GNU The file name field is a_info And the field is
divided into the 3 Subdomains: Flag field ( Flags ), Machine type field ( Machine Type ) And the magic number field ( Magic Number ). Also defines a machine type
corresponding macro field N_MACHTYPE with N_FLAGS . See Fig. 11-1 Fig.
--460--
11.3 a.out.h file
Flags (00)
Machine Type (100 ie 0x64)
Magic Number (0413 namely 0x10b)
Map 11-1 Executable file header structure exec The first field a_magic ( a_info )
in Linux 0.9x System, for the use of a static library executable file attached, the value in the parentheses in FIG each domain annotations is the default value of this field.
Here the header file defines only the magic number field. Thus, in Linux 0.1x A system a.out Binary executable file format started 4 Bytes are:
As can be seen, the use of GNU of a.out Executable file format and Linux 0.1x Difference compiled executable file on the system only in the field of machine type.
Therefore, we can Linux 0.9x Up a.out Machine type field format executable file (first 3 Bytes) cleared, let it run in 0.1x System. As long as the portable executable file system calls
are already in 0.1x The system can be implemented. At the beginning of the formation Linux 0.1x When many of the root file system commands, the author adopted this approach.
GNU of a.out.h Header files and here a.out.h Header files is no different in other respects. In addition, the reference list of
// ============================= // unsigned
long a_magic // perform file magic number. Use N_MAGIC and other macro access.
// unsigned a_bss // length uninitialized data area in the file, the number of bytes.
// unsigned a_syms // the length of the symbol table file, the number of bytes.
// unsigned a_trsize // the code length of relocation information, the number of bytes.
// -----------------------------
6 struct exec {
--461--
11.3 a.out.h file
19 #endif
2021 #ifndef OMAGIC 22 / * Code indicating object file or impure executable. * /
// the history, the earliest in the PDP-11 computer, the magic number (magic number) is the octal number 0407. It is located at the beginning of the program execution head structure. // PDP-11
was originally a jump instruction, then jump to the code that represents the beginning of the word 7. In this way, the loader (loader) on
// can jump after the executable file into memory instructions directly to the beginning of the run. Now there is no program uses this approach, but this
// octal number to identify it as a file type of sign (magic number) retained. OMAGIC can be thought of Old Magic meaning.
twenty four / * Code indicating pure executable. * /
/ * Code specified as pure executable file * / // New Magic, after 1975 started. It relates to virtual memory mechanism.
--462--
11.3 a.out.h file
49 #endif
50
// offset codes relocation information.
53 #endif
54
// offset data relocation information.
55 #ifndef N_DRELOFF 56 #define N_DRELOFF ( x ) ( N_TRELOFF ( x ) + ( x ) .A_trsize)
57 #endif
58
// offset value symbol table.
61 #endif
62
// offset value character string information.
65 #endif
6667 / * Address of text segment in memory after it is loaded. * /
Note that for the following machine name is not listed, you need to define the corresponding
SEGMENT_SIZE * /
78 #ifdef hp300
79 #define PAGE_SIZE 4096
80 #endif
81 #ifdef sony
82 #define SEGMENT_SIZE 0x2000
83 #endif / * Sony. * /
84 #ifdef is68k
85 #define SEGMENT_SIZE 0x20000
86 #endif
87 #if defined (m68k) && defined (PORTAR)
88 #define PAGE_SIZE 0x400
89 #define SEGMENT_SIZE PAGE_SIZE 90 #endif
--463--
11.3 a.out.h file
--464--
11.3 a.out.h file
138 #endif
139 #ifndef N_COMM 140 #define N_COMM
18
141 #endif
142 #ifndef N_FN 143 #define N_FN
15
144 #endif
145
// The following three constants defined nlist structure mask n_type variables (eight process representation).
*
* Indirect asymmetric. Values of other symbols will be used to satisfy the request indirect symbols, but not vice versa.
* If no other symbol is not defined, the library will be searched to find a definition * /
167 All the N_SET [ATDB] symbols with the same name form one set.
168 Space is allocated for the set in the text section, and each set
169 element's value is stored into one word of the space.
170 The first word of the space is the length of the set (number of elements).
171
172 The address of the set is made into an N_SETV symbol
173 whose name is the same as the name of the set.
174 This symbol acts like a N_DATA global symbol
175 in that it can satisfy undefined external references. * /
/ * The following symbols related to the set of elements. All symbols have the same name N_SET [ATDB] of
Forming a set. In the code section it has been assigned to a collection space, and the set value of each element is stored in a space character (word) a. A
first set of word length there space (the number of sets of elements).
It is put into a set of addresses N_SETV symbol set with the same name as its name. In meeting the external reference
/ * The following symbols are used as linker LD input in the target file. * /
--465--
11.3 a.out.h file
The relocation code file is a vector part of these structures, all of which are suitable for the code portion. Similarly, the data
192
// relocation information structure.
--466--
11.3 a.out.h file
221
Linux Kernel 0.11 Supports only a.out (Assembley out) Executable file format, although this format is now gradually do, and use more feature complete ELF ( Executable
and Link Format ) Format, but because of its simplicity, as a material just getting started learning more applicable. The following comprehensive introduction a.out format.
In the header file < a.out.h> It affirmed the three data structures as well as some of the macro function. These machine code files describe the data structures (binary)
An executable file can have a total of seven sections (Section VII) components. In order, these portions are: an end effector portion ( exec header) . Execute the file header
section. This portion contains a number of parameters, these parameters are used to load the kernel executable file into memory and executed, and the linker ( ld) Using these
parameters will be some combination of binary object files into an executable file. This is the only part of the necessary.
Code segment portion ( text segment) . Containing program execution is loaded into memory so that the instruction code and associated data. It can be loaded as read-only.
Data segment portion ( data segment) . This portion contains data already initialized, it is always loaded into the read-write memory. Relocations section ( text relocations) .
This portion contains the linker used for recording data. The code segment for the positioning of the pointer or address in the binary object file combination.
Data relocation section ( data relocations) . The effect is similar relocations section, but is a relocatable data segment pointers.
Symbol table section ( simbol table) . This part also contains the data for recording linker used for cross-reference to named variables and functions (symbol)
String table section ( string table) . This portion contains the symbol corresponding to the name string. Each binaries are to perform a data structure ( exec
struct exec {
unsigned long a_midmag; // a_magic or a_info
unsigned long a_text; unsigned long
a_data; unsigned long a_bss; unsigned
long a_syms; unsigned long a_entry;
unsigned long a_trsize; unsigned long
a_drsize;};
--467--
11.3 a.out.h file
a_midmag The field containing the N_GETFLAG () , N_GETMID with N_GETMAGIC () Sub-section accessible by the link is loaded at runtime into the process address space.
Macros N_GETMID () Machine for returning an identifier ( machine-id) , Indicating a binary file that will run on any machine. N_GETMAGIC () Macro specified magic number, which
uniquely determines the difference between the binaries loaded with other documents. Field must contain one of the following values:
OMAGIC It represents code and data segments and head immediately after the execution is stored in a row. The kernel code and data segments are loaded into
read-write memory.
NMAGIC with OMAGIC Like, code and data segments and head immediately after the execution is stored in a row. However, the kernel code is loaded into a read
only memory section and load data into the code segment begins next writable memory boundaries.
ZMAGIC Kernel loads separate page from the binary executable file if necessary. Performs a header, the code and data segments are processed blocks into a
plurality of page sizes linker. Kernel code loaded when the page is read-only, and the page data segment is writable.
a_text The length field contains the value of the code segment, the number of bytes.
a_data This field contains the length of the data section, the number of bytes.
a_bss contain' bss Segments' length, with a core which is provided after the initial data segment break ( brk ). Kernel loading process
Timing, this can be written in the memory after the data segments exhibit, and initially all zero.
a_syms The symbol table contains the byte length of the value part.
a_entry After the core containing the executable file is loaded into memory, the memory address of the start of program execution.
a_trsize This field contains the code relocation table size, the number of bytes.
a_drsize This field contains the data relocation table size, the number of bytes.
in a.out.h Header file defines several macros use exec Conformance testing structure or the positioning of each execution file portion (section) the position of the offset
N_BADMAG (exec) in case a_magic Field can not be identified, a nonzero value is returned.
N_DATOFF (exec) Start position of the data segment byte offset value.
N_DRELOFF (exec) Data re-start position of the byte offset location table.
N_TRELOFF (exec) Starting position of the code byte relocation table offset.
N_SYMOFF (exec) Start position of the symbol table byte offset value.
N_STROFF (exec) Starting position of the string table byte offset value.
Relocation records having a standard format, which relocation information ( relocation_info) To describe the structure:
struct relocation_info {
int r_address;
unsigned int r_symbolnum: 24, r_pcrel: 1,
r_length: 2, r_extern: 1,
r_baserel: 1, r_jmptable: 1,
r_relative: 1, r_copy: 1;
};
--468--
11.3 a.out.h file
r_address This field contains the byte offset pointer link required program processing (editing) of. Relocations offset value is
Counted from the beginning of the code segment, the data offset value is calculated from the relocation at the beginning of the data segment. The linker will have been stored in
the offset value using the relocation records the calculated new value is added.
r_symbolnum This field contains a sequence number value in the symbol table (not a byte offset) symbol structure. After the linker is calculated absolute address
of the symbol, it is added to the address pointer being relocated. (in case r_extern Bits is 0 The situation is different, see below. )
r_pcrel If this bit is set, the linker will think is updating a pointer that use pc Addressing related parties
Type, belonging to the machine code instruction section. When using this program is run relocated pointer that addresses are implicitly added to the pointer.
r_length The pointer field contains the length of the 2 The power value: 0 Show 1 Bytes long, 1 Show 2 Bytes long, 2 Show 4 byte
long.
r_extern If the bit is set, indicating that the relocation requires an external reference; in this case must use a symbolic link address
To update the corresponding pointer. When this bit is 0 , Then relocation is "local"; the Linker pointer is updated to reflect changes in the respective segment load address, rather
than reflecting a change in symbol values (unless simultaneously provided r_baserel , See below). under these circumstances, r_symbolnum
Contents of the field is a n_type Value (see below); such field tells the linker is repositioned pointer to that segment.
r_baserel If this bit is set, then r_symbolnum Field specifies a symbol to be relocated to Global Offset Table ( Global
Offset Table) One offset value. At runtime, the global offset table is set to the offset address of a symbol.
r_jmptable If the bit is set, then r_symbolnum Field specifies a symbol to be relocated to the procedure linkage table ( Procedure
r_copy If the bit is set, the relocation record specifies a symbol, the symbol of the content is copied to r_address
designated place. The copy operation is shared by the target modules in a suitable data items completed runtime linker.
The symbol name is mapped to an address (or, more colloquially string is mapped to a value). Because the linker to adjust the name address, a symbol must be used to
indicate its address until you have been given an absolute address value. Symbol is the name of a variable length symbol table and a fixed-length string table records the
struct nlist {
union {
char * N_name;
long
n_strx;
} N_un;
unsigned char n_type;
char n_other;
short n_desc;
unsigned long n_value;
};
n_un.n_strx This name has signed byte offset in the string table. When the program uses nlist () Accessing a function symbol table, this field is replaced n_un.n_name
n_type Used to link the program to determine how to update the value of the symbol. Using a bit mask ( bitmasks) can n_type Field into
Three sub-fields, for N_EXT Type of sign bit, the program will link them as "external" symbol, and other binary object files to allow references
N_UNDF Undefined symbol. Linker must locate external symbols having the same name in the other binary object file to determine the absolute value
of the symbol data. Under special circumstances, if n_type Field is non-zero, and no two
--469--
11.4 const.h file
Binary file defines this symbol, the linker in BSS The symbol resolution is in a segment address, a length equal to retain
n_value Byte. If more than one binary symbol is not defined in the object file and the binary value of the target files are inconsistent its length, the
linker will select all files in the target binary maximum length.
N_TEXT A code symbols. The value of this symbol is the code address, the linker when combining binary object file updates its value.
N_DATA A data symbol; and N_TEXT Similarly, the data for the address. An offset value corresponding to the code and data symbols but the value is not the
address file; offset to find the file, it is necessary to determine the relevant portion of the load start address and subtracting it, and then add the offset portion.
N_BSS One BSS Symbols; data symbols and code or the like, but without a corresponding shift in the binary object file.
N_FN A file name of the symbol. When you merge binary object files, the linker will insert the symbol in binary notation before. Name of the symbol is to give the
filename linker, and its value is a binary file in the first code segment address. Symbols do not need to file name, but very useful for the transfer procedure when
N_STAB Mask transfer procedure for selecting the symbol (e.g. gdb) Bit of interest; its value stab () Explained.
n_other According to the field n_type Determining a segment, independent information about the symbols provide symbol relocation operation. Currently,
n_other Lowest field 4 Bits comprising one of two values: AUX_FUNC with AUX_OBJECT (For definition, see < link.h> ).
AUX_FUNC The symbol associated with the function call, AUX_OBJECT The symbols associated with the data, whether they are located in the data segment is a code segment.
This field is used to link the main program ld To create a dynamic executable.
n_desc Transfer procedure reserved for use; linker does not process it. The different fields as different debugger
n_value Containing the value of the symbol. For the code, data, and BSS Symbol, which is an address; for other symbols (e.g., modulation
String table is of length u_int32_t Followed by a null The end of the symbol strings. The length of the table is representative of the size, in bytes, so 32 Its minimum position
The document defines the i File attributes and types of nodes i_mode Some fields are used Flag constant symbols.
// define the buffer memory using terminal (do not use the constant code).
5
Each flag // i i_mode node data structure fields.
6 #define I_TYPE 0170000 I // specified node type.
7 #define I_DIRECTORY 0040000 // is a directory file.
8 #define I_REGULAR 0100000 // regular file, not the file or directory special file.
9 #define I_BLOCK_SPECIAL 0060000 // block device special file.
10 #define I_CHAR_SPECIAL 0020000 // character device special file.
--470--
11.5 ctype.h file
12 #define I_SET_UID_BIT 0004000 // set the effective user id type at execution time.
16
The document is the first document on character testing and treatment, as well as standard C One library header files. Which defines some judgment about the character
type and converting macros. For example, whether a character c Is a numeric character ( isdigit (c) ) Or a space ( isspace (c) ). Using an array (table) in the process (the lib / ctype.c ),
The definition of the array ASCII All of the properties and character code table. When using a macro, the character is as a table (__ ctype) Index, acquiring a byte from the table, then
9 #define _S 0x20 / * White space (space / lf / tab) * / // For whitespace characters such as spaces, \ t, \ n and so on.
10 #define _X 0x40 / * Hex digit * / // This bit is used for hexadecimal number.
11 #define _SP 0x80 / * Hard space (0x20) * / // This bit is used for a space character (0x20).
14 extern char _ctmp ; // a temporary character variable (in lib / ctype.c defined).
15
// Here are some determined character type macro.
16 #define isalnum (C) (( _ctype +1) [c] & ( _U | _L | _D )) // character or numeric [AZ], [az] or [0-9].
17 #define isalpha (C) (( _ctype +1) [c] & ( _U | _L )) // character.
18 #define iscntrl (C) (( _ctype +1) [c] & ( _C )) // is a control character.
twenty one #define islower (C) (( _ctype +1) [c] & ( _L )) // lowercase characters.
twenty two #define isprint (C) (( _ctype +1) [c] & ( _P | _U | _L | _D | _SP )) // is printable characters.
twenty three #define ispunct (C) (( _ctype +1) [c] & ( _P )) // punctuation.
twenty four #define isspace (C) (( _ctype +1) [c] & ( _S )) // blank characters such as spaces, \ f, \ n, \ r, \ t, \ v.
--471--
11.6 errno.h file
// definition of two or more, the use of macro arguments prefix (unsigned), should be added to the c-bracket, i.e. expressed as (c). // Because c may be a complex
expression in the program. For example, if the parameter is a + b, if brackets, then the macro definition @ becomes: (unsigned) a + b. This is obviously wrong. Brackets
3031 #define tolower (C) ( _ctmp = C, isupper ( _ctmp )? _ctmp - ( ' A '-' a '): _ctmp ) // into corresponding lowercase.
32 #define toupper (C) ( _ctmp = C, islower ( _ctmp )? _ctmp - ( ' a '-' A '): _ctmp ) // converted to the corresponding uppercase characters.
33 The reason more than two macro definitions // used a temporary variable _ctmp is: In macro definitions, macro parameters can only be used once.
But for multithreading // this is not safe, because two or more threads might use this public temporary variables at the same time. // therefore start from Linux 2.2.x
version changed to use two functions to replace both the macro definition.
34 #endif
35
In the standard system, or C There is a language called errno Variables regarding C Standards need for this variable, C Organization for Standardization ( X3J11 ) Caused a
lot of controversy. But the debate is not removed result errno Instead create a name " errno.h " Header files. Because standardization organizations want each library function or data
The main reason is: For each kernel system call, if the return value is the result of the value of the specified system call, then it is difficult to report error conditions. If so
that each function returns a true / false indication of value, and the results returned values separately, you can not easily get the result value of the system call. One solution is to
be a combination of these two ways: For a certain system calls, you can specify a differentiated and effective results range error return value. For example, the pointer may be
employed null Value for the pid You can return - 1 value. In many other cases, as long as the value does not conflict with the findings can be adopted - 1 To represent the error
value. But the standard C Library function return values only inform whether an error occurred, the type of error must also learn from other places, so using a errno This variable.
For standard C Library design mechanism compatible, Linux Kernel library files also adopted this approach. Therefore borrowed Standard C This header file. Relevant examples
can be found in lib / open.c Program and unistd.h The system calls the macro definition. In some cases, although the program from returning - 1 Know the value of a mistake, but
would like to know the specific error number, you can read errno The value to determine the last error error number.
Although this document only defines Linux Some of the system error code (error number) of the constant symbols, and Linus Compatibility also want to consider a
program with defined symbols POSIX Like standard. But do not underestimate this simple code, the file is SCO
The company blamed Linux Operating system infringe on the copyright of one of the documents listed. To investigate this question of infringement, the 2003 year 12 month,
10 More current Linux The kernel of the top developers on the Internet to discuss countermeasures. These include Linus , Alan Cox , HJLu , Mitchell Blank Jr . Since the current kernel
version ( 2.4.x )middle errno.h Files from 0.96c Version of the kernel unchanged in the beginning, they have been "tracking" to the old version of the kernel code. At last Linus It found
that the file is from HJLu Was maintained Libc 2.x Library using a program automatically generated, some of which include SCO Copyrighted UNIX old version( V6 , V7 Etc.) the same
variable name.
--472--
11.6 errno.h file
7 * As minix.
8 * Hopefully these are posix or something. I would not know (and posix
9 * Is not telling me - they want $$$ for their f *** ing standard).
10 *
11 * We do not use the _SIGN cludge of minix, so kernel returns must
12 * See to the sign by themselves.
13 *
14 * NOTE! Remember to change strerror () if you change this file!
15 * /
/*
* ok, because I did not get any information about the other wrong number, I can only use the minix system
* The same error number.
* Hope these are POSIX-compliant or to a certain extent is this, I do not know (and POSIX
* He did not tell me - to get their asshole standards need to pay).
*
* We did not use the minix _SIGN cluster like that, so the return value of the kernel must identify themselves sign.
*
* note! If you change the file, you have to remember to modify strerror () function.
*/
16
// system calls and library function returns a lot of special value to indicate the operation failed or wrong. This value is typically chosen @ -1 or other specific value to represent. But
this return value only error occurred. If you need to know the type of error, we need to see // variable representing the number of system error errno. The variable that is declared in
errno.h file. When the program started at the beginning of the variable value is initialized to 0 //.
--473--
11.7 fcntl.h file
5960 #endif
61
Document Control Options header file. The main definition of the function fcntl () with open () Used in some of the options.
// Here is the file creation flags to open (). Access can be used with the above embodiment mode with "bits or apos.
11 #define O_CREAT 00100 / * Not fcntl * / // If the file does not exist is created.
12 #define O_EXCL 00200 / * Not fcntl * / // Exclusive use of file flags.
13 #define O_NOCTTY 00400 / * Not fcntl * / // The control terminal is not allocated.
14 #define O_TRUNC 01000 / * Not fcntl * / // If the file already exists and is write operation, the length of the cut to zero.
15 #define O_APPEND 02000 // add to open the file pointer is set to the file.
16 #define O_NONBLOCK 04000 / * Not fcntl * / // Non-blocking open and manipulate files.
17 #define O_NDELAY O_NONBLOCK // non-blocking open and manipulate files.
--474--
11.7 fcntl.h file
twenty two * /
/ * The following defines the fcntl commands. Note that currently support the lock command has not, while the other
*/
// command file handle (descriptor) function operation the fcntl () a.
twenty three #define F_DUPFD 0 / * Dup * / // handle copy file handle to a minimum value.
twenty four #define F_GETFD 1 / * Get f_flags * / // Take the file handle flags.
25 #define F_SETFD 2 / * Set f_flags * / // Setting File Handles flag.
26 #define F_GETFL 3 / * More flags (cloexec) * / // Take the file status flags and access modes.
27 #define F_SETFL 4 // set the file status flags and access modes.
// Here is the file locking command. the fcntl () lock the third parameter is a pointer to a pointer to the flock structure.
3435 / * Ok, these are locking features, and are not implemented at any
*/
38 #define F_RDLCK 0 // read or shared file locking.
39 #define F_WRLCK 1 // exclusive or write file locking.
length of the lock (l_len) and lock embodiment of the process id.
43 struct flock {
44 short l_type; // lock type (F_RDLCK, F_WRLCK, F_UNLCK).
45 short l_whence; // start offset (SEEK_SET, SEEK_CUR or SEEK_END).
46 off_t l_start; // blocked at the start of the lock. Relative offset (number of bytes).
47 off_t l_len; // blocked Locked size; if it is 0, compared to the end of the file.
// filename parameter is the name of the file to be created, mode is a property created file (see include / sys / stat.h).
51 extern int creat (Const char * filename, mode_t mode);
// handle file operations, will affect the file open.
// parameter fildes is a file handle, cmd is the command operation, see the above line 23-30.
--475--
11.8 signal.h file
// open a file. Establish a link between the file and the file handle.
// filename parameter is the name of the file to be opened, flags is a combination of the above 7-17 mark on the line.
56
Signal provides a method for processing asynchronous events. Signal is also known as a soft interrupt. By sending a signal to a process that we can control the state of
the process (pause, continue or terminate). This document defines all the signal names and functions of the basic operations used in the kernel. The most important function is to
change the function of a specified signal processing method signal () with sigaction () .
As can be seen from this document, Linux The kernel implements POSIX.1 All required 20 Signals. So we can say that Linux
In the beginning of the design has been fully taken into account the compatibility with the standard. See specific function implementation program kernel / signal.c .
twenty two #define SIGUSR1 10 // User1 -- User signal 1, the process can be used.
--476--
11.8 signal.h file
32 #define SIGTSTP 20 // TTY Stop -- tty issued to stop the process, can be ignored.
34 #define SIGTTOU twenty two // TTY Out -- Background process request output.
3536 / * Ok, I have not implemented sigactions, but trying to keep headers POSIX * /
/ * OK, I have not implemented the preparation sigactions, but still want to honor the header file POSIX standard * /
37 #define SA_NOCLDSTOP 1 // When the child process is stopped, not for SIGCHLD process.
38 #define SA_NOMASK 0x40000000 // no longer receive the blocking signal in the specified signal processing (signal handler) in the.
39 #define SA_ONESHOT 0x80000000 // signal handler once been called to revert to the default handler.
40
// The following constants are used sigprocmask (how,) - changing the current blocking signals (mask). Used to change the behavior of the function.
44
// The following symbols are two constants function pointers point to no return value, and has an int integer parameter. Both address pointer value is a function of the value //
Logically actually not the case. The following can be used as a function of the second signal parameter. To tell the kernel, // let the kernel handle the signal processing of the
// sa_handler is a signal corresponding to the specified action to be taken. Can SIG_DFL above, or to ignore this signal SIG_IGN, // it may be a pointer to a
// sa_mask given mask on the signal, when the signal blocking program execution processing of these signals. // sa_flags specified set of signal change signal processing
procedure. It is composed of flag lines 37-39 of definition. // sa_restorer function pointer is restored, the library Libc provided, for cleaning the user mode stack. See kernel
/ signal.c // In addition, the trigger signal causes the signal processing will also be blocked, unless the SA_NOMASK flag.
48 struct sigaction {
49 void (* sa_handler) (int);
50 sigset_t sa_mask;
51 int sa_flags;
52 void (* sa_restorer) (void);
53 };
54
// The following signal function is used to install a new signal processing (signal handler) is a signal _sig, similar sigaction (). // This function contains two parameters: _sig
need to capture the specified signal; _func function pointer having a free parameter and return value. // the return value of the function also having a parameter int (last (int))
function pointers and no return value, which is the original handler processes the signal @.
signal to the current process itself. Its function is equivalent to kill (getpid (), sig).
--477--
11.9 stdarg.h file
// for shielding a process similar to the bit indicates the current blocking signal sets (set mask signal) is blocked field, it is 32, @ which each bit representing a corresponding
blocking signal. Set shielded signal modification process can block or release signal blocking specify. The following five // function is used to operate the process of masking
signal set, though simple is simple to implement, but this version of the kernel has not been achieved. // sigaddset () and sigdelset () signal set signal for add, delete modified.
sigaddset () // for pointing signal to mask the specified concentration increased signal signo. sigdelset and vice versa.
// sigemptyset () and sigfillset () sets the mask signal for the initialization process. Each set of program signals before use, require the use of one of these two
functions // mask signal set is initialized. sigemptyset () for emptying the shield all signals, i.e. the signal in response to all //. sigfillset () to signal all signals into
focus, i.e., block all signals. Of course, SIGINT and SIGSTOP are // not shield the screen.
// sigismember () is used to specify the test signal is a focus signal (1 - Yes, 0 - not, -1 - Error).
58 int sigaddset ( sigset_t * Mask, int signo);
59 int sigdelset ( sigset_t * Mask, int signo);
60 int sigemptyset ( sigset_t * Mask);
61 int sigfillset ( sigset_t * Mask);
62 int sigismember ( sigset_t * Mask, int signo); / * 1 - is, 0 - not, -1 error * /
// set the signal to be tested to see whether there is a pending signal. Return process in the set of signals currently being blocked in the set.
set pointer is not NULL, then modify the process according to the mask signal set how (41-43 lines) indicated.
the handler, the function also returns, and the signal will return to the value of the mask before the call is made.
66 int sigaction (Int sig, struct sigaction * Act, struct sigaction * Oldact);
6768 #endif / * _ SIGNAL_H * /
69
C One of the biggest features of the language is to allow the programmer number of custom variable parameter function. To access these parameters variable argument
list, you need to use stdarg.h File macro. stdarg.h Header files C According to Organization for Standardization BSD systematic varargs.h File revisions.
stdarg.h Is the standard header file parameters. It defines a variable argument list as macros. Mainly explained - types ( va_list) And three macros
(Va_start, va_arg with va_end) For vsprintf , vprintf , vfprintf function. When reading the file, you need to understand the use of variable argument function, see kernel /
1 #ifndef _STDARG_H 2 #define _STDARG_H 3 4 typedef char * va_list ; // va_list defined type is a
character pointer.
--478--
11.10 stddef.h file
/ * Here are the type of space arg list of parameters required by the TYPE.
TYPE can also be an expression of the type of use * /
8
// length in bytes of the following sentence defines the rounded value of type TYPE. Int length is a multiple of (4).
the first call to va_arg or va_end, you must first call the function.
// __builtin_saveregs on line 17 () is defined in the library program libgcc2.c gcc, for saving registers. // it // gcc manual instructions
can be found in the section "Target Description Macros" in the "Implementing the Varargs Macros" section.
12 #ifndef __sparc__
13 #define va_start (AP, LASTARG) \
14 (AP = ((char *) & (LASTARG) + __va_rounded_size (LASTARG)))
15 #else
16 #define va_start (AP, LASTARG) \
17 (__Builtin_saveregs (), \
18 AP = ((char *) & (LASTARG) + __va_rounded_size (LASTARG)))
19 #endif
20
// The following macro function is called for a complete return to normal. va_end can modify the AP that it can not be used before recall
// va_start. va_end must read all of the parameters after the va_arg is invoked.
twenty three
// The following macro expansion for the expression and to have the same value type is passed to the next parameter. // For the default value,
va_arg can use characters, unsigned char, and the floating-point type.
// use the va_arg first time, it returns the first argument of the table, each subsequent calls will return the following table // a parameter. This is the first
visit AP, and then increase it by pointing to the next item to achieve. // va_arg use TYPE to complete the access and positioning the next, each called
once va_arg, it will modify the AP to indicate that the next parameter table //.
29
stddef.h There is also the name of the header file C Organization for Standardization ( X3J11 ) Is created, meaning standard ( std )definition( def) . Mainly used to store some of
the "standard definition." Another confusing contents of the header file is stdlib.h , But also by the standards organization established. stdlib.h
Mainly used to declare some of the various other functions not related to the type of header files. But the contents of two headers which often can be confusing which affirms that
Some members of the standardization organization believe in those who can not fully support the standard C Independent environmental library, C Language should also
be a useful programming language. For a standalone environment, C Standard required to provide C All the properties of language, and for the standard C Library, this
--479--
11.11 string.h file
Kind of realized only provide support 4 Header file functions: float.h , limits.h , stdarg.h with stddef.h . This requires clear stddef.h
What content should contain files, header files and the other three for substantially more specific aspects:
stdarg.h Macros are provided for access variable argument lists definitions. And any other type of stand-alone environment or macro definition used should be placed stddef.h
File. But members of the organization later relaxed these restrictions, leading to some definitions appear in multiple header files. For example, a macro definition NULL Also appeared
in other 4 Header file. Therefore, in order to prevent conflict, stddef.h In the definition file NULL Before first use undef Instruction cancel the original definition (first 14 Row).
Types and macros defined in this document, there is one thing in common: These definitions have tried to be included in the C The characteristics of the language, but later
due to various compilers have their own ways to define these information, it is difficult to write code that can replace all of these definitions come, so give up.
// null pointer.
1617 #define offsetof ( TYPE , MEMBER) (( size_t ) & (( TYPE *) 0) -> MEMBER) // offset in the member types.
1819 #endif
20
The header file defines all the string manipulation functions in the form of built-in functions, in order to improve execution speed using inline assembler. In the standard C The
library also provides a header file of the same name, but the function is realized in the standard C Library, and the file contains only the statement of the correlation function.
--480--
11.11 string.h file
6 #endif
78 #ifndef _SIZE_T 9 #define _SIZE_T 10 typedef
unsigned int size_t ;
11 #endif
1213 extern char * strerror (Int errno );
1415 / *
* Assumed ds = es = data space, this should be routine. The vast majority string functions are carried out by a large number of manual
* Optimization, in particular function strtok, strstr, str [c] spn. They should be able to work, but it is not that
* It is easy to understand. All operations are basically used to complete the set of registers, i.e., the function which makes fast or neat.
* All places are used in string instructions, which in turn makes the code "a little" hard to understand ☺
*
* (C) 1991 Linus Torvalds
*/
26
//// a string (the src) copied to another string (dest), until it encounters a NULL character after stopping. // Parameters: dest
- pointer to a string object, src - pointer to the source string. //% 0 - esi (src),% 1 - edi (dest).
30 "1: \ tlodsb \ n \ t" // load DS: [esi] 1 byte at al, and updates esi.
31 "Stosb \ n \ t" // memory byte al ES: [edi], and updates edi.
32 "Testb %% al, %% al \ n \ t" // memory byte is just 0?
33 "Jne 1b" // instead of the backward jump to label 1, otherwise ends.
34 :: " S "( src), " D "( dest): " si "," di "," ax ");
35 return dest; // return destination string pointer.
36 }
37
--481--
11.11 string.h file
//// copy count bytes of the source string to the destination string.
// If the source is less than the string length count bytes to additional null characters (NULL) to the destination string. // Parameters:
dest - pointer to a string object, src - source string pointer, count - the number of bytes copied. //% 0 - esi (src),% 1 - edi (dest),% 2 -
ecx (count).
38 extern inline char * strncpy (Char * dest, const char * src, int count )
39 {
40 __asm __ ( " cld \ n " // clear direction bit.
48 "Stosb \ n"
49 "2:"
50 :: " S "( src), " D "( dest), " c "( count ): " si "," di "," ax "," cx ");
51 return dest; // return destination string pointer.
52 }
53
//// source string copied to the end of the destination string. // Parameters: dest - pointer to a string
object, src - pointer to the source string. //% 0 - esi (src),% 1 - edi (dest),% 2 - eax (0),% 3 - ecx
(-1).
54 extern inline char * strcat (Char * dest, const char * src)
55 {
56 __asm __ ( " cld \ n \ t " // clear direction bit.
57 "Repne \ n \ t" // al comparison and es: [edi] bytes, and the update edi ++,
58 "Scasb \ n \ t" // string until the object is found in byte 0, byte 1 at this time point is after edi.
60 "1: \ tlodsb \ n \ t" // source string of bytes taken ds: [esi] al, and esi ++.
61 "Stosb \ n \ t" // the bytes to save es: [edi], and edi ++.
62 "Testb %% al, %% al \ n \ t" // This byte is 0?
63 "Jne 1b" // not, then jumps back to 1 to continue at the label copy, otherwise ends.
64 :: " S "( src), " D "( dest), " a "( 0), " c "( 0xffffffff): " si "," di "," ax "," cx ");
65 return dest; // return destination string pointer.
66 }
67
//// copy count bytes of the source string to the end of the destination string, and finally adding a null character. // Parameters:
dest - destination string, src - the source string, count - the number of bytes to be copied. //% 0 - esi (src),% 1 - edi (dest),% 2 -
eax (0),% 3 - ecx (-1),% 4 - (count).
68 extern inline char * strncat (Char * dest, const char * src, int count )
69 {
70 __asm __ ( " cld \ n \ t " // clear direction bit.
--482--
11.11 string.h file
86 }
87
//// comparing a string to another string. // Parameters: cs - string
1, ct - 2 string.
//% 0 - eax (__ res) returns the value,% 1 - edi (cs) string pointer 1,% 2 - esi (ct) 2 string pointer. // Returns: 1 if the string> string 2,
1 is returned; string string 2 = 1, 0 is returned; string 1 <string 2, -1 is returned.
88 extern inline int strcmp (Const char * cs, const char * ct)
89 {
90 register int __res __asm __ ( " ax "); // __res a register variable (eax).
91 __asm __ ( " cld \ n " // clear direction bit.
92 "1: \ tlodsb \ n \ t" // ds 2 takes a string of bytes: [esi] al, and esi ++.
93 "Scasb \ n \ t" // al string of bytes es 1: [edi] compared, and edi ++.
94 "Jne 2f \ n \ t" // If not equal, then jump to the label 2 forward.
95 "Testb %% al, %% al \ n \ t" // The byte value is 0 bytes it (end of the string)?
96 "Jne 1b \ n \ t" // not, then jump back to number 1, the comparison continues.
97 "Xorl %% eax, %% eax \ n \ t" // Yes, the return value is cleared eax,
101 "Negl %% eax \ n" // otherwise eax = -eax, returns a negative value, end.
102 "3:"
103 : "= a "(__ res): " D "( cs), " S "( ct): " si "," di ");
104 return __res; // returns the result of the comparison.
105 }
106
//// string 1 is compared with the first count characters of the string 2. // Parameters: cs - string 1, ct - 2, count
//% 0 - eax (__ res) returns the value,% 1 - edi (cs) string pointer 1,% 2 - esi (ct) string pointer 2,% 3 - ecx (count). // Returns: 1 if the string> string 2, 1
is returned; string string 2 = 1, 0 is returned; string 1 <string 2, -1 is returned.
107 extern inline int strncmp (Const char * cs, const char * ct, int count )
108 {
109 register int __res __asm __ ( " ax "); // __res a register variable (eax).
110 __asm __ ( " cld \ n " // clear direction bit.
113 "Lodsb \ n \ t" // get a string of characters ds 2: [esi] al, and esi ++.
114 "Scasb \ n \ t" // character string and comparing al es 1 is: [edi], and edi ++.
115 "Jne 3f \ n \ t" // If not equal, then jump forward to numeral 3.
116 "Testb %% al, %% al \ n \ t" // The characters are NULL characters?
117 "Jne 1b \ n" // not, then jump back to number 1, the comparison continues.
118 "2: \ txorl %% eax, %% eax \ n \ t" // is NULL character, eax cleared (return value).
119 "Jmp 4f \ n" 4 // jump to the label forward end.
120 "3: \ tmovl $ 1, %% eax \ n \ t" // eax in the set.
121 "Jl 4f \ n \ t" // If the previous comparison character string 2 <2 character string, returns an end.
122 "Negl %% eax \ n" // otherwise eax = -eax, returns a negative value, end.
123 "4:"
124 : "= a "(__ res): " D "( cs), " S "( ct), " c "( count ): " si "," di "," cx ");
125 return __res; // returns the result of the comparison.
--483--
11.11 string.h file
126 }
127
//// first match for the characters in the string. // Parameters: s -
the string, c - To find the characters.
//% 0 - eax (__ res),% 1 - esi (string pointer s),% 2 - eax (character c).
// Returns: pointer to string matching character first appears once. If the characters match is not found, a null pointer is returned.
132 "Movb %% al, %% ah \ n" // will want to compare the characters move ah.
133 "1: \ tlodsb \ n \ t" // get the character string ds: [esi] al, and esi ++.
134 "Cmpb %% ah, %% al \ n \ t" // al character string is compared with the specified character ah.
138 "Movl $ 1,% 1 \ n" // yes, then the match is not found character, esi set.
139 "2: \ tmovl% 1,% 0 \ n \ t" After // points to match a character byte pointer value is placed into the eax
140 "Decl% 0" // the pointer to point adjusted to match the character.
141 : "= a "(__ res): " S "( s), "" (c): " si ");
142 return __res; // Return pointer.
143 }
144
//// looking for a place specified character string last occurrence. (Reverse search string) // Parameters: s - the
string, c - To find the characters.
//% 0 - edx (__ res),% 1 - edx (0),% 2 - esi (string pointer s),% 3 - eax (character c). // Returns: pointer to string matching character last
appeared. If the characters match is not found, a null pointer is returned.
145 extern inline char * strrchr (Const char * s, char c)
146 {
147 register char * __res __asm __ ( " dx "); // __ res is the register variable (edx).
148 __asm __ ( " cld \ n \ t " // clear direction bit.
149 "Movb %% al, %% ah \ n" // will want to look for the character to move ah.
150 "1: \ tlodsb \ n \ t" // get the character string ds: [esi] al, and esi ++.
151 "Cmpb %% ah, %% al \ n \ t" // string of characters with a specified character ah al compare.
154 "Decl% 0 \ n" // pointer back one, pointing to the string matches the character.
155 "2: \ ttestb %% al, %% al \ n \ t" // comparison character is 0 right (to the end of the string)?
156 "Jne 1b" // instead of the backward jump to number 1, the comparison continues.
157 : "= d "(__ res): "" (0), " S "( s), " a "( c): " ax "," si ");
158 return __res; // Return pointer.
159 }
160
//// Looking first character string in a sequence, any sequence of characters in the character string are included in 2. // Parameters: cs
- 1 string pointer, ct - 2 string pointer.
//% 0 - esi (__ res),% 1 - eax (0),% 2 - ecx (-1),% 3 - esi (a string pointer cs),% 4 - (2 string pointer ct). // Returns a string length value comprise any
sequence of characters in the first character string 2.
161 extern inline int strspn (Const char * cs, const char * ct)
162 {
163 register char * __res __asm __ ( " si "); // __ res is the register variable (esi).
164 __asm __ ( " cld \ n \ t " // clear direction bit.
165 "Movl% 4, %% edi \ n \ t" // first string length 2 is calculated. 2 edi pointer into the string.
166 "Repne \ n \ t" // Comparative al (0) 2 and the string of characters (es: [edi]), and edi ++.
--484--
11.11 string.h file
167 "Scasb \ n \ t" // if not equal, the comparison continues (ecx gradually decreasing).
170 "Movl %% ecx, %% edx \ n" // the length value into the string 2 is temporarily in edx.
171 "1: \ tlodsb \ n \ t" Character string 1 // Take ds: [esi] al, and esi ++.
172 "Testb %% al, %% al \ n \ t" // The character is equal to zero the value of it (end of string 1)?
176 "Repne \ n \ t" @ 2 Comparative al character string and es: [edi], and edi ++.
177 "Scasb \ n \ t" // if not equal comparison continues.
178 "Je 1b \ n" // If they are equal, then the backward jump to a label.
179 "2: \ tdecl% 0" // esi--, points to the last 2 contained in the character string.
180 : "= S "(__ res): " a "( 0), " c "( 0xffffffff), "" (cs), " g "( ct)
181 : " ax "," cx "," dx "," di ");
182 return __res-cs; // returns the length of the character sequences.
183 }
184
//// find the first sequence of characters in a string 1 2 does not contain any character string. //
Parameters: cs - 1 string pointer, ct - 2 string pointer.
//% 0 - esi (__ res),% 1 - eax (0),% 2 - ecx (-1),% 3 - esi (a string pointer cs),% 4 - (2 string pointer ct). // Returns a string length value does not contain any
sequence of characters the first two characters in the string.
185 extern inline int strcspn (Const char * cs, const char * ct)
186 {
187 register char * __res __asm __ ( " si "); // __ res is the register variable (esi).
188 __asm __ ( " cld \ n \ t " // clear direction bit.
189 "Movl% 4, %% edi \ n \ t" // first string length 2 is calculated. 2 edi pointer into the string.
190 "Repne \ n \ t" // Comparative al (0) 2 and the string of characters (es: [edi]), and edi ++.
191 "Scasb \ n \ t" // if not equal, the comparison continues (ecx gradually decreasing).
194 "Movl %% ecx, %% edx \ n" // the length value into the string 2 is temporarily in edx.
195 "1: \ tlodsb \ n \ t" Character string 1 // Take ds: [esi] al, and esi ++.
196 "Testb %% al, %% al \ n \ t" // The character is equal to zero the value of it (end of string 1)?
200 "Repne \ n \ t" @ 2 Comparative al character string and es: [edi], and edi ++.
201 "Scasb \ n \ t" // if not equal comparison continues.
202 "Jne 1b \ n" // If not equal, then the backward jump to a label.
203 "2: \ tdecl% 0" // esi--, points to the last 2 contained in the character string.
204 : "= S "(__ res): " a "( 0), " c "( 0xffffffff), "" (cs), " g "( ct)
205 : " ax "," cx "," dx "," di ");
206 return __res-cs; // returns the length of the character sequences.
207 }
208
//// find any characters included in the first string 2 in string 1. // Parameters: cs -
pointer to a string of 1, ct - 2 pointer to a string.
//% 0 -esi (__ res),% 1 -eax (0),% 2 -ecx (0xffffffff),% 3 -esi (a string pointer cs),% 4 - (2 string pointer ct). // Returns a string pointer 2 contains
the string of characters.
209 extern inline char * strpbrk (Const char * cs, const char * ct)
210 {
211 register char * __res __asm __ ( " si "); // __ res is the register variable (esi).
--485--
11.11 string.h file
213 "Movl% 4, %% edi \ n \ t" // first string length 2 is calculated. 2 edi pointer into the string.
214 "Repne \ n \ t" // Comparative al (0) 2 and the string of characters (es: [edi]), and edi ++.
215 "Scasb \ n \ t" // if not equal, the comparison continues (ecx gradually decreasing).
218 "Movl %% ecx, %% edx \ n" // the length value into the string 2 is temporarily in edx.
219 "1: \ tlodsb \ n \ t" Character string 1 // Take ds: [esi] al, and esi ++.
220 "Testb %% al, %% al \ n \ t" // The character is equal to zero the value of it (end of string 1)?
224 "Repne \ n \ t" @ 2 Comparative al character string and es: [edi], and edi ++.
225 "Scasb \ n \ t" // if not equal comparison continues.
226 "Jne 1b \ n \ t" // If not equal, then the backward jump to a label.
227 "Decl% 0 \ n \ t" // esi--, points contained in a 2-character string.
228 "Jmp 3f \ n" // forward jump to number 3.
229 "2: \ txorl% 0,% 0 \ n" // not found qualified, the return value is NULL.
230 "3:"
231 : "= S "(__ res): " a "( 0), " c "( 0xffffffff), "" (cs), " g "( ct)
232 : " ax "," cx "," dx "," di ");
233 return __res; // returns the pointer value.
234 }
235
//// find the first match the entire string string 2 in string 1. // Parameters: cs -
pointer to a string of 1, ct - 2 pointer to a string.
//% 0 -eax (__ res),% 1 -eax (0),% 2 -ecx (0xffffffff),% 3 -esi (a string pointer cs),% 4 - (2 string pointer ct). // Return: Returns a string in a string
matching string pointer 2.
236 extern inline char * strstr (Const char * cs, const char * ct)
237 {
238 register char * __res __asm __ ( " ax "); // __ res is the register variable (eax).
239 __asm __ ( " cld \ n \ t "\ // clear direction bit.
240 "Movl% 4, %% edi \ n \ t" // first string length 2 is calculated. 2 edi pointer into the string.
241 "Repne \ n \ t" // Comparative al (0) 2 and the string of characters (es: [edi]), and edi ++.
242 "Scasb \ n \ t" // if not equal, the comparison continues (ecx gradually decreasing).
245 "Movl %% ecx, %% edx \ n" // the length value into the string 2 is temporarily in edx.
246 "1: \ tmovl% 4, %% edi \ n \ t" // pointer to take into two series of edi.
247 "Movl %% esi, %% eax \ n \ t" // pointer to the string 1 replication in eax.
248 "Movl %% edx, %% ecx \ n \ t" // string length value of 2 and then placed in ecx.
249 "Repe \ n \ t" // string comparison of 1 and 2 character string (ds: [esi], es: [edi]), esi ++, edi ++.
250 "Cmpsb \ n \ t" // if the corresponding equal character has been relatively down.
251 "Je 2f \ n \ t" / * Also works for empty string, see above * /
/ * Also valid for empty string, see above * / // if equal full, go to reference numeral 2.
252 "Xchgl %% eax, %% esi \ n \ t" // pointer to a string esi, a string pointer eax comparison result.
253 "Incl %% esi \ n \ t" // string of a pointer to the next character.
254 "Cmpb $ 0, -1 (%% eax) \ n \ t" 1 // string pointer (eax-1) referred to byte 0?
255 "Jne 1b \ n \ t" // not jump to the label 1, the sequence continues to start comparing the second letter of 1.
256 "Xorl %% eax, %% eax \ n \ t" // clear eax, indicating no match is found.
257 "2:"
258 : "= a "(__ res): "" (0), " c "( 0xffffffff), " S "( cs), " g "( ct)
--486--
11.11 string.h file
261 }
262
//// string length is calculated. //
Parameters: s - string.
//% 0 - ecx (__ res),% 1 - edi (string pointer s),% 2 - eax (0),% 3 - ecx (0xffffffff). // Return: Returns the length of the string.
267 "Repne \ n \ t" // al (0) and the string of characters es: [edi] comparison,
271 : "= c "(__ res): " D "( s), " a "( 0), "" (0xffffffff): " di ");
272 return __res; // returns the string length value.
273 }
274 275 extern char * ___strtok ;
// temporary storage point for analysis of the following string pointer is 1 (s) of.
276
//// 2 using string character string is divided into a flag (tokern) sequence.
// The string 1 viewed as comprising a sequence of zero or more words (token), and separated by a delimiter character string of 2 or more characters. // When
the first call strtok (), returns a pointer to the string 1 of the first character of the first pointer token, and the token // return a null character to the delimiter.
Subsequent use null string as the caller 1, the string 1 will continue scanning in this way, until no // token so far. In various call processes, the division string 2
may be different. // Parameters: s - string to be processed 1, ct - each string 2 comprises a delimiter. @ Assembler output:% 0 - ebx (__ res),% 1 - esi (__ strtok);
@ Assembling the input:% 2 - ebx (__ strtok),% 3 - esi (pointer to a string of 1 s),% 4 - (2 string pointer ct). // Return: Returns a string
s in the first token, if the token is not found, a null pointer is returned. // string s subsequent call null pointer, the search for a next
token in the original string s.
277 extern inline char * strtok (Char * s, const char * ct)
278 {
279 register char * __res __asm __ ( " si ");
280 __asm __ ( " testl% 1,% 1 \ n \ t " // first test ESI (pointer to a string of 1 s) whether it is NULL.
281 "Jne 1f \ n \ t" // If not, the show is the first call of this function, jump label 1.
282 "Testl% 0,% 0 \ n \ t" // If it is NULL, it means that this is a follow-up call, test ebx (__ strtok).
283 "Je 8f \ n \ t" // If ebx pointer is NULL, the handle can not jump over.
284 "Movl% 0,% 1 \ n" // pointer to copy ebx esi.
285 "1: \ txorl% 0,% 0 \ n \ t" // clear ebx pointer.
286 "Movl $ -1, %% ecx \ n \ t" // set ecx = 0xffffffff.
287 "Xorl %% eax, %% eax \ n \ t" // clear eax.
288 "Cld \ n \ t" // clear direction bit.
289 "Movl% 4, %% edi \ n \ t" // length of the string below 2 requirements. edi points to string 2.
290 "Repne \ n \ t" The // al (0) and es: [edi] Comparative, and edi ++.
291 "Scasb \ n \ t" // null characters until you find the end of string 2, or count ecx == 0.
292 "Notl %% ecx \ n \ t" // will ecx negated,
293 "Decl %% ecx \ n \ t" // ecx--, to obtain the length of the string value of 2.
295 "Movl %% ecx, %% edx \ n" // The length of the string 2 temporarily stores edx.
296 "2: \ tlodsb \ n \ t" // get a string of characters ds 1: [esi] al, and esi ++.
--487--
11.11 string.h file
297 "Testb %% al, %% al \ n \ t" // The character is 0 the value of it (string 1 end)?
301 "Repne \ n \ t" // comparing all characters in the character string in a string al. 2,
303 "Je 2b \ n \ t" // If we can find the same character (delimiter) in the string 2, reference numeral 2 jump.
304 "Decl% 1 \ n \ t" // If not delimiter, a string pointer esi points to the character at that time.
310 "Je 5f \ n \ t" // If, represents the end of a string, a jump to the label 5.
315 "Jne 3b \ n \ t" // If the jump label delimiter is 3, 1 is detected in the next character string.
316 "Decl% 1 \ n \ t" // If the delimiter, esi--, pointing to the delimiter character.
317 "Cmpb $ 0, (% 1) \ n \ t" // The delimiter is NULL characters?
318 "Je 5f \ n \ t" // If so, then jump to the label 5.
319 "Movb $ 0, (% 1) \ n \ t" // If not, then the delimiter character replaced with NULL.
320 "Incl% 1 \ n \ t" 1 // esi points to the next character string, the first string that is remaining.
dest - copy destination address, src - copy source address, n - the number of bytes copied. //% 0 - ecx (n),% 1 - esi
336 extern inline void * memcpy (Void * dest, const void * src, int n)
337 {
338 __asm __ ( " cld \ n \ t " // clear direction bit.
344 }
345
//// memory block move. Copying the same block of memory, but considering the direction of movement.
--488--
11.11 string.h file
// Parameters: dest - copy destination address, src - copy source address, n - the number of bytes copied. // If
dest <src is:% 0 - ecx (n),% 1 - esi (src),% 2 - edi (dest). // Otherwise:% 0 - ecx (n),% 1 - esi (src + n-1),% 2 -
edi (dest + n-1). // this operation is to prevent overlapping coverage mistake when copying.
346 extern inline void * memmove (Void * dest, const void * src, int n)
347 {
348 if (dest <src)
349 __asm __ ( " cld \ n \ t " // clear direction bit.
350 "Rep \ n \ t" From @ ds: [esi] to es: [edi], and esi ++, edi ++,
351 "Movsb" // Repeat copy ecx bytes.
352 :: " c "( n), " S "( src), " D "( dest)
353 : " cx "," si "," di ");
354 else
355 __asm __ ( " std \ n \ t " // direction bit is set to start from the end of copying.
356 "Rep \ n \ t" From @ ds: [esi] to es: [edi], and esi -, edi--,
357 "Movsb" // copy ecx bytes.
358 :: " c "( n), " S "( src + n-1), " D "( dest + n-1)
359 : " cx "," si "," di ");
360 return dest;
361 }
362
//// comparison of two n bytes of memory (two strings), even if the case is not stopped NULL byte comparison. // Parameters: cs - 1 memory block address, ct - 2
memory block address, count - the number of bytes to be compared. //% 0 - eax (__ res),% 1 - eax (0),% 2 - edi (memory block 1),% 3 - esi (memory block 2),% 4 -
ecx (count). // Returns: If the block 1> 2 return to block 1; 1 block <block 2, returns -1; Block 2 Block 1 == 0 is returned.
363 extern inline int memcmp (Const void * cs, const void * ct, int count )
364 {
365 register int __res __asm __ ( " ax "); // __res is register variables.
366 __asm __ ( " cld \ n \ t " // clear direction bit.
377 }
378
//// Looking at memory blocks specified character (string) n byte size.
// Parameters: cs - Specifies the address of the memory block, c - the specified character, count - memory block length. //% 0 - edi (__ res),% 1 - eax
(character c),% 2 - edi (memory block address cs),% 3 - ecx (bytes count). // returns a pointer to the first character matched, if not found, NULL character is
returned.
379 extern inline void * memchr (Const void * cs, char c, int count )
380 {
381 register void * __res __asm __ ( " di "); // __ res is the register variable.
382 if (! count ) // If the memory block length == 0, the process returns NULL, not found.
--489--
11.12 termios.h file
393 }
394
//// Fill with specified character memory block length.
// fill memory area pointed to by s with character c, co-fill count bytes. //% 0 - eax (character c),% 1 - edi
(memory addresses),% 2 - ecx (bytes count).
395 extern inline void * memset (Void * s, char c, int count )
396 {
397 __asm __ ( " cld \ n \ t " // clear direction bit.
399 "Stosb" // characters into the al es: [edi], and edi ++.
400 :: " a "( c), " D "( s), " c "( count )
401 : " cx "," di ");
402 return s;
403 }
404 405 #endif
406
This file contains terminal I / O Interface definition. include termios Some data structures and function prototypes for the general terminal interface settings. These functions
are used to read or set the terminal attributes, line control, set the baud rate and read or read or set the front end of the terminal process group id . Although this is linux The early
header files, but it has been in full compliance with the current POSIX Standard, and made the appropriate extension.
Two terminal data structure defined in this document termio with termios Respectively in two categories UNIX Series (or carved Long), termio
It is in AT & T system V Defined, and termios Yes POSIX Standard specified. Two structure is basically the same, just termio Using the short integer type definition mode flag is set,
and termios With a length of custom mode flag set. Due to the current two structures are in use, so for compatibility, most systems are at the same time support them. In addition,
/ * 0x54 just a magic number, the purpose is to make these unique constants ( 'T') * /
--490--
11.12 termios.h file
7
// tty device ioctl call command set. The ioctl command encoding in the low word. // the following name TC [*]
// get information of the corresponding terminal termios structure (see tcgetattr ()).
affect the output, we need to use this form (see tcsetattr (), TCSADRAIN option).
will affect the output, we need to use this form (see tcsetattr (), TCSADRAIN option).
output queue; if is 2, the refresh input and output queues (see tcflush ()).
--491--
11.12 termios.h file
36 struct winsize {
37 unsigned short ws_row; The number of lines of characters // window.
44 struct termio {
45 unsigned short c_iflag; / * Input mode flags * / // input mode flag.
46 unsigned short c_oflag; / * Output mode flags * / // output mode flag.
47 unsigned short c_cflag; / * Control mode flags * / // control mode flag.
48 unsigned short c_lflag; / * Local mode flags * / // local mode flag.
49 unsigned char c_line; / * Line discipline * / // line discipline (rate).
50 unsigned char c_cc [ NCC ]; / * Control characters * / // control character array.
51 };
52
// termios structure of POSIX.
53 #define NCCS 17 // termios control structure length character array.
54 struct termios {
55 unsigned long c_iflag; / * Input mode flags * / // input mode flag.
56 unsigned long c_oflag; / * Output mode flags * / // output mode flag.
57 unsigned long c_cflag; / * Control mode flags * / // control mode flag.
58 unsigned long c_lflag; / * Local mode flags * / // local mode flag.
59 unsigned char c_line; / * Line discipline * / // line discipline (rate).
60 unsigned char c_cc [ NCCS ]; / * Control characters * / // control character array.
61 };
6263 / * C_cc characters * /
/ * C_cc array of characters * /
// The following is an index value corresponding to c_cc array of characters.
--492--
11.12 termios.h file
68 #define VEOF 4 // c_cc [VEOF] = EOF (^ D), \ 004, end of file character.
69 #define VTIME 5 // c_cc [VTIME] = TIME (\ 0), \ 0, a timer value (see later description).
70 #define VMIN 6 // c_cc [VMIN] = MIN (\ 1), \ 1, the timer value.
71 #define VSWTC 7 // c_cc [VSWTC] = SWTC (\ 0), \ 0, switching characters.
72 #define VSTART 8 // c_cc [VSTART] = START (^ Q), \ 021, beginning characters.
78 #define VWERASE 14 // c_cc [VWERASE] = WERASE (^ W), \ 027, the word erase characters.
79 #define VLNEXT 15 // c_cc [VLNEXT] = LNEXT (^ V), \ 026, the next line of characters.
93 #define IXON 0002000 // allowed to start / stop (XON / XOFF) control output.
94 #define IXANY 0004000 // allows any character to restart output.
95 #define IXOFF 0010000 // allowed to start / stop (XON / XOFF) control input.
96 #define IMAXBEL 0020000 // enter the ring when the queue is full.
100 #define OLCUC 0000002 // When the output lowercase characters to uppercase characters.
101 #define ONLCR 0000004 // the line breaks in the output is mapped to the transport NL - linefeed CR-NL.
102 #define OCRNL 0000010 // the output carriage return linefeed CR mapped to NL.
105 #define OFILL 0000100 // delay when using padding characters without time delay.
106 #define OFDEL 0000200 // fill character is ASCII code DEL. If not set, use ASCII NULL.
107 #define NLDLY 0000400 // Select Wrap delay.
108 #define NL0 0000000 // Wrap delay type 0.
109 #define NL1 0000400 // Wrap delay type 1.
110 #define CRDLY 0003000 // Choose Enter delay.
111 #define CR0 0000000 // Enter delay type 0.
112 #define CR1 0001000 // Enter delay type 1.
113 #define CR2 0002000 // Enter delay type 2.
114 #define CR3 0003000 // Enter delayed type 3.
115 #define TABDLY 0014000 // Select horizontal tab delay.
116 #define TAB0 0000000 // horizontal tab delay type 0.
117 #define TAB1 0004000 // horizontal tab delay type 1.
--493--
11.12 termios.h file
158 #define CPARENB 0000400 // turn generates output parity, parity input.
159 #define CPARODD 0001000 // Input / Output parity is odd.
160 #define HUPCL 0002000 // hang up after the last process closes.
--494--
11.12 termios.h file
// constant symbol termios structure c_lflag the local mode flag field.
169 #define ISIG 0000001 // When the character is received INTR, QUIT, SUSP or DSUSP, generate respective signals.
171 #define XCASE 0000004 // if set ICANON, the terminal is uppercase characters.
172 #define ECHO 0000010 // Echo input characters.
173 #define ECHOE 0000020 // if set ICANON, the ERASE / WERASE will erase the previous character / word.
174 #define ECHOK 0000040 // if set ICANON, the KILL character erases the current line.
175 #define ECHONL 0000100 // such as setting up ICANON, even if ECHO is not open also echo the NL character.
176 #define NOFLSH 0000200 // when generating SIGQUIT SIGINT signal and input output queue is not refreshed, when // SIGSUSP
177 #define TOSTOP 0000400 // SIGTTOU signal is sent to the background process group, which // background process attempts to write their own
control terminal.
178 #define ECHOCTL 0001000 // If set ECHO, in addition to the ASCII TAB, NL, START and STOP control signals to be the // echo
179 #define ECHOPRT 0002000 // if set ICANON and IECHO, the characters will be displayed when erasing.
180 #define ECHOKE 0004000 // if set ICANON, the KILL is significant back by erasing all characters on the line.
181 #define FLUSHO 0010000 // output is refreshed. By typing the DISCARD character, the flag is reversed.
182 #define PENDIN 0040000 // When the next character is read, all the characters in the input queue is redisplayed.
183 #define IEXTEN 0100000 // open the input processing defined at implementation.
201 #define TCIOFF 2 // a STOP character transmission system, the device stops transmission of data to the system.
202 #define TCION 3 // transmission system a START character, the device starts data transmission to the system.
203 204 / * Tcflush () and TCFLSH use these * / / * drained tcflush () and constants TCFLSH use these symbols * /
205 #define TCIFLUSH 0 // clear the data received but not read.
206 #define TCOFLUSH 1 // clear the data has been written but not transmitted.
207 #define TCIOFLUSH 2 // clear the data received but not read. Clear data has been written but not transmitted.
--495--
11.12 termios.h file
216 extern speed_t cfgetispeed (Struct termios * Termios_p); // return transmission baud
termios_p referred termios structure.
217 extern speed_t cfgetospeed (Struct termios * Termios_p); // the termios_p termios structure
referred receiver baud rate is set to speed.
218 extern int cfsetispeed (Struct termios * Termios_p, speed_t speed);
// Send baud termios_p referred termios structure to speed.
219 extern int cfsetospeed (Struct termios * Termios_p, speed_t speed);
// Wait fildes referent has been written output data is sent out.
220 extern int tcdrain (Int fildes);
// suspend / restart fildes referred to receive and transmit object data.
223 extern int tcgetattr (Int fildes, struct termios * Termios_p); // if the terminal using asynchronous serial data transmission, the continuous
229
In the non-canonical mode input process, the input character is not processed in rows, so the erase process is terminated, and will not occur. MIN with
TIMEDE I.e. values for determining how to handle the received characters.
MIN Represents a read operation when satisfied (i.e., when the character is returned to the user) minimum number of characters to be read. TIME It is 1/10 Sec count timer
values, timeout for the timing of data transmission and short-term. Four combinations of the two characters and their interactions are described below:
MIN> 0 , TIME> 0 Situation: in this case, TIME Since timer interaction between the two characters, and the reception of the first 1 It comes into play after the characters.
Because it is a timer between two characters, so restart each receive a character will be reset. MIN versus TIME The interaction between as follows: Upon receipt of an
inter-character character timer starts working. If the timer expires (note that each receive a character timer will start counting again) before receiving a MIN Characters, i.e., the
read operation is satisfied. If the MIN Characters are received before the timer expires, it will be received by the character this time returned to the user. Note that if TIME Timeout,
then at least there is a received character will be returned because the timer only after receiving a character comes into play (timing). under these circumstances( MIN> 0 , TIME>
0) , A read operation will sleep until the receipt of the first 1 Characters activate MIN versus TIME mechanism. If you read the number of characters is less than the existing number
of characters, then the timer will not be re-activated, and thus the subsequent read will be satisfied immediately.
MIN> 0 , TIME = 0 Case: in this case, since the TIME Values are 0 Therefore timer does not work, only MIN It makes sense. Waiting for a read operation only when
receiving the MIN Will be met (waiting time character of the operation will sleep until you receive MIN Characters). Using this case based on the record of the terminal to read IO
--496--
11.13 time.h file
In this case, since the MIN = 0 ,then TIME No longer play the role of inter-character timer, but a read operation of the timer, and the read operation beginning work. As
long as a character is received or the timer expires already satisfy the read operation. Note that in this case, if the timer expires, will not read a character. If the timer has not
timed out, then only read operations will meet after reading a character. Therefore, in this case, the reading will not indefinitely (indefinitely) is blocked to wait for the
character. After the read operation begins, if TIME * 0.10 Character is not received within seconds, a read operation will receive 0 Characters to return.
Generally speaking, in the non-canonical mode, two values are character timeout timer value and the count value. MIN That in order to satisfy the read operation, the
minimum number of characters to be read. TIME It is a tenth of a second timer count value. When both are set, the read operation will wait until it reads at least one character,
and then to read MIN Characters or the time TIME Out after reading the last character. If you set only MIN Then read MIN Read will not return before the characters. If you set only TIME
, The read returns immediately after reading at least one character, or when the timer expires. If both are not set, the read will return immediately, only gives the number of bytes
The header file for functions involving the processing time. in MINIX There are some very interesting description of the time: The processing time for more complex, such as
what is GMT (GMT), local time, or other time. Although Bishop Ussher (1581-1656 Years) has calculated that, according to Scripture, is the beginning of World Day BC 4004 year 10 month
GMT 1970 year 1 month 1 Midnight onwards, and before that, all are empty and (invalid).
// GMT from the beginning of January 1, 1970 to count time in seconds (calendar time).
7 #endif
89 #ifndef _SIZE_T 10 #define _SIZE_T 11 typedef
unsigned int size_t ;
12 #endif
1314 #define CLOCKS_PER_SEC 100
// frequency system clock tick, 100HZ.
1516 typedef long clock_t ;
// ticks from the beginning of the process through the system clock.
--497--
11.14 unistd.h file
1718 struct tm {
28 };
29
// The following function prototype is about time operation.
// determine the processor time. The time to return to the program processor (ticks) by approximation.
39 size_t strftime (Char * s, size_t smax, const char * fmt, const struct tm * Tp); // initialize time conversion information, the environment variable TZ,
for zname variables are initialized. // associated with the time zone at the time of the conversion function will be called automatically.
43
Standard symbol type header file and constants. This document defines a number of constants and a wide variety of types, and some function stated. If the symbol is
defined in the program __ LIBRARY__ , It also includes the kernel system call number and inline assembly _ syscall0 () Wait.
--498--
11.14 unistd.h file
1 #ifndef _UNISTD_H 2 #define _UNISTD_H 3 4 / * Ok, this may be a joke, but I'm
working on it * /
19 #endif
2021 / * Access * /
/ * File access * /
// The following symbolic constants defined for access () function.
30 #define SEEK_END 2 // read the file pointer for the file setting plus an offset length.
3132 / * _SC stands for System Configuration. We do not use them much * /
--499--
11.14 unistd.h file
/ * More (possible) configurable parameter - is now a path name * / // constants for the
50 #define _PC_VDISABLE 8 //
51 #define _PC_CHOWN_RESTRICTED 9 // change the host is limited.
54 #include <sys / times.h> // define the structure of the process of running time tms and times () function prototype.
// The following system call kernel implementation symbolic constant, the index value is used as a system call function table. (See include / linux /
sys.h)
61 #define __NR_exit 1
62 #define __NR_fork 2
63 #define __NR_read 3
64 #define __NR_write 4
65 #define __NR_open 5
66 #define __NR_close 6
67 #define __NR_waitpid 7
68 #define __NR_creat 8
69 #define __NR_link 9
70 #define __NR_unlink 10
71 #define __NR_execve 11
72 #define __NR_chdir 12
73 #define __NR_time 13
74 #define __NR_mknod 14
75 #define __NR_chmod 15
76 #define __NR_chown 16
77 #define __NR_break 17
78 #define __NR_stat 18
79 #define __NR_lseek 19
80 #define __NR_getpid 20
81 #define __NR_mount twenty one
85 #define __NR_stime 25
86 #define __NR_ptrace 26
87 #define __NR_alarm 27
88 #define __NR_fstat 28
89 #define __NR_pause 29
90 #define __NR_utime 30
--500--
11.14 unistd.h file
91 #define __NR_stty 31
92 #define __NR_gtty 32
93 #define __NR_access 33
94 #define __NR_nice 34
95 #define __NR_ftime 35
96 #define __NR_sync 36
97 #define __NR_kill 37
98 #define __NR_rename 38
99 #define __NR_mkdir 39
100 #define __NR_rmdir 40
101 #define __NR_dup 41
102 #define __NR_pipe 42
103 #define __NR_times 43
104 #define __NR_prof 44
105 #define __NR_brk 45
106 #define __NR_setgid 46
107 #define __NR_getgid 47
108 #define __NR_signal 48
109 #define __NR_geteuid 49
110 #define __NR_getegid 50
111 #define __NR_acct 51
112 #define __NR_phys 52
113 #define __NR_lock 53
114 #define __NR_ioctl 54
115 #define __NR_fcntl 55
116 #define __NR_mpx 56
117 #define __NR_setpgid 57
118 #define __NR_ulimit 58
119 #define __NR_uname 59
120 #define __NR_umask 60
121 #define __NR_chroot 61
122 #define __NR_ustat 62
123 #define __NR_dup2 63
124 #define __NR_getppid 64
125 #define __NR_getpgrp 65
126 #define __NR_setsid 66
127 #define __NR_sigaction 67
128 #define __NR_sgetmask 68
129 #define __NR_ssetmask 69
130 #define __NR_setreuid 70
131 #define __NR_setregid 71
132
// The following definitions are embedded assembler macro function system calls. System // no
//% 0 - eax (__ res),% 1 - eax (__ NR _ ## name). Wherein the name is the name of the system call, the system call symbol is formed above __NR_ // constant in combination with such a
table for the system calls the function pointer addressing. // Returns: if the return value is greater than or equal to 0, the value is returned, otherwise set errno error number, and returns -1.
--501--
11.14 unistd.h file
139 : "" (__NR _ ## name)); \ // interrupt input system call number __NR_name.
140 if (__res> = 0) \ // If the return value is> = 0, then return the value directly.
--502--
11.14 unistd.h file
188
// function prototype is defined corresponding to each system call. (See details include / linux / sys.h)
--503--
11.15 utime.h file
254
The document defines the structure file access and modification times utimbuf {} as well as utime () Function prototype. Total time in seconds.
1 #ifndef _UTIME_H 2 #define _UTIME_H 3 4 #include <sys / types.h> / * I know - should not do this, but ..
*/
8 time_t modtime; // file modification time. From 1970.1.1: 0: 0: 0 Number of seconds to start.
9 };
10
// Set file access and modification time function.
14
--504--
File under 11.16 include / asm / directory
The document defines the hardware IO Embedded assembler port access macro functions: outb () , inb () as well as outb_p () with inb_p () . The first two functions with two
rear main difference is that the latter uses a code jmp A time delay instruction.
--505--
11.18 memory.h file
twenty four })
25
This file contains a copy of memory macros embedded assembler memcpy () . versus string.h Defined memcpy () The same, but the latter is used in embedded assembly C Functional
form definition.
1/*
2 * NOTE !!! memcpy (dest, src, n) assumes ds = es = normal data segment. This
3 * Goes for all kernel functions (ds = es = kernel space, fs = local data,
4 * Gs = null), as well as for all well-behaving user programs (ds = es =
5 * User data space). This is NOT a bug, as any user program that changes
6 * Es deserves to die if it is not careful.
7*/
/*
* Note !!! memcpy (dest, src, n) is assumed segment register ds = es = normal data segment. Used in the kernel
* All functions are based on the assumption (ds = es = kernel space, fs = spatial local data, gs = null), having good
* The behavior of the application the same way (ds = es = user data space). If any arbitrary changes to the user program
copy destination address, src - copy source address, n - the number of bytes copied. //% 0 - edi (destination address dest),% 1 - esi
--506--
11.19 segment.h file
This document defines the access segment register or memory operation functions associated with segment register.
twenty four
The //// a byte is stored at the memory address specified in paragraph fs. // Parameters:
val - byte value; addr - memory address. //% 0 - Register (byte value val);% 1 - (memory
address addr).
--507--
11.19 segment.h file
27 __asm__ ( " movb% 0, %% fs:% 1 "::" r "( val), " m "(* addr));
28 }
29
//// word will be placed in the designated fs segment at memory address. // Parameters: val
- word value; addr - memory address. //% 0 - Register (word value val);% 1 - (memory
address addr).
long word value; addr - memory address. //% 0 - Register (longword value val);% 1 -
35 extern inline void put_fs_long (Unsigned long val, unsigned long * addr)
36 {
37 __asm__ ( " movl% 0, %% fs:% 1 "::" r "( val), " m "(* addr));
38 }
3940 / *
41 * Someone who knows GNU asm better than I should double check the followig.
42 * It seems to work, but I do not know if I'm doing something subtly wrong.
43 * --- TYT, 11/24/91
44 * [Nothing wrong here, Linus]
45 * /
/*
* I know better than the GNU assembler people should check the following code carefully. These codes can be used, but I do not know whether
--508--
11.20 system.h file
62 {
63 __asm __ ( " mov% 0, %% fs "::" a "(( unsigned short) val));
64 }
6566
This document defines a set or modify the descriptor / interrupt gate or the like embedded macro assembler.
Where the function move_to_user_mode () For initializing the kernel at the end of manual switching (moves) to the initial process (task 0 ) To do it. The method used was a
simulated interrupt procedure call returns, i.e. by Command iret Run the initial task 0 . See Fig. 11-2 Fig.
CS original ESP
Original EFLAGS
Original
Original EIP
SP1-iret instructions before the implementation of the new SS: ESP
Map 11-2 When the content interrupt call stack to switch between layers
In to perform the task 0 Before the code, first set up the stack, the analog switch has a privileged layer of just entering the arrangement of the contents of the stack when
the interrupt calling procedure. Iret then execute instructions to cause the system to a task 0 In execution. In execution iret When the statement, the contents of the stack as shown 11.2
As shown, at this time esp for esp1 . task 0 The stack is a stack kernel. When executed iret After that, he moved to the task 0
In the execution. As the task 0 Is a descriptor privilege level 3 Therefore stack on ss: esp It will be ejected. Thus, in iret after that, esp And equal esp0 A. Note that this interruption
return instruction iret And will not cause CPU To perform the task switching operation, because before executing this function, the flag NT Already here sched_init () It is reset. in NT Perform
reset iret Instruction will not cause CPU Perform a task switch operation. task 0 The execution is purely artificial started.
task 0 Is a special process that data segment and code segment mapped directly to the kernel code and data space, i.e., from the physical address 0 Started 640K Memory
space, its stack address is the kernel code used in the stack. Thus the original stack in FIG. SS And former ESP Existing kernel stack pointer is pushed on the stack directly.
--509--
11.20 system.h file
// This function is implemented using iret instruction to move from kernel mode to perform the initial tasks 0.
1 #define move_to_user_mode () \
2 __asm__ ( " movl %% esp, %% eax \ n \ t "\ // save the stack pointer register eax esp.
3 "Pushl $ 0x17 \ n \ t" \ // first the stack segment selector (SS) stack.
4 "Pushl %% eax \ n \ t" \ // then the value of the saved stack pointer (ESP) stack.
5 "Pushfl \ n \ t" \ // The flag register (eflags) the contents of the stack.
// Parameters: gate_addr - descriptor address; type - the type field value descriptor; dpl - descriptor privilege level value; addr - offset. % // 0 - (a dpl, type
combined into a type of flag word);% 1 - (4-byte descriptor Low); //% 2 - (4 descriptor high byte address);% 3 - edx (program offset address addr);% 4 - eax (high
twenty four "Movw% 0, %% dx \ n \ t" \ // the offset type flag words and descriptor words into a high-high-order 4 bytes (edx).
25 "Movl %% eax,% 1 \ n \ t" \ // are provided gate descriptor and the lower 4 bytes 4 bytes higher.
// & idt [n] corresponding to the interrupt number in an interrupt descriptor offset values in the table; interrupt descriptor type is 14, the privilege level is zero.
// & idt [n] corresponding to the interrupt number in an interrupt descriptor offset values in the table; interrupt descriptor type is 15, the privilege level is zero.
// & idt [n] corresponding to the interrupt number in an interrupt descriptor offset values in the table; interrupt descriptor type is 15, the privilege level is 3.
--510--
11.20 system.h file
55 "Rorl $ 16, %% eax \ n \ t" \ // High word into the base address of the ax.
56 "Movb %% al,% 3 \ n \ t" \ // The base address low byte of the high word of the descriptor into 4 bytes.
57 "Movb $" type ",% 4 \ n \ t "\ // Type flag byte to the fifth byte of the descriptor.
58 "Movb $ 0x00,% 5 \ n \ t" \ // descriptor sixth byte set to zero.
59 "Movb %% ah,% 6 \ n \ t" \ // The base address high byte of the high word of the descriptor into 7 bytes.
// n - is the descriptor pointer; addr - is the base address value descriptor. The type of task status segment descriptor is 0x89.
65 #define set_tss_desc (N, addr) _set_tssldt_desc (((Char *) (n)), addr, " 0x89 ")
//// set the local descriptor table in the global table.
// n - is the descriptor pointer; addr - is the base address value descriptor. Local descriptor table type is 0x82.
66 #define set_ldt_desc (N, addr) _set_tssldt_desc (((Char *) (n)), addr, " 0x82 ")
67
--511--
File under 11.21 include / linux / directory
Kernel configuration header file. Custom keyboard language type and hard disk type used ( HD_TYPE ) Options.
*/
89 / *
--512--
11.22 config.h file
*/
16 / * # Define KBD_US * /
17 / * # Define KBD_GR * /
18 / * # Define KBD_FR * /
19 #define KBD_FINNISH 20 21 / *
twenty two * Normally, Linux can get the drive parameters from the BIOS at
twenty three * Startup, but if this for some unfathomable reason fails, you'd
twenty four * Be left stranded. For this case, you can define HD_TYPE, which
25 * Contains all necessary info on your harddisk.
26 *
27 * The HD_TYPE macro should look like this:
28 *
29 * #Define HD_TYPE {head, sect, cyl, wpcom, lzone, ctl}
30 *
31 * In case of two harddisks, the info should be sepatated by
32 * Commas:
33 *
34 * #Define HD_TYPE {h, s, c, wpcom, lz, ctl}, {h, s, c, wpcom, lz, ctl}
35 * /
/*
* Usually, Linux can get the drive parameters from the BIOS in Germany at the start, but if an unknown reason
* But not when these parameters, the program will do nothing. In this case, you can define HD_TYPE,
* Including all hard drive information.
*
* HD_TYPE macro should like this in the form below:
*
* # define HD_TYPE {head, sect, cyl, wpcom, lzone, ctl}
*
* For two hard drives, the information required parameters separated by commas:
*
* # define HD_TYPE {h, s, c, wpcom, lz, ctl}, {h, s, c, wpcom, lz, ctl}
*/
36 / *
37 This is an example, two drives, first is type 2, second is type 3:
3839 #define HD_TYPE {4,17,615,300,615,8}, {6,17,615,300,615,0}
4041 NOTE: ctl is 0 for all drives with heads <= 8, and ctl = 8 for drives
--513--
11.23 fdreg.h header file
* The ctl = 8.
*
* If you want the type of BIOS given hard disk, simply do not define HD_TYPE. This is the default action.
*/
4748 #endif
49
The header file for describing the floppy disk to the system used and the parameters used I / O port. Since the control of the floppy drive more cumbersome, but also
command more, so before you read the code, it is best reference books on the principle of micro-computer control interface, understand floppy disk controller ( FDC) Works, then
you will find the definition here is quite reasonable and orderly.
For access to programming 4 Ports, respectively corresponding to one or more registers. for 1.2M The table has a floppy disk controller 11-1 Some port.
Digital output port (port number control) is a 8 Bit register which controls the drive motor is turned on, the drive selection, start / reset FDC As well as enable / disable DMA
FDC The status register is a main 8 Bit register is used to reflect the floppy disk controller FDC And a floppy disk drive FDD The basic state. Typically, CPU to FDC Before
sending a command or from FDC Before obtaining the operation result, the master must read the status register bits, to discriminate the current FDC Data register is ready and
FDC A plurality of registers corresponding to the data port (write only type parameter register and the command register, read-only result register), but any one time, only
one appears in the data port register 0x3f5 . When accessing the write-only register, the main state control DIO Direction bit must be 0 ( CPU FDC ), And vice versa when the read
access type register. When reading the results only in FDC After reading the results considered busy, usually resulting data Up 7 Bytes.
--514--
11.23 fdreg.h header file
The floppy disk controller can accept a total of 15 Command. Each command through three stages: the command phase, implementation phase and the results stage.
Command stage CPU to FDC Send command byte and parameter bytes. The first byte of each command byte is always the command (command code). Thereafter followed 0--8 Byte
parameters. The implementation phase is FDC Perform the operation specified command. In the implementation phase CPU That without intervention, usually through FDC It issues
an interrupt request to know the end of the command execution. in case CPU dispatched FDC Command is transmitted data, FDC You can interrupt or DMA Conducted. Interrupt
Transmitting data to and from memory until all of the data transferred. at this time DMA Controller will signal the transfer byte count termination FDC Finally, the FDC Issues an
interrupt request signal inform CPU The implementation phase is completed. The result is a stage CPU Read FDC Data register return value, to thereby obtain FDC The results of the
command execution. Return result data length 0--7 byte. For data command does not return results, should the FDC Interrupt Status command transmission detecting operation state
is obtained.
1/*
2 * This file contains some defines for the floppy disk controller.
3 * Various sources Mostly "IBM Microcomputers:. A Programmers
4 * Handbook ", Sanches and Canton.
5*/
/*
* This file contains a number of definitions of the floppy disk controller. There are many sources of information, mostly taken from Sanches and Canton
*/
6 #ifndef _FDREG_H // This code is defined to exclude this header file contains duplicate.
7 #define _FDREG_H 8
--515--
11.23 fdreg.h header file
--516--
11.24 fs.h file
/ * DMA command * /
flag.
68 #define DMA_READ 0x46 // read the disk DMA, DMA mode word (send DMA port 12,11).
69 #define DMA_WRITE 0x4A // DMA write disk, DMA mode word.
7071 #endif
72
1/*
2 * This file has definitions for some important file table
3 * Structures etc.
4*/
/*
* This paper contains certain critical files define the table structure, and the like.
*/
56 #ifndef _FS_H 7 #define _FS_H 8 9 #include
<sys / types.h>
1011 / * Devices are as follows: (same as minix, so we can use the minix
twenty two * /
/*
* Equipment contained in the system are as follows :( Like minix system, so we can use the minix
27 #define WRITE 1
28 #define READA 2 / * Read-ahead - do not pause * /
29 #define WRITEA 3 / * "Write-ahead" - silly, but somewhat useful * /
3031 void buffer_init (Long buffer_end);
34 #define MINOR (A) ((a) & 0xff) // get low byte (the minor device number).
--518--
11.24 fs.h file
44 #define NR_INODE 32
45 #define NR_FILE 64
46 #define NR_SUPER 8
47 #define NR_HASH 307
48 #define NR_BUFFERS nr_buffers 49 #define BLOCK_SIZE
1024 // Data block length.
50 #define BLOCK_SIZE_BITS 10 // number of bits occupied by the data block length.
53 #endif
54
// Each logical block may be stored in the nodes i.
55 #define INODES_PER_BLOCK (( BLOCK_SIZE ) / (Sizeof (struct d_inode ))) // number of directory entries can be stored in
73 unsigned char b_dirt; / * 0-clean, 1-dirty * / // Modify flag: 0 unmodified, 1 has been modified.
74 unsigned char b_count; / * Users using this block * / // number of users.
75 unsigned char b_lock; / * 0 - ok, 1 -locked * / // Whether the buffer is locked.
76 struct task_struct * B_wait; // point to wait for the buffer to unlock the task.
77 struct buffer_head * B_prev; // hash approached a queue (these four pointers used to manage buffer).
83 struct d_inode {
84 unsigned short i_mode; // file type and attributes (rwx bits).
85 unsigned short i_uid; // user id (file owner identifier).
86 unsigned long i_size; // File Size (bytes).
87 unsigned long i_time; // modification time (from 1970.1.1: 0, counting seconds).
90 unsigned short i_zone [9]; // Direct (0-6), indirect (7) or double indirectly (8) a logical block number.
--519--
11.24 fs.h file
// zone is meant the zone, can be translated into segments, or logical blocks.
91 };
92
// This is the i-node structure in memory. Before 7 and d_inode exactly the same.
93 struct m_inode {
94 unsigned short i_mode; // file type and attributes (rwx bits).
95 unsigned short i_uid; // user id (file owner identifier).
96 unsigned long i_size; // File Size (bytes).
97 unsigned long i_mtime; // modification time (from 1970.1.1: 0, counting seconds).
100 unsigned short i_zone [9]; // Direct (0-6), indirect (7) or double indirectly (8) a logical block number.
127 unsigned short s_imap_blocks; // i-node number of blocks occupied by the bitmap.
128 unsigned short s_zmap_blocks; // logical block number of data blocks occupied by the bitmap.
137 struct m_inode * S_isup; // i root node of the file system is mounted. (Isup-super i)
138 struct m_inode * S_imount; // i is attached to the node.
139 unsigned long s_time; // Change the time.
--520--
11.24 fs.h file
140 struct task_struct * S_wait; // Wait for the process of the superblock.
149 unsigned short s_imap_blocks; // i-node number of blocks occupied by the bitmap.
150 unsigned short s_zmap_blocks; // logical block number of data blocks occupied by the bitmap.
155 };
156
// file directory entry structure.
167
//// disk operations function prototypes. // Check whether the
//// The following is the function prototype with the file system operations management.
173 extern void truncate (Struct m_inode * Inode); // refresh the i-node
information.
174 extern void sync_inodes (Void);
// wait i node specified.
175 extern void wait_on (Struct m_inode * Inode);
// logical block (sector, disk blocks) bitmap operations. Block fetch data block corresponding to the logical block number in the device.
--521--
11.24 fs.h file
179 extern int open_namei (Const char * pathname, int flag, int mode,
180 struct m_inode ** res_inode);
// release a i-node (written back device).
181 extern void iput (Struct m_inode * Inode); // read the specified number
of slave node a node i.
182 extern struct m_inode * iget (Int dev, int nr);
// Get a free node i from the i-node table entry (inode_table) in.
183 extern struct m_inode * get_empty_inode (Void);
// Get the (applying a) pipeline node. It returns a pointer to the node i (if NULL is a failure).
184 extern struct m_inode * get_pipe_inode (Void);
// find the specified data block in a hash table. Returns a pointer to find the first buffer block.
187 extern void ll_rw_block (Int rw, struct buffer_head * Bh); // release a specified buffer block.
188 extern void brelse (Struct buffer_head * buf ); // read the specified data block.
191 extern struct buffer_head * breada (Int dev, int block, ...);
// apply a disk block (sector, logical blocks) to device dev. Returns the logical block number
203
--522--
11.25 hdreg.h file
1/*
2 * This file contains some defines for the AT-hd-controller.
3 * Various sources. Check out some definitions (see comments with
4 * A ques).
5*/
/*
* This document contains a number of definitions AT hard disk controllers. From a variety of materials. Please verify certain
*/
6 #ifndef _HDREG_H 7 #define _HDREG_H 8 9 / * Hd controller regs Ref:. IBM AT
Bios-listing * /
--523--
11.25 hdreg.h file
=========================================== ======= //
// ------------------------------------------------ - // 0x01
No error Data loss mark
// 0x02 Controller error Wrong track 0
// ------------------------------------------------ ---
45 #define MARK_ERR 0x01 / * Bad address mark? * /
46 #define TRK0_ERR 0x02 / * Could not find track 0 * /
47 #define ABRT_ERR 0x04 / *? * /
48 #define ID_ERR 0x10 / *? * /
49 #define ECC_ERR 0x40 / *? * /
50 #define BBD_ERR 0x80 / *? * /
51
// hard disk partition table structure. See the following list information.
52 struct partition {
53 unsigned char boot_ind; / * 0x80 - active (unused) * /
54 unsigned char head ; / *? * /
55 unsigned char sector ; / *? * /
56 unsigned char cyl; / *? * /
57 unsigned char sys_ind; / *? * /
58 unsigned char end_head; / *? * /
59 unsigned char end_sector; / *? * /
60 unsigned char end_cyl; / *? * /
61 unsigned int start_sect; / * Starting sector counting from 0 * /
62 unsigned int nr_sects; / * Nr of sectors in partition * /
63 };
6465 #endif
66
In order to realize a plurality of operating systems to share resources hard disk, the hard disk can be logically divided into 1--4 Partitions. Between the sector number of
each partition are contiguous. The partition table 4 Table entries, each entry is made 16 Byte, information corresponding to a partition, partition size and storing the cylinder
number, track number and sector number of the start and end, Table 11-2 Fig. Stored in the hard disk's partition table 0 cylinder 0 Head first 1 Sectors
--524--
11.26 head.h file
0x00 boot_ind byte Boot flags. 4 Partition at the same time only one partition is bootable.
0x00- Not boot the operating system from the partition; 0x80- Operating system from the boot partition.
0x02 sector byte Partition start sector number (bits 0-5) And high starting cylinder number 2 Bit (Bit 6-7) .
0x04 sys_ind byte Partition type byte. 0x0b-DOS; 0x80-Old Minix; 0x83-Linux ...
0x05 end_head byte The end of the head number of the partition.
0x06 end_sector byte End sector number (bits 0-5) And high-end cylinder number 2 Bit (Bit 6-7) .
0x0c - 0x0f nr_sects Long word The number of sectors occupied by partitions.
head Header files, define Intel CPU Simple structure descriptor, and the descriptor entry number specified.
// define data structures segment descriptor. The structure described only each description
5 unsigned long a, b; // operator is composed of 8 bytes, a total of each descriptor table 256.
6 } desc_table [256];
78 extern unsigned long pg_dir [1024]; // array of memory pages directory. Each directory entry is 4 bytes. Starting from the physical address 0.
14 #define GDT_TMP 3 // item 3, the system segment descriptors, Linux is not used.
18 #define LDT_DATA 2 // Item 2, the program is user data segment descriptor entry.
1920 #endif
--525--
11.27 kernel.h file
twenty one
1/*
2 * 'Kernel.h' contains some often-used function prototypes etc
3*/
/*
* 'Kernel.h' defines some common functions like prototype.
*/
// verify whether a given block of memory addresses starting overrun. If the additional memory overrun. (Kernel / fork.c, 24).
5 volatile void panic (Const char * str ); // standard print (display) function. (Init /
main.c, 151).
6 int printf (Const char * fmt, ...);
// kernel dedicated print information function, function printf () the same. (Kernel / printk.c, 21).
7 int printk (Const char * fmt, ...);
// to specify the length of the string tty write. (Kernel / chr_drv / tty_io.c, 290).
8 int tty_write (Unsigned ch, char * buf , Int count ); // common core memory
allocation functions. (Lib / malloc.c, 117).
9 void * malloc (Unsigned int size);
// release the memory occupied by the specified object. (Lib / malloc.c, 182).
1314 / *
--526--
11.28 mm.h file
2223
mm.h Memory management is the header file. Which defines the main memory page size and page release several function prototypes.
5
// get free pages function. Return page address. Scanning the mem_map page mapping array [] get free pages.
7 extern unsigned long put_page (Unsigned long page, unsigned long address);
// release a physical page of memory address addr began. Modify page mapping array mem_map [] in reference to the number of information.
11
Scheduler header file that defines the task structure task_struct The initial task 0 Data, there are some relevant descriptors parameter set and get embedded assembly
5 #define HZ 100 // Define frequency of the system clock ticks (1 million Hertz, each tick 10ms)
--527--
11.29 sched.h file
11 #include <linux / fs.h> // file system header files. Table structure definition file (file, buffer_head, m_inode, etc.).
12 #include <linux / mm.h> // memory management header files. It contains the defined page size and page number of the release function prototypes.
13 #include <signal.h> // signal header files. Defined symbolic constant signal, the signal structure and the operation function prototype signal.
16 #error " Currently the close-on-exec-flags are in one word, max 32 files / proc "
17 #endif
18
// This defines the state of the process may be run at.
twenty two #define TASK_ZOMBIE 3 // process dead in the state, has stopped running, but the parent process has not signaled.
27 #endif
28
// page directory page table replication process. Linus kernel think this is one of the most complex functions. (Mm / memory.c, 105)
29 extern int copy_page_tables (Unsigned long from, unsigned long to, long size);
// release the page table designated memory block and page table itself. (Mm / memory.c, 150)
39
// Here is the structure of a math coprocessor used mainly for the implementation of state i387 information when you save the process of switching.
40 struct i387_struct {
41 long cwd; // Control Word (Control word).
42 long swd; // Status word (Status word).
43 long twd; // marker word (Tag word).
44 long fip; // coprocessor code pointers.
45 long fcs; // coprocessor code segment register.
--528--
11.29 sched.h file
// long signal signal. Bitmap, each bit represents a signal, the signal value of the bit offset value = +1.
// struct sigaction sigaction [32] and the operation execution flag signal information attribute structure, a corresponding signal will be executed. // long blocked
// unsigned long start_code code segment address. // unsigned long end_code The code length
(number of bytes). // unsigned long end_data Code length + data length (number of bytes). //
unsigned long brk
Total length (number of bytes).
--529--
11.29 sched.h file
// struct desc_struct ldt [3] local descriptor table of the present task. 0- empty, 1- snippet cs, 2- data and stack segments ds & ss. //
------------------------- // struct tss_struct tss
TSS information structure in this process.
// ==========================
78 struct task_struct {
79 / * These are hardcoded - do not touch * /
80 long state ; / * -1 unrunnable, 0 runnable,> 0 stopped * /
81 long counter;
82 long priority;
83 long signal;
84 struct sigaction sigaction [32];
85 long blocked; / * Bitmap of masked signals * /
86 / * Various fields * /
87 int exit_code;
88 unsigned long start_code, end_code, end_data, brk , Start_stack;
89 long pid, father, pgrp, session, leader;
90 unsigned short uid, euid, suid;
91 unsigned short gid, egid, sgid;
92 long alarm ;
93 long utime , stime , Cutime, cstime, start_time;
94 unsigned short used_math;
95 / * File system info * /
96 int tty; / * -1 if no tty, so it must be signed * /
97 unsigned short umask ;
98 struct m_inode * Pwd;
99 struct m_inode * Root;
100 struct m_inode * Executable;
101 unsigned long close_on_exec;
102 struct file * Filp [ NR_OPEN ];
103 / * Ldt for this task 0 - zero 1 - cs 2 - ds & ss * /
104 struct desc_struct ldt [3];
105 / * Tss for this task * /
106 struct tss_struct tss;
107 };
108109 / *
--530--
11.29 sched.h file
* INIT_TASK The first task for setting the table, if you want to modify your own risk ☺ !
* Base Address Base = 0, segment length limit = 0x9ffff (= 640kB).
*/
// correspondence information of the first task of the task structure above.
139 extern long volatile jiffies ; // ticks begin to run from the boot of (10ms / tick).
140 extern long startup_time ; // boot time. 0:: 0: 0 Number of seconds from the start time of 1970.
143
// add a timer function (regular time jiffies ticks, call the function * fn () when the timer expires). (Kernel / sched.c, 272)
144 extern void add_timer (Long jiffies , Void (* fn) (void)); // wait for uninterruptible sleep.
(Kernel / sched.c, 151)
145 extern void sleep_on (Struct task_struct ** p); // wait interruptible sleep.
(Kernel / sched.c, 167)
146 extern void interruptible_sleep_on (Struct task_struct ** p); // clear wake-sleep process. (Kernel /
sched.c, 188)
147 extern void wake_up (Struct task_struct ** p);
148 149 /
*
150 * Entry into gdt where to find first TSS. 0-nul, 1-cs, 2-ds, 3-syscall
151 * 4-TSS0, 5-LDT0, 6-TSS1 etc ...
152 * /
/*
* Find the first entry in a TSS global table. 0 - no use nul, 1- snippet cs, 2- segment ds, 3- syscall system segment
* 4- TSS TSS0,5- local table LTD0,6- task state segment TSS1, and the like.
*/
// global table of a task state segment (TSS) descriptor selector index.
--531--
11.29 sched.h file
156 #define _LDT (N) ((((unsigned long) n) << 4) + ( FIRST_LDT_ENTRY << 3))
// macro definition, loading task register tr n-th task.
157 #define ltr (N) __asm __ ( " ltr %% ax "::" a "( _TSS (N-)))
// macro definition, Local Descriptor Table Register loading ldtr n-th task.
158 #define lldt (N) __asm __ ( " lldt %% ax "::" a "( _LDT (N-)))
// get the current task number to run the task (task array index value, unlike the process number pid). // returns: n -
the current task number. For (kernel / traps.c, 79).
159 #define str (N) \
160 __asm __ ( " str %% ax \ n \ t "\ // register the task effectively address TSS segment ax
selector composition. Thus __tmp value in a 32-bit offset value and the lower 2 bytes b // selector (not higher 2 bytes) and the new TSS segment. Jump to TSS segment
selector will cause TSS task switch to the corresponding process. For cause long jump // task switching, a value is useless. Indirect jump instruction memory 177 on line
using a 6-byte operand as long pointer jump destination, // the format: jmp 16-bit segment selector: 32-bit offset. However, in a sequence number memory operation
opposite herein. // When the judge whether to perform a new task last used coprocessor is used to compare the task state segment address coprocessor by the new
task state segment addresses stored in the variable // last_task_used_math made, // see kernel / sched.c a function math_state_restore ().
178 "Cmpl %% ecx, _last_task_used_math \ n \ t" \ // The new task coprocessor last used it?
179 "Jne 1f \ n \ t" \ // do not jump, quit.
180 "Clts \ n" \ // new tasks last used coprocessor, the cr0 clear signs of TS.
181 "1:" \
--532--
11.29 sched.h file
1 - Address Offset 4 addr;% 2 - offset address addr 7; edx - base address base.
190 "Rorl $ 16, %% edx \ n \ t" \ // the high edx base address (bits 31-16) dx.
191 "Movb %% dl,% 1 \ n \ t" \ The high 16-bit base address // lower 8 bits (bits 23-16) [addr + 4].
192 "Movb %% dh,% 2" \ The high 16-bit base address // upper 8 bits (bits 31-24) [addr + 7].
address addr;%. 1 - Address addr offset 6; edx - segment length value limit.
202 "Movb% 1, %% dh \ n \ t" \ // take the original [addr + 6] bytes dh, wherein these flags is four bits.
203 "Andb $ 0xf0, %% dh \ n \ t" \ Dh // clear the lower 4 bits (bit length of the stored segment 19-16).
204 "Orb %% dh, %% dl \ n \ t" \ // the high four original segment length flag and high-order 4 bits (bits 19-16) Synthesis of 1 byte,
211 #define set_base (Ldt, base) _set_base (((Char *) & (ldt)), base)
// Set segment length field ldt local descriptor table descriptor.
212 #define set_limit (Ldt, limit) _set_limit (((Char *) & (ldt)), (limit-1) >> 12)
213
Symbol // fetch the base address from the address addr of the description. Functions and _set_base () just the opposite.
// edx - storage base address (__base);% 1 - 2 offset address addr;% 2 - offset address addr 4;% 3 - addr offset 7.
214 #define _get_base (Addr) ({\
215 unsigned long __base; \
216 __asm __ ( " movb% 3, %% dh \ n \ t "\ // get [addr + 7] at a high 16-bit base address of the upper 8 bits (bits 31-24) dh.
217 "Movb% 2, %% dl \ n \ t" \ // get [addr + 4] of the base address of the lower 8-bit high-order 16 bits (bits 23-16) dl.
218 "Shll $ 16, %% edx \ n \ t" \ @ 16 is shifted to the high base address edx high at 16.
219 "Movw% 1, %% dx" \ // get [addr + 2] of the base address of the lower 16 bits (bits 15-0) dx.
220 : "= d "(__ base) \ // edx thus contained 32-bit segment base address.
--533--
11.29 sched.h file
// get the local descriptor table descriptor base address indicated ldt of.
// Load Segment Limit command lsl is abbreviated. It is removed from the dispersion indefinite length designated segment descriptor bit segment makes up the complete // indefinite
length value into the designated register. The resulting long segment limit is 1 minus the actual number of bytes, so there is also a need to increase before returning. % // 0 - value
234
31 twenty three 15 7 0
0,000,000,000,000,000 GS 5C
0,000,000,000,000,000 FS 58
0,000,000,000,000,000 DS 54
0,000,000,000,000,000 SS 50
0,000,000,000,000,000 CS 4C
0,000,000,000,000,000 ES 48
EDI 44
ESI 40
EBP 3C
ESP 38
EBX 34
EDX 30
ECX 2C
EAX 28
0,000,000,000,000,000 SS2 18
ESP2 14
0,000,000,000,000,000 SS1 10
ESP1 0C
0,000,000,000,000,000 SS0 08
ESP0 04
--534--
12.9 malloc.c program
Bucket descriptor
1. First search the directory to find the corresponding directory entry for the requested descriptor linked list of memory block size. When the target byte length of directory entry
It is greater than the byte length of the request, even if found appropriate directory entry. If the search is complete directories have not found the right directory
2. Find a free space having a descriptor in the directory entry corresponding descriptor list. If a free memory pointer descriptor
freeptr It is not NULL , It means to find the appropriate descriptor. If no descriptors have free space, then we need to create a new
a. If the free list head pointer descriptor or NULL It indicates that the first call malloc () Function, this time need
b. Then take a descriptor from the free descriptor at the head of the list, initializes the descriptor, object reference count is allowed to 0 Objects
Size is equal to a value corresponding to the length of the directory entry of the specified object, and apply a memory page, so page pointer descriptor page Pointing
to the memory page descriptor pointer free memory freeptr Also pointing to the page start position.
c. According to the catalog entry for page initialization used memory object length of the page, to create a list of all objects. and also
I.e., the head of each object are stored a pointer pointing to the next object, beginning at the last object in a storage
d. The descriptor is then inserted into the descriptor list corresponding to the beginning of the directory entry.
3. The free memory pointer descriptor freeptr Replication is returned to the user memory pointer, then adjusting the freeptr Pointing Description
Character corresponding to the next free page memory object position, and the reference count by descriptor 1 .
free_s () Function is used to recover the user releases the memory block. The basic principle is first converted from the address of the memory block corresponding to the
memory block address of the page (the page length modulo operation performed by), and then searches all directory descriptors, descriptors should find the page. The released
memory block links freeptr The free list pointed to the object, and the object descriptor reference count Save 1 . At this time, if the reference count is equal to zero, it indicates that
the descriptor corresponding to the page has been completely vacated, the memory can be released and the page descriptor is retracted to the free descriptor list.
1/*
2 * Malloc.c --- a general purpose kernel memory allocator for Linux.
3*
4 Written by Theodore Ts'o * ( [email protected] ), 11/29/91
5*
6 * This routine is written to be as fast as possible, so that it
7 * Can be called from the interrupt level.
8*
9 * Limitations: maximum size of memory we can allocate using this routine
10 * is 4k, the size of a page in Linux.
555
12.9 malloc.c program
11 *
12 * The general game plan is that each page (called a bucket) will only hold
13 * Objects of a given size. When all of the object on a page are released,
14 * The page can be returned to the general free pool. When malloc () is
15 * Called, it looks for the smallest bucket size which will fulfill its
16 * Request, and allocate a piece of memory from that bucket pool.
17 *
18 * Each bucket has as its control block a bucket descriptor which keeps
19 * Track of how many objects are in use on that page, and the free list
20 * For that page. Like the buckets themselves, bucket descriptors are
twenty one * Stored on pages requested from get_free_page (). However, unlike buckets,
twenty two * Pages devoted to bucket descriptor pages are never released back to the
twenty three * System. Fortunately, a system should probably only need 1 or 2 bucket
twenty four * Descriptor pages, since a page can hold 256 bucket descriptors (which
25 * Corresponds to 1 megabyte worth of bucket pages.) If the kernel is using
26 * That much allocated memory, it's probably doing something wrong. :-)
27 *
28 * Note: malloc () and free () both call get_free_page () and free_page ()
29 * in sections of code where interrupts are turned off, to allow
30 * malloc () and free () to be safely called from an interrupt routine.
31 * (We will probably need this functionality when networking code,
32 * particularily things like NFS, is added to Linux.) However, this
33 * presumes that get_free_page () and free_page () are interrupt-level
34 * safe, which they may not be once paging is added. If this is the
35 * case, we will need to modify malloc () to keep a few unused pages
36 * "Pre-allocated" so that it can safely draw upon those pages if
37 * it is called from an interrupt routine.
38 *
39 * Another concern is that get_free_page () should not sleep; if it
40 * does, the code is carefully ordered so as to avoid any race
41 * conditions. The catch is that if malloc () is called re-entrantly,
42 * there is a chance that unecessary pages will be grabbed from the
43 * system. Except for the pages for the bucket descriptor page, the
44 * extra pages will eventually get released back to the system, though,
45 * so it is not all that bad.
46 * /
47
/*
* malloc.c - Linux generic kernel memory allocation functions.
*
* Compiled by the Theodore Ts'o ( [email protected] ), 11/29/91
*
* The function is written as soon as possible, so you can call this function from the fault.
*
* Restrictions: Using this function can be assigned a maximum memory is 4k, namely the size of the Linux memory pages.
*
* Preparing the general rule is followed by the function page (called a bucket) assigned to only the size of the object to be accommodated.
* When all objects on a page are released, this page will be returned universal free memory pool. When malloc () is called
* When it looks for the smallest of buckets to meet the requirements, and allocate a chunk of memory from the bucket.
*
* Each bucket has a control as a bucket descriptor, which records the page number has an object being
* Use and a list of free memory on this page. The same as its own bucket, bucket descriptor is stored in the usage
* that get_free_page () on the page to apply, but with a different bucket, the bucket descriptor is occupied by page
556
12.9 malloc.c program
* It will no longer be released to the system. Fortunately, only about a system bucket descriptor page 1-2, because a
* Pages 256 can store descriptors buckets (buckets corresponding to 1MB of memory pages). If the system is a bucket descriptor points
* (When the network code, it may be necessary in particular when this function is added to the NFS, etc. Linux). But before
* Mentioning the assumption get_free_page () and free_page () can be safely used in the interrupt level program,
* This once the addition of paging through it may not be safe. If this is the case, then we
* You need to modify malloc () to "pre-allocated" a few pages of unused memory, if malloc () and free ()
* You can safely use these pages when it is called from an interrupt routine.
*
* Another consideration is to get_free_page () should not sleep; if it will sleep, then in order to prevent
* Any competitive conditions, the code needs to be carefully arranged order. The key is that if malloc () can be reentrant
* Is called, then it will have a chance to unnecessary page is removed from the system. In addition to describing barrel
* Fu pages, these additional pages will eventually be released to the system, so it is not as bad as imagined.
*/
48 #include <linux / kernel.h> // kernel headers. It contains some common prototype custom kernel function.
49 #include <linux / mm.h> // memory management header files. It contains the defined page size and page number of the release function prototypes.
50 #include <asm / system.h> // system header files. Set or modify the defined descriptors / interrupt gate or the like embedded macro assembler.
51
// bucket descriptor structure.
52 struct bucket_desc { / * 16 bytes * /
53 void * Page; // pointer to the memory page descriptor corresponding to the tub.
58 };
59
// bucket descriptor directory structure.
62 struct bucket_desc * Chain; The directory entry // bucket bucket list pointer descriptor.
63 };
6465 / *
*
* If many objects of the specified size distribution of the Linux kernel, then we hope that this added to the specified size
557
12.9 malloc.c program
* The list (list), and because it allows more efficient allocation of memory. However, since a complete memory page
* The size of all the objects specified in the list must be used, it needs to be done to test the total number of operational aspects.
*/
// buckets directory listing (array).
77 struct _bucket_dir bucket_dir [] = {
78 {16, (Struct bucket_desc *) 0}, // Memory block 16 bytes in length.
*/
92 struct bucket_desc * free_bucket_desc = (Struct bucket_desc *) 0;
9394 / *
*/
//// Initialization bucket descriptor.
// Create idle bucket descriptor list, and let free_bucket_desc points to the first empty bucket descriptor.
558
12.9 malloc.c program
*/
// idle bucket descriptor pointer free_bucket_desc added to the list.
113 bdesc-> next = free_bucket_desc ;
114 free_bucket_desc = First;
115 }
116
//// dynamic memory allocation functions.
*/
// search directory buckets, barrels descriptor list to find suitable application memory block size. If the number of barrels byte directory entry // is greater than the number of bytes requested, to
*/
138 cli (); / * Avoid race conditions * / / * To avoid race conditions, first disable interrupts * /
// search for the corresponding directory entry in the bucket descriptor list, find the bucket descriptors have free space. If the bucket descriptor pointer // freeptr free memory is not
559
12.9 malloc.c program
146 if (! bdesc) {
147 char * Cp;
148 int i;
149
// If free_bucket_desc also empty, showing for the first time the program is called, then the descriptor list is initialized. // free_bucket_desc points
150 if (! free_bucket_desc )
151 init_bucket_desc ();
// points to take free_bucket_desc free bucket descriptor, and let free_bucket_desc point to the next free bucket descriptor.
152 bdesc = free_bucket_desc ;
153 free_bucket_desc = Bdesc-> next;
// initialize the new bucket descriptor. Make reference to a number equal to 0; bucket size equal to the corresponding size of the tub directory; application a memory page, the page descriptor //
make page pointer pointing to the page; free memory pointer also points to the beginning of the page, because the whole is in an idle .
157 if (! cp)
158 panic ( ' Out of memory in kernel malloc () ");
159 / * Set up the chain of free objects * /
/ * Create a free object in the list of free memory in the page * /
// specified to the bucket size for the object directory entry barrel length, dividing the page in memory, and starts // 4 bytes is provided to point to the next pointer for each target
object.
// then let the bucket descriptor next descriptor pointer field pointing to the corresponding directory entry pointer of the descriptor chain referred to in the tub, and the tub chain // directory
pointing to the bucket descriptor, the descriptor is about to be inserted into a descriptor chain head office.
171 sti (); / * OK, we're safe again * / / * OK, now we are safe * /
172 return (retval);
173 }
174 175 /
*
176 * Here is the free routine. If you know the size of the object that you
177 * Are freeing, then free_s () will use that information to speed up the
178 * Search for the bucket descriptor.
179 *
180 * We will #define a macro so that "free (x)" is becomes "free_s (x, 0)"
181 * /
/*
* The following is a release subroutine. If you know the size of the object is released, the free_s () will use this information to accelerate
560
12.9 malloc.c program
*
* We will define a macro that "free (x)" becomes "free_s (x, 0)".
*/
//// release bucket objects.
// Parameters: obj - the object corresponding to the pointer; size - size.
jump to the found. If the descriptor does not contain the corresponding page, so that the descriptor pointer points to the descriptor prev.
count by 1.
561
12.10 open.c program
218 if (prev)
219 prev-> next = bdesc-> next;
// if prev == NULL, then the current descriptor is the first directory entry descriptor, that directory entry directly // chain should point to the current descriptor bdesc, otherwise,
it indicates a problem with the list, the error message is displayed, crash. Thus, to the current descriptor // removed from the list, let the chain should point to the next
descriptor.
220 else {
221 if (bdir-> chain! = bdesc)
222 panic ( ' malloc bucket chains corrupted ");
223 bdir-> chain = bdesc-> next;
224 }
// release the current memory page descriptor operation, and the descriptor is inserted at the beginning of the free list descriptor.
open () System call is used to convert a file name into a file descriptor. When the call is successful, the file descriptor returned will be the process did not open the
minimum number of descriptors. The call creates a new open file, not shared with any other process. In execution
exec When the function, the new file descriptor will always maintained open. File read and write pointers at the beginning of a file are provided.
parameter flag Yes 0_RDONLY , O_WRONLY , O_RDWR One, representing a read-only file is opened, read and write and write-only open Open, it can
1/*
2 * Linux / lib / open.c
3*
4 * (C) 1991 Linus Torvalds
5*/
6
562
12.11 setsid.c program
system call number and also contain embedded assembly _syscall0 () and the like.
9 #include <stdarg.h> // standard parameter header. In the form of macro variables defined parameter list. Mainly it described
- a type // (the va_list) and three macros (va_start, va_arg and va_end), for // vsprintf, vprintf, vfprintf
function.
10
//// open file functions.
// open and possibly create a file.
// Parameters: filename - file name; flag - File Open logo; ... // Returns: the file descriptor,
if the error is an error code is set, and returns -1.
11 int open (Const char * filename, int flag, ...)
12 {
13 register int res;
14 va_list arg;
15
// use va_start () macro function to obtain a pointer flag following the argument and then calling system interrupt int 0x80, // function performed open file open operation.
//% 0 - eax (or descriptor returned error code);% 1 - eax (interrupt system function call number __NR_open); //% 2 - ebx (file name filename);% 3 - ecx
(open file flag flag);% 4 - edx (parameter file with the attribute mode).
16 va_start (Arg, flag);
17 __asm __ ( " int $ 0x80 "
18 : "= a "( res)
19 : "" ( __NR_open ) " b "( filename), " c "( flag),
20 "D" ( va_arg (Arg, int)));
// interrupt system call returns a value greater than or equal to 0, which indicates that a file descriptor, then return it directly.
The program includes a setsid () System call function. If the calling process is not a group of leaders, this function is used to create a new session. The calling process will
be the leader of the new session, group leader of the new process group, and has no controlling terminal. The group calling process id
And session id It is set to process PID ( Process identifier). The calling process will be the only new process and new process group session.
1/*
2 * Linux / lib / setsid.c
3*
563
12.12 string.c program
system call number and also contain embedded assembly _syscall0 () and the like.
9
//// create a session and sets the process group number. // The following macro
corresponds to the system call function: pid_t setsid (). // returns: the calling process
All string manipulation functions already string.h Implemented, and therefore string.c Program includes only string.h head File.
1/*
2 * Linux / lib / string.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #ifndef __GNUC__
// need the GNU C compiler.
8 #error I want gcc!
9 #endif
1011 #define extern
12 #define inline
13 #define __LIBRARY__ 14 #include
<string.h>
15
The program includes a function waitpid () with wait () . These two functions allow a process to obtain the status of one of its child processes information. Various options
allow to obtain child process has been terminated or stopped status information. If there are two or more sub-process state information, the order of the report is not specified.
564
12.14 write.c program
wait () Suspends the current process until one of its child process exits (termination), or receiving a termination signal to the process or to call a signal handler (signal
handler) requirements.
waitpid () Suspends the current process until pid Specified child process exits (terminate) signal or receive to terminate the process, or the need to call a signal
in case pid = -1 , options = 0 ,then waitpid () The role and wait () The same function. Otherwise, their behavior will vary pid with options They vary parameters. (See kernel
/ exit.c, 142 )
1/*
2 * Linux / lib / wait.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 #define __LIBRARY__ 8 #include
<unistd.h>
// Linux standard header file. Symbols and constants defined type, and affirms that the various functions. // as defined __LIBRARY__, the
system call number and also contain embedded assembly _syscall0 () and the like.
9 #include <sys / wait.h> // wait for the call header. The system defined call wait () and waitpid () and constants related symbols.
10
//// wait for its termination system calls.
// The following macro configuration corresponding to the function: pid_t waitpid (pid_t pid, int * wait_stat, int options) //
// Parameters: pid - waiting process is terminated process id, or for other special cases specified particular value; //
wait_stat - for storing status information; options - WNOHANG or WUNTRACED or 0.
11 _syscall3 ( pid_t , waitpid , pid_t , Pid, int *, wait_stat, int, options)
12
//// wait () system call. Direct call waitpid () function.
13 pid_t wait (Int * wait_stat)
14 {
15 return waitpid (-1, wait_stat, 0);
16 }
17
The program includes a function to write a file descriptor write () . The function specified file is written to the file descriptor count Bytes of data to the buffer buf in.
1/*
565
12.14 write.c program
system call number and also contain embedded assembly _syscall0 () and the like.
9
//// write file system calls.
// This macro configuration corresponding to the function: int write (int fd, const char * buf, off_t count) // Parameters: fd - file
descriptors; buf - the write buffer pointer; count - the number of bytes written.
// Return: Returns the number of bytes written (for write 0 bytes 0) success; -1 returns an error, and if the error number.
10 _syscall3 (Int, write , Int, fd, const char *, buf , off_t , count )
11
566
13.1 Overview
13.1 Outline
Linux Kernel source code tools Directory contains a utility to build the kernel disk image file build.c The individual program compiled executable in linux / Directory
Makefile Called file operation for connecting and merging all kernel code into compiled kernel image file that can be run image . The specific method is boot / middle bootsect.s
, setup.s use 8086 Compile assembler respectively generate respective execution module. Re-use of all other program source code GNU Compiler gcc / gas Compiling
and connected module system . Then use build These three tools are combined into a kernel image file image . Basic compiler connection
Build Tools
Kernel image file
Image
build Program uses 4 Parameters, namely, bootsect file name, setup file name, system File name and an optional root file system device file name.
Program first checks the last root device filename optional parameter on the command line, if it exists, the state information of the device configuration file is read ( stat ),
Remove the device number. If it is not specified on the command line, the default value.
Then bootsect File is processed, read the file minix Performing header information, determine its validity, and then subsequently read
512 Code data bytes of the boot, it is determined whether the flag has a bootable 0xAA55 And the number in front of the acquired root device to write 508, 509,
567
13.2 build.c program
At the displacement, the final 512 Byte code data written to stdout Standard output, by the Make File redirects to Image file.
The next process in a similar manner setup file. If the file is smaller than 4 Sectors, with the 0 It is filled with 4 The length of the sectors, and writes to standard output stdout
in.
The last treatment system file. The file is to use GCC Produced by a compiler, so the header format is performed GCC Types, and linux
Defined a.out The same format. Execution entry point is determined 0 After data is written to standard output will stdout in. If the code data whose length exceeds 128KB , The error
message is displayed.
1/*
2 * Linux / tools / build.c
3*
4 * (C) 1991 Linus Torvalds
5*/
67 / *
*
* - bootsect: 8086 machine code of the file up to 510 bytes, for loading other programs.
* - setup: 8086 machine code of the file up to four disk sectors, for setting the system parameters.
* Then remove the head module and a large expansion correct length. The program will also write data to some systems stderr.
*/
1819 / *
/*
* tytso the program was modified to allow the device to specify the root file.
*/
2223 #include <stdio.h>
/ * Fprintf * / / * Fprintf used therein () * /
twenty four #include <string.h> / * String operations * /
25 #include <stdlib.h> / * Contains exit * / / * Comprising Exit () * /
26 #include <sys / types.h> / * unistd.h needs this * / / * for use unistd.h * /
27 #include <sys / stat.h> / * File status information structure * /
568
13.2 build.c program
38 #define DEFAULT_MINOR_ROOT 6 // default root device minor number - 6 (2nd hard Partition 1).
3940 / * Max nr of sectors of setup: do not change unless you also change
41 * Bootsect etc * /
/ * The following specifies the maximum number of sectors account setup module: Do not change this value, unless you also change the corresponding file bootsect and so on.
45
//// displays an error message and terminates the program.
58 {
59 int i, c, id;
60 char buf [1024];
61 char major_root, minor_root;
62 struct stat sb;
63
// If the command line parameter is not a 4 or 5, the display program usage and exit.
66 if (argc == 5) {
// If the root device names are floppy disk ( "FLOPPY"), then take the status information of the device file when an error message is displayed, quit.
569
13.2 build.c program
75 major_root = 0;
76 minor_root = 0;
77 }
// If the parameter is only 4, so that the major and minor device number equal to the system default root device.
78 } Else {
79 major_root = DEFAULT_MAJOR_ROOT ;
80 minor_root = DEFAULT_MINOR_ROOT ;
81 }
// display apparatus main root of the selected number of times on standard error device terminal.
82 fprintf (stderr, " Root device is (% d,% d) \ n ", major_root, minor_root); // if the primary number is not equal to 2 (floppy disk) or 3 (a hard disk),
not equal to 0 (default take root device), an error message is displayed exits.
83 if ((major_root! = 2) && (major_root! = 3) &&
84 (Major_root! = 0)) {
85 fprintf (stderr, " Illegal root device (major =% d) \ n ",
86 major_root);
87 die ( ' Bad root device --- major # ");
88 }
// Initialize the buffer buf, all set to zero.
89 for (i = 0; i <sizeof buf ; I ++) buf [I] = 0;
// Open the file specified parameter 1 (bootsect) as read-only, if the error is an error message and exit.
570
13.2 build.c program
571
13.2 build.c program
Minix executable file a.out The head structure is shown below (see minix 2.0 Source 01400 Line start):
struct exec {
unsigned char a_magic [2]; // perform file magic number.
. . .
};
572
13.2 build.c program
GCC Execute the file header structure information see linux / include / a.out.h file.
573
14.1 Overview
14.1 Outline
To cope with Linux 0.11 Core operating principle of learning, this chapter describes the use of PC Machine simulation software and run on the actual computer
Linux 0.11 Systematic approach. These include the kernel compilation process, PC Production methods simulation environment to access and copy files, boot disk and root file
system and Linux 0.11 The method of using the system. Finally it explains how to make a small amount of syntax modifications to the kernel code to the existing RedHat 9 system( gcc
Before starting the experiment, first prepare some useful tools. in Windows The platform can be prepared following software:
WinImage DOS Format a floppy disk image file read and write software.
run Linux 0.11 The best way is to use the system PC Simulation software. Popular world face PC There are simulation software system 3
Species: VMware company's VMware Workstation , Connectix company's Virtual PC (Now the software has been acquired by Microsoft) and open source Bochs (With pronunciation ' box
' the same). This 3 Kinds of software are virtual or simulated Intel x86 Hardware environment that allows us to run a variety of other "guest" operating systems on the system
The scope of use and operating performance, this 3 A simulation software still has some differences. Bochs Simulated x86 Hardware environment and its peripherals, it can
easily be ported to many operating systems on different platforms or architectures. Since the main use of simulation technology, its operating performance and speed to be slower
than the other two software a lot. Virtual PC The performance of the sector in Bochs with VMware Workstation between. It simulates x86 Most, while the other part is the use of
virtual technologies. VMware Workstation Only a few simulation I / O Function, while all other parts are in x86 Performed directly on real-time hardware. That is when a client
operating system requires to execute an instruction, VMware Not a simulation method to simulate this directive, but this instruction "pass" to the actual system hardware to
complete. therefore VMware Yes 3 One of the highest speed and performance types of software. On this 3 Specific differences and performance differences between the kinds of
From the application point of view, if the simulation environment is mainly used for application development, then VMware Workstation with Virtual PC
It may be a better choice. But if you need to develop some low-level system software (such as operating system development and debugging, compiler system development, etc.),
then Bochs It is a good choice. use Bochs You can know the hardware in the simulation environment specifically state the exact timing and execution of the program, rather than the
result of the actual hardware implementation of the system. This is why many operating system developers prefer
Bochs s reason. Therefore, this chapter focuses on the use of Bochs Simulation environment running Linux 0.11 Methods. Currently, Bochs Web site name
http://sourceforge.net/projects/bochs/ . You can download the latest release from the top to the Bochs Software system and many have made a good run disk image
file.
Bochs It is a completely simulation Intel x86 Program of the computer. It can be configured to emulate 386 , 486 , Pentium Or more of the new CPU . Throughout the
implementation process, Bochs Simulation of all instructions, and contains standard PC Peripherals all modules.
574
14.2 Bochs emulation system
due to Bochs Simulation of the entire PC Environment, in which the execution of the software "thinks" that it is running on a real machine. This approach allows us to complete the
Bochs Yes Kevin Lawton to 1994 Started using C ++ Language development software system, is designed to be able to Intel x86 , PPC ,
Alpha , Sun with MIPS Run on the hardware. Regardless of the host running uses what hardware platform, Bochs Still Simulation x86 Software. This is the other two simulation
software can not do. In order to perform any activity on the simulated machine, Bochs You need to interact with the host operating system. When Bochs When a key is pressed the
display window, a keystroke will be sent to the keyboard device processing module. When the simulated machine requires performing a read operation from the analog disk, Bochs Will
perform a read operation from the hard disk image file on the host.
Bochs Software installation is very easy. You can directly from the bochs.sourceforge.net On the site to download Bochs Installation package. If you are using a computer
operating system Windows Is a commonly used software installation process exactly the same. After installation will C Generating a directory on a disc: ' C: \ Program Files \
Bochs-2.1.1 \ ' (The version number of different versions with different). If your system is RedHat
9 Or other Linux System, you can download Bochs of RPM To install the package and as follows:
user $ su
Password:
root # rpm -i bochs-1.2.1.i386.rpm root # exit user $ _
You need to install root Permissions, otherwise you might have to recompile in their own directory Bochs system. In addition, Bochs Need X11
Environment to run, so the system must already be installed X Windows The system can use Bochs . After installing, you can use Bochs
Comes with Linux dlx Packages to test and familiarize yourself with the system. It is also possible from Bochs On the site to download some ready made
Linux Disk image file. Recommended download Bochs On a website SLS Linux Simulation system: sls-0.99pl.tar.bz2 As the founder Linux
0.11 Auxiliary platform simulation system. When creating a new hard disk image file need to use these systems to the hard disk image file to partition and format operations.
About recompiling Bochs Or the system Bochs The method of operation of the installation to other hardware platforms, refer to Bochs User manual for instructions.
In order to Bochs Running an operating system that requires a minimum of resources or some of the following information:
vga bios Image file (e.g., ' VGABIOS-lgpl-latest ' ); At least a boot disk image file (floppy disk,
hard disk or CDROM The image file).
But we often need to pre-set some parameters for the operation of the system during use. These parameters can be uploaded and handed the command line
Bochs Execution of the program, but we usually uses a configuration file (for example, Sample.bxrc ) Is a specialized application to set. In the following description Windows Set
other analog machines. Each simulation systems need to set a corresponding configuration file. If installed Bochs System is
2.1 Or later, then Bochs The system will automatically identify the suffix '. bxrc ' Configuration file, and it will automatically start when double-clicking the file icon Bochs system
running. For example, we can take for the configuration file name ' bochsrc-0.11.bxrc ' . in Bochs There is installed a main directory name ' bochsrc-sample.txt ' A model configuration
file, which lists all the available parameter settings, and with detailed
575
14.2 Bochs emulation system
Instructions. Following is a brief introduction of several parameters in experiments often you want to modify.
1. megs
Contained in the system for setting the analog memory. The default value is 32MB . For example, if we want to simulate machine comprising 128MB System, is required to
megs: 128
2. floppya ( floppyb )
floppya It represents a floppy drive, floppyb It represents the second floppy drive. If you need to boot up from a floppy disk, then floppya
We need to point to a bootable disk. If you want to use the disk image file, write the name of the disk image file later. In many operating systems, Bochs Floppy disk
drive can read and write directly to the host system. To access the actual disk drive, use the device name ( Linux System) or drive letter ( Windows system). You can
also use status To indicate the status of the disk is inserted. ejected
Representation is not inserted, inserted It indicates that the disk has been inserted. Here are a few examples, wherein all the discs are inserted state.
floppya: 1_44 = / dev / fd0, status = inserted # A direct access to the disk under Linux systems 1.44MB.
floppya: 1_44 = b :, status = inserted # Direct access to the disk 1.44MB B win32 system.
floppya: 1_44 = bootimage.img, status = inserted # Pointing to a disk image file bootimage.img.
floppyb: 1_44 = .. \ Linux \ rootimage.img, status = inserted # pointing to the parent directory Linux / under rootimage.img.
In the configuration file, if the parameter of the same name a few lines exist, then only the last row of function parameters.
number. By default, only ata0 It is enabled, and default parameter values as follows:
4. ata0-master ( ata0-slave )
ata0-master It is used to indicate the first simulation system 1 More ATA aisle( 0 A first upper channel connected) 1 More ATA Device (hard drive or CDROM
Wait); ata0-slave The first specified 1 Connecting the first channels 2 More ATA device. As shown in the example below, the meaning of the option configuration wherein, as shown
ata0-master: type = disk, path = hd.img, mode = flat, cylinders = 306, heads = 4, spt = 17, translation = none ata1-master: type = disk, path =
2G.cow, mode = vmware3 , cylinders = 5242, heads = 16, spt = 50, translation = echs ata1-slave:
type = disk, path = 3G.img, mode = sparse, cylinders = 6541, heads = 16, spt = 63, translation = auto
ata2-master: type = disk, path = 7G.img, mode = undoable, cylinders = 14563, heads = 16, spt = 63, translation = lba ata2-slave:
ata0-master: type = disk, path = "hdc-large.img", mode = flat, cylinders = 487, heads = 16, spt = 63 ata0-slave:
type = disk, path = ".. \ hdc-0.11.img", mode = flat, cylinders = 121, heads = 16, spt = 63
576
14.2 Bochs emulation system
biosdetect bios Detection Type [None | auto], Only ata0 on disk Effective [ cmos]
In the configuration ATA The device must be connected to specify the type of device type , May be disk or cdrom . Must also indicate "pathname" equipment path .
"Pathname" may be a hard disk image file, CDROM of iso File or directly to the system CDROM driver. in Linux System, the system can be used as a device Bochs Hard
disk, but due to security reasons, windows In favor of the physical hard disk directly on the system.
For type disk Equipment, options path , cylinders , heads with spt It's required. For type cdrom Equipment, options path It's required.
Disk Transformation program (in the traditional int13 bios Function implemented, and used as DOS This old operating system) can be defined as:
none : No conversion for capacity is less than 528MB ( 1032192 Sectors) of the hard disk;
large : Standard bit shift algorithms for capacity is less than 4.2GB ( 8257536 Sectors) of the hard disk;
rechs : Shift correction algorithm, using 15 Dummy heads physical drive parameters for capacity is less than 7.9GB ( 15,482,880 Sectors) of the hard disk;
lba :standard lba- Aided algorithm. Suitable capacity is less than 8.4GB ( 16,450,560 Sectors) of the hard disk;
auto : Automatically select the best transform scheme. (Analog system will not start if it should be changed).
mode Options for how to use the hard disk image file. It can be one of the following modes:
volatile : A variable redo the flat file. The default value of the
5. boot
boot Machine used to define the simulation for the boot drive. You can specify a floppy disk, hard disk or CDROM . You can also use drive letters' c ' with' a ' . Examples are
as follows:
boot: a
577
14.3 create a disk image file
6. ips ips ( Instructions Per Second ) Specifies the number of instructions per second strip simulation. this is Bochs Running on the host system IPS Value. This value will affect
many event simulation system with time-dependent. Such as changing IPS Value will affect VGA The update rate, and some other systems Simulation evaluation value. It is
necessary to set the value according to the properties of the host used. Refer to Table 14-2 Set.
E.g:
ips: 1000000
7. log
Designation log Pathname can make Bochs Some record log information execution. If the Bochs Running phylogenetic not run correctly, you can refer to the
information which is essential to find out the reason. log Usually set to:
log: bochsout.txt
Disk image file ( Disk Image File ) Is a complete hard disk or floppy disk map information, and save it as a file. Disk image file format to save the information on exactly the
same format as the corresponding disk to store information. Empty disk capacity and disk image file is created we are all the same but the content 0 Of a file. These empty image
file as just bought a new floppy or hard disk, also need to go through partition or / and format to use.
Before making a disk image file, we first need to determine the capacity of the image file is created. For the floppy disk image files, a variety of ( 1.2MB or 1.44MB )
Are fixed capacity. So here mainly describes how to determine the capacity of the hard disk image file you need. Normal hard disk structure composed by a pile of the
metal disc. The upper and lower surfaces of each disc for storing data, and a concentric manner into the entire surface of a dividing tracks, or cylinders called ( Cylinder ).
Thus a need for a disk head ( Head ) Above to read and write data. When the disk rotary head only radial movement can be moved over any of the tracks, it is possible to
access all the active position of the disk surface. Each track is divided into a number of sectors, sector length by the general 256--1024 Bytes. For most systems, are
typically sector length 512 byte. A typical disk structure is shown in 14-1 Fig.
578
14.3 create a disk image file
Top
A sector
Tracks
magnetic head
It is shown a structure with two hard metal disc. So the hard disk has 4 Physical heads. The maximum number of cylinders contained in the production have been
identified. When the hard disk partition and format, the surface of the magnetic media disk is initialized to the specified data format, so that each track (or cylinder) is divided into a
specified number of sectors. So the total number of sectors of the hard disk as follows:
Total number of sectors = hard Physical track number X Physical heads X The number of sectors per track
These parameters will be different with the actual physical parameters of an operating system used in the hard disk or more, referred to as logical parameters. But the total
number of sectors of the parameters calculated with the hard physical parameters must be calculated the same. Due to the design PC Without considering the capacity and
performance of hardware systems developed so fast, ROM BIOS Some drive parameters represent bits used is too small to meet the requirements of actual physical parameters of
the hard disk. Therefore, the current operating system or machine BIOS Measures commonly used is appropriately adjusted in the case where the total number of sectors equal to
the hard disk to ensure the number of tracks, the number of prefixes and the number of sectors per track, in order to meet the requirements of the capabilities and limitations represented. in Bochs
Profile parameters related to the device's hard drive transformation ( Translation ) Option is also provided for this purpose.
We are in Linux 0.11 Production of hard disk system Image When the file, taking into account its own small amount of code, and the use of MINIX
1.5 The maximum capacity of the file system 64MB The restrictions, the maximum size of each hard disk partition can only be 64MB . In addition, Linux 0.11
The system is not support extended partitions, so for a hard disk Image Files, up to 4 Partitions. therefore, Linux 0.11 The system can be used in hard disk Image The maximum
capacity of the file 64 x 4 = 256MB . In the following description, we will have to create a 4 Partitions, each partition is 60MB Hard drive Image Document described as an
example.
For floppy disks, we can see it as having a fixed number (cylinders) of tracks, the number of heads and sectors per track ( spt Sectors Per Track ) Ultra-small hard
disk. For example, capacity 1.44MB Floppy disk parameters 80 Tracks, 2 And have heads per track 18
Sectors, each sector has 512 byte. Its total number of sectors is 2880 The total capacity is 80 x 2 x 18 x 512 = 1474560 byte. Therefore, all production methods described below for
the hard disk image file can be used to create a floppy disk image file. In order to facilitate the narrative, particularly in the absence of that we all collectively referred to as disk
Bochs System with a Image Generation tool " Disk Image Creation Tool "( bximage.exe ). It can be used to make floppy and hard disk space Image file. And the emergence of
running Image When you create the interface, the program first prompted to select the need to create Image Type (hard disk hd Or floppy disk fd ). If the hard disk is created, there
will be prompted for hard disk Image of mode Types of. Usually only need to select their default values flat It can be. Then you need to create input Image capacity. Corresponding to
the hard disk the program displays the parameters: number of cylinders (track number, the head number and the number of sectors per track, and requests a Image Name of the file.
Program generated Image After the file is displayed for a Bochs Profile settings configuration information for the hard disk parameters. Write down this information and edit the
579
14.3 create a disk image file
================================================== ======================
bximage
Disk Image Creation Tool for Bochs
$ Id: bximage.c, v 1.19 2003/08/01 01:20:00 cbothamy Exp $ ============================
============================================ Do you want to create a floppy disk image or a hard disk
image? Please type hd or fd. [hd]
Enter the hard disk size in megabytes, between 1 and 32255 [10] 256
Writing: [] Done.
If you already have a capacity to meet the requirements of the hard disk Image File, you can directly copy the file to generate a different Image
file. Then the file can be processed according to their own requirements. To create a floppy disk Image The procedure is similar to the above documents, but also prompts you to
select the type of floppy tips. Similarly, if you have other floppy disk Image File, then copy the direct method can be.
14.3.2 in Linux Under the system uses dd Create a command Image file.
As already explained, the newly created Image It is a full file content is 0 Just empty file its capacity consistent with the requirements. Therefore, we can first calculate the
capacity requirements Image Number of sectors in the file, and then use dd Command to generate a corresponding Image file.
For example, we want to build a number of cylinders 520 The number of heads is 16 , The number of sectors per track is 63 Hard drive Image File, the total number of its
1.44MB floppy disk Image files for which the number of sectors is 2880, so the command is:
580
14.4 Information access disk image file
14.3.3 use WinImage create DOS Format a floppy disk Image file
WinImage Is a DOS format Image File access and creation tools. Double-click DOS floppy disk Image Icon files can browse, delete or add files inside. In
addition, it is also used for browsing CDROM of iso file. use WinImage Create a floppy disk
Image It may be generated with a time DOS Formats Image file. Methods as below:
a) run WinImage . select "Options-> Settings" Menu, select one of the Image Settings page. Set up Compression
b) create Image file. Select the menu File-> New Will pop up a floppy disk format selection box. Select capacity 1.44MB
Format.
c) Select the boot sector properties menu item Image-> Boot Sector properties , Click the dialog box MS-DOS Button.
d) save document.
Note that the "Save as type" in Save File dialog box, be sure to select " All files (*. *) " Otherwise created Image File will contain some WinImage Own information, which will
result in Image Documents Bochs Under it is not working. Can be determined by looking at the length of the newly created file Image does it reach the requirement. standard 1.44MB
File length is greater than this value, in strict accordance with the method used to re-create or UltraEdit And other binary editor to remove the extra bytes. Delete operations as
follows:
use UltraEdit Opened in binary mode Image file. The disk image file first 511 , 512 Byte 55, AA Two hexadecimal digits, we push down 512 Bytes,
delete all bytes before that. For this time MSDOS5.0 As the boot disk is concerned, the first few bytes of the file should look like "EB 3C 90 4D ..." .
Then drop down on the right scroll bar to move img At the end of the file. delete "... F6 F6 F6" All the data back. Generally speaking is to remove from 0x168000
All data begins. When the operation is complete the last line should be complete row "F6 F6 F6 ..." . Save and exit to use this Image Files.
Bochs To simulate the analog system external storage device, all files are saved in the operating system simulation are floppy or hard disk devices in the image file format
used in the disk image file. Thus to bring the host operating system and Bochs Problems are exchanged information between the analog system. although Bochs The system can
be configured to direct the host to use a floppy disk drive, CDROM And other physical device drivers to run, but the use of such information exchange method is relatively
cumbersome. Therefore it is best to directly read and write Image Information in the file. If you need to add a file, put the file into the operating system to be simulated in Image File.
If you want to remove the files from Image File read. However, due to save Image Not only the information in the file is located in a corresponding format floppy or hard disk, but
also to store a certain file system format. Therefore access Image Program information file must be able to identify where the file system to operate. For the application of this
chapter, we need some tools to identify Image File MINIX and / or) DOS File system format.
Generally speaking, if the file length and simulation systems exchange is relatively small, we can use a floppy disk Image File as a medium of exchange. If there are large
quantities of files need to be removed or placed in the analog system from an analog system, then we can use the existing Linux System to operate. Here are several ways from
The use of tools to read and write disk image access information floppy disk image files (small files or split files) in Linux The main use of the
environment loop Devices to access information in the hard disk image file. (Large quantities of information exchange) use iso File format for
A floppy disk Image File, we can exchange a few files with the analog system. Provided that the simulation system support DOS
581
14.4 Information access disk image file
Reading and writing floppy disk format (e.g., by mtools command). In the following example to illustrate the specific methods of operation.
Prior to read and write files, you need to be prepared first according to a previously described method 1.44MB Image File (the file name is the assumption
diskb.img ). And modify Linux 0.11 of bochs.bxrc Profile, floppya Add the following line of information the following parameters:
I.e. an increase of the system to the analog 2 More 1.44MB Floppy disk device, and the device corresponding to Image The file name is diskb.img . If you want to Linux 0.11 A
file system is taken out, so now you can double-click the icon to start running configuration file Linux 0.11
system. Entering Linux 0.11 After the system, use DOS Floppy disk read and write tool mtools The hello.c The first written document 2 A floppy disk Image
in. If the floppy disk Image It is to use Bochs Created or has not been formatted, you can use mformat b: Command to format it first.
Exit now Bochs System and use WinImage turn on diskb.img File, WinImage The main window will have a hello.c
File exists. Select the file with your mouse and drag it to the desktop to complete the entire operation takes files. If a file requires the input to an analog system, then just
existing Linux System (for example, RedHat 9 ) To access a variety of file systems, including the use of loop File in the file system to access the storage device. For
floppy disk Image File, we can directly use mount Command to load Image The file system read and write access. For example, we need access rootimage-0.11 Files, as long
[ Root @ a plinux ImagesRF Royalty Free] # mount -t minix rootimage-0.11 / mnt -o loop
among them mount Command - t minix Option indicates the type of file system is read MINIX - o loop Option Description by loop Device to load the file system. If you need to
access DOS Format a floppy disk Image File, simply mount Command in the File Type Options minix Replaced msdos It can be.
If you want to access the hard disk Image File, then the process operation different from the above. Since the floppy disk Image General image file contains a complete file
system, it can be used directly mount Command loads the floppy disk Image The file system, but the hard disk Image Generally contain partition information file, and the file system
is built in each partition. That we can put the hard drive of each partition as a complete "big" floppy disk.
Therefore, in order to access a hard disk Image Information files in a partition, we need to first understand the hard disk Image File partition information to determine the
need to access partitions Image Starting file offset position. On the hard disk Image File partition information, we can use the simulation system is running fdisk View command,
you can view here, too. Here in the following package includes a hard disk
582
14.4 Information access disk image file
Image file hdc-0.11.img An example to illustrate where the first visit 1 The method of file system a partition.
http://oldlinux.org/Linux.old/bochs/linux-0.11-devel-040329.zip
It should be used loop The device is provided with a control command losetup . This command is mainly used to block a normal file or a device
loop Associated with the device, or for releasing a loop Device, a query loop Status of the device. Detailed description of the command refer to the online manual pages.
First execute the following command hdc-0.11.img Files with the loop1 Associate, and use fdisk Command to view the partition information therein.
from above fdisk Partition information given can be seen that Image File containing only 1 Partitions. Note of the starting sector of the partition (i.e., the partition table Start A
bar content). If you need to access the hard drive with multiple partitions Image , Then you need to remember the starting sector number associated partition.
Next, let's use losetup of- d Options to hdc-0.11.img Files with the loop1 The association is released, it re-associate
hdc-0.11.img Paper 1 At the start position of the partition. This requires the use losetup of- o Option, which specifies the byte offset associated with the starting position. Partition
information is apparent from the above, where the first 1 Beginning offset partitions is 1 * 512 byte. In the first 1 Partitions and
loop1 After the re-association, we can use mount Command to access its files.
After the partition of the file system access end, and finally uninstall and remove the association.
583
14.5 Production root file system
Goal of this section is to establish a root file system on the hard disk. Although oldlinux.org It can be downloaded on to floppy and hard disks have produced a good root file
system Image File, but it was still the production process is described in detail again, for them to learn. In the production process can also refer Linus Base: INSTALL-0.11 . Before
making the root file system disk, we must first download rootimage-0.11 with
http://oldlinux.org/Linux.old/images/bootimage-0.11-20040305
http://oldlinux.org/Linux.old/images/rootimage-0.11-20040305
Modify these two files into easy to remember bootimage-0.11 with rootimage-0.11 And the establishment of a special called Linux-0.11
Subdirectory. In the production process, we need to copy rootimage-0.11 Some in the execution of the program and use the floppy disk bootimage-0.11 Boot disk to start the
simulation system. So before you started work on the root file system, you first need to confirm've been able to run both Floppy
Linux When booting, the default file system is the root file system. Which typically include some of the following subdirectories and files:
dev / Containing a special device file, the file manipulation statements using the operation device;
bin / Storage system executes the program. E.g sh , mkfs , fdisk Wait;
Storage device file system is the file system device. For example, for general use Windows2000 Operating system, hard drive C Disk is a file system device, and the file on
the hard disk storage according to certain rules on the composition of the file system, Windows2000 Have NTFS or FAT32
And other file systems. and Linux 0.11 Supported by the kernel file system MINIX 1.0 File system.
For hard disk created above Image File, also can be used before it must be partition and create a file system. The usual practice is hard to need to be addressed Image Documents
attached to Bochs Under the existing analog system (e.g., the above-mentioned SLS Linux ), Then use the simulation system for the new command Image File for processing. The
following assumes that you have installed SLS Linux Analog system, and the system is stored in the name SLS-Linux Subdirectory. We use it to create the above 256MB hard disk Image
file hdc.img
Partition and create MINIX File system. We will in this Image Create a file 1 Partitions, and to establish MINIX File system. We perform the following steps:
1. in SLS-Linux Under the same directory as the establishment of a name Linux-0.11 Subdirectory, the hdc.img Move a file to the directory.
2. enter SLS-Linux Directory, edit SLS Linux systematic Bochs Profiles bochsrc.bxrc . in ata0-master Plus a line under
Into our hard drives Image Configuration parameters line of the file:
ata0-slave: type = disk, path = .. \ Linux-0.11 \ hdc.img, cylinders = 520, heads = 16, spt = 63
3. Exit the editor. Double-click bochsrc.bxrc Icon, run SLS Linux Analog system. In the event Login When the prompt, type ' root '
584
14.5 Production root file system
And press Enter. If at this time Bochs Can not operate normally, generally due to the profile information is incorrect, please re-edit the configuration file.
4. use fdisk Command hdc.img File establish 1 Partitions. Below is the establishment of the first 1 Partition command sequences. Build another 3 More
The process is similar to this partition. due to SLS Linux The default partition type is to support the establishment of MINIX2.0 File System 81 Types of( Linux / MINIX ), It is
necessary to use fdisk of t The command type modified 80 ( Old MINIX )Types of. Note here that we have put hdc.img Hook into SLS Linux Under the first system 2 A hard
disk. according to Linux 0.11 For naming the hard disk, the hard disk should be the overall device name / dev / hd5 (See Table 14-3 ). But from Linux 0.95 Hard disk version
began naming rules have been modified to use the current rules, so SLS Linux Lower Dir 2 The whole hard disk device name is / dev / hdb .
585
14.5 Production root file system
5. Keep in mind that the number of data block partition size (here 65015 ), When you create a file system will be used to this value. When the partition is set up
After, as you typically would need to reboot the system to allow SLS Linux System kernel can correctly identify the newly added partition.
6. Re-enter SLS Linux After the simulation system, we use mkfs The first command just created 1 Create a partition on MINIX File system
System. As shown in the following command information. It has created here 64000 Partition data block (a data block 1KB byte).
So far, we have completed in hdc.img The first file 1 Partitions created in the working file system. Of course, establishing create a file system can also be run Linux
0.11 Establish the root file system on the floppy disk. Now we can use that partition as a root file system build.
We can SLS Linux of Bochs Profiles bochsrc.bxrc copy to Linux-0.11 Directory, and then the same as above modified content. Need special attention floppya ,
ata0-master with boot ,This 3 Parameter must be consistent with the above.
Now double-click the configuration file with the mouse. First of all Bochs Map display window should appear 14-2 In the picture.
586
14.5 Production root file system
At this point you should click on the menu bar ' CONFIG ' Icon to enter Bochs Settings window (need to use the mouse to click in order to put the window to the front).
587
14.5 Production root file system
The first modification 1 The floppy disk settings to point to rootimage-0.11 plate. Then press the Enter key continuously, until the last line window set ' Continuing simulation ' until.
At this time, and then switch to Bochs Run window. Click the Enter key after the formal entry into the Linux
Since the floppy disk capacity is too small, to make Linux 0.11 The system can really do something, then you need a hard disk (here it refers to the hard disk Image
Create a root file system on the file). We have already established a 256MB Hard drive Image file hdc.img , And at this time it connected to a running Bochs Environment,
If you do not see this message, state your Linux 0.11 The configuration file is not set correctly. Please re-edit bochsrc.bxrc File, and re-run Bochs Systems, described
We have in front hdc.img The first 1 The establishment of the partitions MINIX File system. If not built or want to try the side of it, then type the following
Now you can start to load the file system on the hard drive. Execute the following command to load the new file system to / mnt Directory.
588
14.5 Production root file system
[/ Usr / root] # cd /
After loading the file system on the hard disk partition, we can copy the root file system on a floppy disk to the hard drive. Execute the following command:
[/] # cd / mnt
> do
> cp + recursive + verbose / $ i $ i done
At this time, all the files on the floppy disk root file system is copied into the file system on the hard disk. Many like the following message appears during the copying
process.
Now that you have established a good basic root file system on the hard disk. You can look everywhere in the new file system. And then uninstall the hard disk file system,
and type ' logout ' or' exit ' drop out Linux 0.11 system. The following information is displayed:
[/ Mnt] # cd /
[/] # logout
root] #
Once you are on the hard disk Image Establish good file on a file system, you can make Linux 0.11 With its start as the root file system. This is achieved by modifying the
boot disk bootimage-0.11 The first file 509 , 510 Content bytes can be achieved. Please to follow these steps.
1. First Copy bootimage-0.11 with bochsrc.bxrc Two documents, produce bootimage-0.11-hd with bochsrc-hd.bxrc file.
2. edit bochsrc-hd.bxrc Profile. To which ' floppya: ' File name on the modified ' bootimage-0.11-hd ' And save.
589
14.6 0.11 compiled on Linux 0.11 kernel system
3. use UltraEdit Or any other modifications binary file editor ( winhex Etc.) Edit bootimage-0.11-hd binary file.
The first modification 509 , 510 Byte (original value should be 00 , 00 )for 01 , 03 , Represents the root file system device on the hard disk Image First 1
A partition. Then save and exit. If the file system is installed in a different partition, you need to modify ago 1 Bytes corresponding to your partition.
You can now double-click bochsrc-hd.bxrc Configuration icon file, Bochs The system should quickly enter Linux 0.11 And shows the system of FIG. 14-5 In graphics.
At present author has been re-established with a gcc 1.40 Compiler environment Linux 0.11 System software package. The system is arranged to
Bochs Run simulation system and have configured the appropriate bochs Profile. The package can be obtained from the address below.
http://oldlinux.org/Linux.old/bochs/linux-0.11-devel-040329.zip
The package contains a README , Which described the package and usage of all files. If your system has been installed bochs System, you can
simply double-click configuration file bochs-hd.bxrc The hard disk icon to run Image File as the root file system Linux 0.11 . in/ usr / src / linux Directory type ' make
' Command can be compiled Linux 0.11 Kernel source, and generates a boot image file Image . If you need to output this Image Files can be backed up first bootimage-0.11-hd
File, then
590
14.7 In Redhat 9 system kernel compile Linux 0.11
Use the following command will put bootimage-0.11-hd Replaced with the new boot file. Direct Restart Bochs You can use the new compiler generated bootimage-0.11-hd To
linux] #
You can also use mtools Command of the new generation Image The first written document 2 A floppy disk image file diskb.img And then use software tools WinImage will diskb.img
If you want to start a new guide Image Root file system on the floppy disk files rootimage-0.11 Used together, first edit before compilation Makefile File, use
It can usually be completed very smoothly when compiling the kernel. Possible problem is that the compiler gcc Identification parameter is not '- mstring-ins' ,this is Linus To
compile yourself gcc Do extended experimental parameters, you can delete all Makefile In this parameter and then recompile the kernel. Another possible problem can not be
found gar Command, and the can / usr / local / bin / Under the ar Direct link or copy / renamed
initial Linux The operating system kernel is in Minix 1.5.10 The extended version of the operating system Minix-i386 On cross-compiler development.
Minix 1.5.10 The version of the operating system is included with the AS Tanenbaum of" Minix Design and Implementation, "a book first 1 A version with Prentice Hall
Offering. This version of Minix Although it can run 80386 And compatible microcomputer, but did not use 80386 of 32 Bit mechanism. In order to carry out on the system 32 Bit
operating system development, Linus used Bruce Evans The patch will upgrade it to MINIX-386 And put GNU A series of development tools gcc , gld , emacs , bash And other
transplanted to Minix-386 on. On this platform, Linus Cross-compile, develop Linux 0.01 , 0.03 , 0.11 Other versions of the kernel. The authors have based on Linux The article
describes the mailing list, established a similar Linus At that time development platform, and successfully compile Linux Early versions of the kernel (see http://oldlinux.org Introduction
forum).
However, due to Minix 1.5.10 Outdated, but the establishment of the development platform is very cumbersome, so here only briefly explain how to modify the Linux 0.11 Version
of the kernel source code, so that it can be used in the current RedHat 9 Compile the operating system standard compiler environment, that can be run boot image file bootimage .
Readers can in general PC Machine or Bochs Run it and other virtual machine software. Here are the only major modification terms, all the tools can be used to modify the
Department diff After comparing modified and unmodified code before, to find out the difference.
591
14.7 In Redhat 9 system kernel compile Linux 0.11
If, over the unmodified code linux Directory, the modified code linux-mdf , You need to execute the following command:
Which documents dif.out That is included in the code all over the place modifications. It has been modified and can be good at RedHat 9 Under compiled Linux 0.11 Kernel source
http://oldlinux.org/Linux.old/kernel/linux-0.11-040327-rh9.tar.gz
http://oldlinux.org/Linux.old/kernel/linux-0.11-040327-rh9.diff.gz
When a good start with a floppy boot image file compilation, the following information should be displayed on the screen:
If the "display Loding system ... " After no response, indicating that the hard disk controller does not recognize the kernel subsystem in the computer. You can find an
old-fashioned PC Machine to try again, or use vmware , bochs And other virtual machine software testing. When asked to insert the root disk, if simply press the Enter key, the root
file system information can not be loaded, and the crash appears. To run a complete
linux 0.11 Operating system, you also need to match with the root file system, to oldlinux.org Download a use on the site.
http://oldlinux.org/Linux.old/images/rootimage-0.11-for-orig
in Linux 0.11 Kernel code file, almost every subdirectory includes a makefile File, they need to make the following modifications:
a. will gas => as, gld => ld . just now gas with gld It has been renamed called directly as with ld A.
b. as ( original gas) I have not - c Option, so to Makefile, It is necessary to remove it - c Compiler option. In the main kernel directory Linux
Options. in 94 Year gcc Manual had not found - fcombine-regs Options, and - mstring-insns Yes Linus On their own
gcc The modification increases the options so you and me gcc This certainly does not include the optimization options.
d. in gcc Compiler flags options, increase - m386 Options. In this way RedHat 9 Under compile the kernel image file is not
contain 80486 And above CPU Instruction, so that the core can run 80386 On the machine.
as86 The compiler does not recognize c Comment statement language, it is necessary to use! Commented boot / bootsect.s File C Comment statement.
in boot Three assembler in the directory, align The method used at present statement has changed. original align Value refers to the back belt of the power of the value
from memory location, and now needs to be given an integer value from address directly. Therefore, the original statement:
592
14.7 In Redhat 9 system kernel compile Linux 0.11
. align 3
. align 8
Because of the as Continuous improvement, which is currently increasing degree of automation, and therefore do not need to be manually specify a variable used
CPU register. Thus kernel code __ asm __ ( "ax") All need to be removed. E.g fs / bitmap.c The first file 20 Row, 26 Row,
Embedded assembly code, also need to remove all of the contents of the register is invalid declaration. E.g include / string.h B 84 Row:
:);
In the development Linux 0.11 Used in the assembler, in reference C You need to add the program variables in the variable name with an underscore character '_', and the
current gcc The compiler can be used to identify those compiled directly referenced c Variable, it is necessary to compile a program (including an embedded assembler statement)
all c Remove the underscore before the variable. E.g boot / head.s The first program 15 Line statement:
We need to change:
We need to change:
Before entering protected mode, you can use ROM BIOS middle int 0x10 Call display information on the screen, but after entering the protected mode, which can not use the
interrupt calls. In order to understand the state of internal data structures and the protected mode kernel operating environment, we can use the following function data check_data32
() 5 . Although the kernel printk () Display function, but it needs to call tty_write (),
In the kernel is not fully up and running this function can not be used. This one check_data32 () Function can print what you're interested in on the screen after entering the
protected mode. Page feature only use it or not, does not affect the results, because virtual memory 4M Within just use the first page table directory entry, and the page table
directory from the physical address 0 Start, plus the kernel data segment base address 0 ,and so 4M The range, the same virtual memory and physical memory and linear memory
address. linus This may also be had advisedly, that this setting more convenient to use ☺ .
Embedded assembler statements using the method, see 5.4.3.1 Section below.
/*
* Effects: on screen display with a 32-bit hexadecimal integer.
* pos -- Screen position, character width of 16 units, for example 2, i.e., the display 32 indicates the start of the character width at the upper left corner.
* Returns: None.
* If you are using assembler, to ensure that the function is compiled and linked into the kernel .gcc usage compilation is as follows:
* pushl pos // pos use your actual data instead of, for example pushl $ 4
* pushl value // pos and value can be any valid addressing modes
593
14.8 kernel debugging using the bochs
* call check_data32
*/
inline void check_data32 (int value, int pos) {
__asm__ __volatile __ ( % // 0 - value containing the value to be displayed; ebx - screen position.
"Shl $ 4, %% ebx \ n \ t " // the pos value multiplied by 16, the start address of the display memory plus VGA,
"Addl $ 0xb8000, %% ebx \ n \ t " // ebx obtained display character position in the upper left corner of the screen to start.
"Andl %% eax, %% edx \ n \ t " Take edx eax // specified has 4 bits.
"Shr %% cl, %% edx \ n \ t " // right 28, 4-bit value that is taken in edx.
"Add $ 0x30, %% dx \ n \ t " // This value is converted into ASCII code.
"Cmp $ 0x3a, %% dx \ n \ t " // If the 4-bit value is less than 10, the forward jump to numeral 2.
"Jb2f \ n \ t" "add
$ 0x07, %% dx \ n " // Otherwise, plus 7, to convert the value to a corresponding character A-F.
"Movw %% dx, (%% ebx) \ n \ t " // display the value into memory.
"Sub $ 0x04, %% cl \ n \ t " // prepare a hexadecimal display, the right number of bits minus 4.
"Cmpl $ 0x0, %% eax \ n \ t " // right end has moved out of the mask value (8 have been displayed in hexadecimal)?
594
references
references
[1] Intel Co. INTEL 80386 Programmer's Reference Manual 1986, INTEL CORPORATION, 1987. [2]
James L. Turley. Advanced 80386 Programming Technigues. Osborne McGraw-Hill, 1988. [3] Brian W. Kernighan, Dennis M. Ritchie. The C programming Language.
Prentice-Hall 1988. [4] Leland L. Beck System Software:. An Introduction to Systems Programming, 3 nd. Addison-Wesley, 1997. [5] Richard M. Stallman, Using and Porting the GNU
Compiler Collection, the Free Software Foundation, 1998. [6] The Open Group Base Specifications Issue 6 IEEE Std 1003.1-2001, The IEEE and The Open Group. [7] David A
Rusling, The Linux Kernel, 1999. http://www.tldp.org/ [8] Linux Kernel Source Code , http://www.kernel.org/ [9] Digital co.ltd. VT100 User Guide, http://www.vt100.net/ [10] Clark L.
Coleman. Using Inline Assembly with gcc. Http://oldlinux.org/Linux.old/ [11] John H. Crawford, Patrick P. Gelsinger. Programming the 80386. Sybex, 1988. [12] FreeBSD Online
Manual, http://www.freebsd.org/cgi/man.cgi [13] Andrew S.Tanenbaum The Luyou Shan, Shi Zhenchuan translation, operating system Tutorial MINIX Design and Implementation.
World Publishing Company, 1990.4 [14] Maurice J. Bach , And Chen Bao Jue, Wang Xu, willow pure record, Feng translated snow-capped mountains, UNIX Operating system design.
Machinery Industry Press, 2000.4 [15] John Lions With, Jinyuan translation, Leon's UNIX Source code analysis, Machinery Industry Press, 2000.7 [16] Andrew S. Tanenbaum The Translation,
operating system, Wang Peng, Jinyuan et al: Design and Implementation (first 2 Version), Electronic Industry Press, 1998.8 [17] Alessandro Rubini , Jonathan With, Wei Yongming,
Luo Gang, Jiang Jun translation, Linux Device drivers, China Electric Power Press, 2002.11 [18] Daniel P. Bovet, Marco Cesati With, Chen Lijun, Feng Rui, cattle Xinyuan translation,
in-depth understanding LINUX Kernel, China Electric Power Press 2001. [19] Chang Tsai Hung. Microcomputers ( PC Series) interface control tutorial, Tsinghua University Press, 1992.
[20] Li Fenghua, ZHOU Li-hua, Zhao Lisong. MS-DOS 5.0 Core analysis. Xi'an University of Electronic Science and Technology Press, 1992. [21] RedHat 7.3 Online manual operating
system. http://www.plinux.org/cgi-bin/man.cgi [22] W.Richard Stevens The Jinyuan such as translation, UNIX High-level programming environment. Machinery Industry Press, 2000.2
[23] Linux Weekly Edition News. Http://lwn.net/ [24] PJ Plauger. The Standard C Library. Prentice Hall, 1992 [25] Free Software Foundation. The GNU C Library. Http://www.gnu.org/
2001 [26] Chuck Allison. The Standard C Library. C / C ++ Users Journal CD-ROM, Release 6. 2003 [27] Bochs simulation system. Http://bochs.sourceforge.net/
595
Appendix 1 constant major core
appendix
# define TASK_ZOMBIE 3 // process is in a dead state, has stopped running, but the parent process has not signaled.
Two drives all logical device number shown in the table below.
--596--
Appendix 1 constant major core
among them 0x300 with 0x305 Which does not correspond to the partition, but on behalf of the entire hard disk. From linux Kernel 0.95 After using this version is
no longer cumbersome naming, but now using the same naming method.
--597--
Appendix 2 kernel data structures
Here lists the main focus of the kernel data structures, and gives a brief description, specify the file and the specific location of each structure is located. As you read
reference.
1. Execute the file structure a.out ( include / a.out.h The first 6 Row)
a.out ( Assembly out ) Executable file header format structure.
struct exec {
unsigned long a_magic // perform file magic number. Use N_MAGIC and other macro access.
unsigned a_bss // length uninitialized data area in the file, the number of bytes.
unsigned a_syms // the length of the symbol table file, the number of bytes.
unsigned a_trsize // the code length of relocation information, the number of bytes.
};
struct flock {
short l_type; // lock type (F_RDLCK, F_WRLCK, F_UNLCK).
short l_whence; // start offset (SEEK_SET, SEEK_CUR or SEEK_END).
off_t l_start; // blocked at the start of the lock. Relative offset (number of bytes).
off_t l_len; // blocked Locked size; if it is 0, compared to the end of the file.
struct sigaction {
void (* sa_handler) (int);
sigset_t sa_mask; int
sa_flags;
void (* sa_restorer) (void);};
sa_handler Action is to be taken for a signal corresponding to the specified. Above may be SIG_DFL ,or SIG_IGN To ignore this signal may be a pointer to a function of
sa_mask Given mask on the signal, when the signal blocking program execution processing of these signals. In addition, the signal causes the trigger signal processing will
sa_restorer Restore function pointer from the library Libc Provided, for cleaning the user mode stack.
struct winsize {
--599--
Appendix 2 kernel data structures
struct termio {
unsigned short c_iflag; // input mode flag.
unsigned short c_oflag; // output mode flag.
unsigned short c_cflag; // control mode flag.
unsigned short c_lflag; // local mode flag.
unsigned char c_line; // line discipline (rate).
unsigned char c_cc [ NCC ]; // control character array.
};
POSIX of termios Structure (first 54 Row). Wherein the data length of the control character NCC = 17 .
struct termios {
unsigned long c_iflag; // input mode flag.
unsigned long c_oflag; // output mode flag.
unsigned long c_cflag; // control mode flag.
unsigned long c_lflag; // local mode flag.
unsigned char c_line; // line discipline (rate).
unsigned char c_cc [ NCCS ]; // control character array.
};
Two terminals defined above data structure termio with termios Respectively in two categories UNIX Series (or carved Long), termio It is in AT & T
system V Defined, and termios Yes POSIX Standard specified. Two structure is basically the same, just termio Using the short integer type definition mode flag is set, and termios With
a length of custom mode flag set. Due to the current two structures are in use, so for compatibility, most systems are at the same time support them. In addition, previously used a
struct tm {
int tm_sec; // the number of seconds [0,59].
};
7. File access / modify the structure ( include / utime.h The first 6 Row)
struct utimbuf {
time_t actime; // file access time. From 1970.1.1: 0: 0: 0 Number of seconds to start.
time_t modtime; // file modification time. From 1970.1.1: 0: 0: 0 Number of seconds to start.
--600--
Appendix 2 kernel data structures
};
8. Buffer header structure buffer_head ( include / linux / fs.h The first 68 Row)
Buffer header data structure. Commonly used in the program bh To represent buffer_head Abbreviations type of the variable.
struct buffer_head {
char * b_data; // pointer to the data block (data block of 1024 bytes).
unsigned long b_blocknr; // block numbers.
unsigned short b_dev; // number of data source devices (not represented by 0).
unsigned char b_uptodate; // update flag: Indicates whether the data has been updated.
unsigned char b_count; // Use the number of users of the data block.
9. Memory disk inode structure ( include / linux / fs.h The first 93 Row)
This is in memory i Node structure. On-disk inode structure d_inode It includes only the first 7 item.
struct m_inode {
unsigned short i_mode; // file type and attributes (rwx bits).
unsigned short i_uid; // user id (file owner identifier).
unsigned long i_size; // File Size (bytes).
unsigned long i_mtime; // file modification time (from 1970.1.1: 0, counting seconds).
unsigned short i_zone [9]; // Direct (0-6), indirect (7) or double indirectly (8) a logical block number. // zone is meant the
10. File Structure ( include / linux / fs.h The first 116 Row)
File structure for the file handle i Establish a relationship between the nodes.
struct file {
unsigned short f_mode; // file operation mode (RW bit)
--601--
Appendix 2 kernel data structures
11. Disk superblock structure ( include / linux / fs.h The first 124 Row)
Superblock structure memory disk. Superblock structure on disk d_super_block It includes only the first 8 item.
struct super_block {
unsigned short s_ninodes; // nodes.
unsigned short s_nzones; // number of logical blocks.
unsigned short s_zmap_blocks; // logical block number of data blocks occupied by the bitmap.
unsigned short s_firstdatazone; // first logical block number of data. unsigned short s_log_zone_size; // log (block
number / logical blocks). (Base 2). unsigned long s_max_size;
The maximum length // file.
struct buffer_head * s_imap [8]; // i node bitmap buffer block pointer array (occupying 8, may represent a 64M). struct buffer_head *
s_zmap [8]; // bitmap logic block buffer block pointer array (occupying 8). unsigned short s_dev;
// super block device number is located.
struct m_inode * s_isup; // i root node of the file system is mounted. (Isup-super i)
struct m_inode * s_imount; // i is attached to the node.
unsigned long s_time; // Change the time.
12. Directory entry structure ( include / linux / fs.h The first 157 Row)
File directory entry structure.
struct dir_entry {
unsigned short inode; // i node.
char name [ NAME_LEN ]; // file name.
};
13. Hard disk partition table structure ( include / linux / hdreg.h The first 52 Row)
Hard disk partition table structure. See the following list information.
struct partition {
unsigned char boot_ind; // boot flags. 0x80- bootable operating system partition.
unsigned char head ; // partition start head number.
unsigned char sector ; // start sector number of the partition (bits 0-5) and the starting cylinder number upper 2 bits (bits 6-7).
unsigned char cyl; // starting cylinder number of the partition the lower 8 bits.
unsigned char sys_ind; // partition type byte. 0x0b-DOS; 0x80-Old Minix; 0x83-Linux
unsigned char end_head; // end head number partition.
unsigned char end_sector; // end sector number (bits 0-5) and an end cylinder 2 bits (bits 6-7) is high.
unsigned int start_sect; // partition start physical sector number (the count starts from 0).
--602--
Appendix 2 kernel data structures
};
In order to realize a plurality of operating systems to share resources hard disk, the hard disk can be logically divided into 1--4 Partitions. Between the sector number of each
partition are contiguous. The partition table 4 Table entries, each entry is made 16 Byte, information corresponding to a partition, partition size and storing the start and end of the
cylinder number, track number, sector number and the guide mark. Stored in the hard disk's partition table 0 cylinder 0 Head first 1 Sectors 0x1BE - 0x1FD
struct desc_struct { // define data structures segment descriptor. The structure described only each description
unsigned long a, b; // operator is composed of 8 bytes, a total of each descriptor table 256.
} desc_table [256];
15. i387 Use of structure ( include / linux / sched.h The first 40 Row)
This is a structural math coprocessor used, mainly for the save process when switching i387 The execution status information.
struct i387_struct {
long cwd; // Control Word (Control word).
long swd; // Status word (Status word).
long twd; // marker word (Tag word).
long fip; // coprocessor code pointers.
long fcs; // coprocessor code segment register.
16. Task state segment structure ( include / linux / sched.h The first 51 Row)
Task State Segment data structure (see Appendix).
struct tss_struct {
long back_link; / * 16 high bits zero * /
long esp0;
long ss0; / * 16 high bits zero * /
long esp1;
long ss1; / * 16 high bits zero * /
long esp2;
long ss2; / * 16 high bits zero * /
long cr3;
long eip;
long eflags; long
eax, ecx, edx, ebx; long
esp;
long ebp;
long esi; long
edi;
long es; / * 16 high bits zero * /
long cs; / * 16 high bits zero * /
long ss; / * 16 high bits zero * /
long ds; / * 16 high bits zero * /
long fs; / * 16 high bits zero * /
--603--
Appendix 2 kernel data structures
17. Process (task) data structure task ( include / linux / sched.h The first 78 Row)
This is the task (process) data structure, otherwise known as the process descriptor.
struct task_struct {
long state // task of running state (-1 inoperable, 0 run (ready),> 0 has stopped).
long counter // task running time count (decrement) (ticks), run time slice.
long priority // Run priority number. When the task starts running counter = priority, the greater the long run.
long signal // signal. Bitmap, each bit represents a signal, the signal value of the bit offset value = +1.
struct sigaction sigaction [32] // flag information signal and performs the operation attribute structure, a corresponding signal will be executed. long blocked
int exit_code // task exit code execution stops, the parent process will take.
unsigned long end_data // the code length + data length (number of bytes).
18. tty Pending queue structure ( include / linux / tty.h The first 16 Row)
--604--
Appendix 2 kernel data structures
struct tty_queue {
unsigned long data; // wait queue buffer pointer current data (number of characters [??]). // For serial
};
extern struct tty_struct tty_table []; // tty structure array.
20. File status structure ( include / sys / stat.h The first 6 Row)
struct stat {
dev_t st_dev; // number of the file containing the device.
off_t st_size; // file size (in bytes) (if the file is a regular file).
time_t st_atime; // last (last) access time.
time_t st_mtime; // Last Modified.
time_t st_ctime; // node last modified time.
};
twenty one. File access and modification time structure ( include / sys / times.h The first 6 Row)
struct tms {
time_t tms_utime; // CPU time used by the user.
time_t tms_stime; // system (core) CPU time.
time_t tms_cutime; User CPU time // child process terminated used.
time_t tms_cstime; The system CPU time // child process terminated used.
};
--605--
Appendix 2 kernel data structures
struct ustat {
daddr_t f_tfree; The total number of free blocks // System.
};
The last two fields are not in use, always return NULL pointer.
twenty three. System name of the header file ( include / sys / utsname.h The first 6 Row)
struct utsname {
char sysname [9]; // name of the version of the operating system.
char nodename [9]; // associated with the realization of the network node name.
};
twenty four. Block device configuration requested item ( kernel / blk_drv / blk.h The first twenty three Row)
The following is the structure of a queue entry request. Which if dev = -1 , Then do not use that. struct request {
struct buffer_head * Bh; // buffer header pointer (include / linux / fs.h, 68).
struct request * Next; // points to the next request entry.
};
--606--
Appendix 3 80x86 protection operating mode
1.80386 Outline
80386 Is an advanced 32 Bit microprocessor, designed for multi-tasking operating system, and for applications requiring high performance design.
32 Bit registers and data channels support 32 Bit addressing modes and data types, the processor can address up to 4GB As well as physical memory 64TB ( 2 46 Bytes) of virtual
memory. On-chip memory management include address translation registers, advanced multitasking hardware protection mechanisms and paged virtual memory mechanism.
Below for system programming, an overview of the use of 80386 These basic principles.
System designed for programming system registers include the following categories:
Flag register EFALGS ; Memory management register; control register; debug register; test register. System flag register EFLAGS Controls I / O , Maskable
interrupt, virtual debugging, task switching and protection mode and multi-tasking environments 8086 Execution of the program. Where the main symbol see photos 1 Fig.
31 twenty three 15 7 0
R IO O D I T S Z
000000000000O0V
M F0N T PL F F F F F F0A F0P F1C F
Wherein the system flags: VM - virtual 8086 mode; RF - Recovery signs; NT - Nested task flag; IO PL - I / O Privileged class notation;
Memory management registers have 4 One for the segment memory management:
• TR - Task register. Wherein the first two registers ( GDTR, LDTR) Pointing to descriptor table GDT with LDT . IDTR Register points to interrupt vector table.
80386 A total of 4 Control registers, respectively, CR0 , CR1 , CR2 with CR3 . See attached format 2 Fig.
31 twenty three 15 7 0
Reserved
CR1
Reserved
P Reserved E T E M P
G Reserved T S M P E CR0
--607--
Appendix 3 80x86 protection operating mode
Control register CR0 Containing overall control flag system. among them:
• PE - Protected Mode open position ( Protection Enable , Bit 0 ). If this bit set, it will cause the processor to start running in protected mode.
• MP - Coprocessor existence flag ( Math Present , Bit 1 ). For control WAIT Function instruction to run with the co-processing.
• EM - Simulation Control ( Emulation , Bit 2 ). Indicates whether the need for emulation coprocessor.
• TS - Task switching ( Task Switch , Bit 3 ). Whenever a task switch processor will set this bit and the test bit coprocessor instructions
explained before.
• ET - Extension type ( Extention Type , Bit 4 ). This bit indicates the type of co-processor system contained (YES 80287
still is 80387 ).
• PG - Paging operations ( Paging , Bit 31 ). This bit indicates whether the page tables using the linear address into a physical address.
Memory management mainly related to memory addressing mechanism processors. 80x86 The two-step segment forms a logical address into a physical address of the
physical memory.
• Converting section, a logical address composed of selectors and offsets by the inner segment to segment a linear address;
• Page conversion to convert the linear address to a physical address corresponding to the. This step is optional.
When paging is turned on, and by the conversion section converts the foregoing pages together, i.e. the two conversion stages to achieve from a logical address to a
physical address.
Drawings 3 The processor is shown how to convert a logical address into a linear address. During the conversion process CPU Use the following data structures:
• Selectors ( Selectors );
• Segment register ( Segment Registers ).
15 0 31 0
logical address: Selectors Offset
Descriptor Table
Base address
directory descriptor +
--608--
Appendix 3 80x86 protection operating mode
1.4 Descriptor
Descriptor to CPU Providing the information to map the logical address to a linear address necessary. Descriptor is a program compiler, linker, loader or operating system
created. The following figure shows two general Format Descriptor. All types of descriptors having one of these two formats. The meaning of each field of the segment descriptor
31 twenty three 15 7 0
AVL TYPE
Base address (BASE) Length limit (LIMIT) Base address (BASE)
GXO P DPL 1 4
bits 31..24 bits 19..16 bits 23..16
A
The base address (BASE) bits 15..0 Segment length limit (LIMIT) bits 15..0 0
31 twenty three 15 7 0
AVL
Base address (BASE) Length limit (LIMIT) Base address (BASE)
GXO P DPL 0 TYPE 4
bits 31..24 bits 19..16 bits 23..16
The base address (BASE) bits 15..0 Segment length limit (LIMIT) bits 15..0 0
Base address ( BASE ): In the definition section 4GB Linear position in space. Three parts of the processor will be combined into a group address 32
Bit value. Segment limit long ( LIMIT ): Defines the maximum length of the segment. Processor indefinite length segments form a two part composition 20 Bit value. The
processor will be based on particle size ( Granularity Value) of the bit field to interpret the actual meaning of the segment limit field length: when to 1 A byte as a unit, is
defined as the maximum 1MB Length in bytes; when to 4KB A byte as a unit, is defined as the maximum 4GB Length in bytes. In the long-time load value will be left 12 Bit.
Graininess( Granularity ): Specifies the length field value means limit the meaning of the representative. When is 0 , The limit value of unit length 1 Bytes; when the bit 1 When
the unit is indefinite length 4KB byte. Types of( TYPE ): Used to distinguish the various types of descriptors. Descriptor privilege level ( Descriptor Privilege Level - DPL ): For
protection. A total of 4 level: 0-3 . 0 Level is the highest privilege level, 3 Level is the lowest privilege level. Paragraph presence bits ( Segment-Present bit - P ): If this bit is
zero, then the descriptor is invalid for the address transformation process. When the point descriptor segment selector is loaded into the register, the processor will send
an abnormality signal. Access Bit ( Accessed bit - A ): When a processor accesses through the segment will set this bit.
Descriptor is stored in the descriptor table, the descriptor table there are two types:
• Local Descriptor Table ( Local descriptor table - LDT ). Descriptor table by 8 A memory array entry descriptor in bytes of the configuration, see FIG.
5 Fig. Descriptor table is variable in length, containing up to 8192 ( 2 13 ) Descriptor. But for GDT Table, which is the first descriptor (Index 0 ) Is not used.
--609--
Appendix 3 80x86 protection operating mode
1N+2N+3M
The processor is through the use of GDTR with LDTR Location register GDT And the current table LDT table. This register contains the length of the two descriptor table in a
linear base address and the address table. instruction lgdt with sgdt For access GDTR Registers; Instruction lldt with sldt
For access LDTR register. lgdt Using a memory 6 Operand bytes to load GDTR Register. The first two bytes represent the length of the descriptor table, after 4 Byte base
address is described in the descriptor table. Note, however, visit LDTR An instruction register lldt As used operand is a 2 Byte operand representing global descriptor table GDT
A character selector item description. The selectors corresponding GDT Descriptor table entries should correspond to a local descriptor table. Meaning selectors see FIG. 6 Explained.
31 twenty three 15 7 0
Selector is part of the logical address for designating a descriptor, which is designated by a descriptor table in which the index and a descriptor entry completed. Drawings 7
Index value ( Index) : Used to select descriptor table specifies 8192 A description of a character. The index value is multiplied by the processor 8( Byte length descriptor),
plus the descriptor table and the base address to access the segment descriptor specified in the table.
Table indicator ( Table Indicator - TI) : Specify the selection identifier descriptor table referenced. Value 0 Indicates that the specified GDT Table, value 1 Indicates that the
15 3210
Index TI RPL
(INDEX)
--610--
Appendix 3 80x86 protection operating mode
due to GDT A first table entry (index value 0) Is not used, therefore an index value having 0 Table indicator value and also 0 Selectors (i.e. directed GDT First
selector) may be used as a blank ( null) Selectors. When a segment register (not a CS
or SS ) Loading empty when a selector, and the processor will not generate an exception. However, if the use of this segment will register an exception when accessing memory.
For the segment registers are initialized to fall into the accident has not been used in reference to, this feature is very useful.
Processor information descriptor is stored in segment registers, and thus avoid the query descriptor table each time a memory access. Each segment
register has a "visible" part and a "invisible" part, see Fig. 8 Fig. The visible part of the segment address register is operated by a program, as if they are simply 16
Loading operation of these registers using a common program instructions that can be divided into two categories:
1. Direct load instructions; e.g., MOV , POP , LDS , LSS , LGS , LFS . These instructions refers explicitly specified segment
register.
2. Implicit load instruction; e.g., far call CALL And far jump JMP . These instruction implicitly references CS Segment register, and with
The new value is loaded into CS in. These instructions will use the program 16 Bit selector loaded into the visible portion of the segment register, the processor will
automatically breaks a base address in the descriptor table from the description, segment limit length, type, and other information is loaded into the invisible part of the
CS
SS
DS
ES
FS
GS
2. Transform page
In the second stage of address translation, CPU Converts linear addresses into physical addresses. Address translation at this stage to achieve the basic functions of
page-based virtual memory and paging system level protection. Page change this step is optional, only set up conversion page CR0 of PG Function bits after the bit is initialized when
the software provided by the operating system. If you need to implement multiple virtual operating system 8086 Task-based protection mechanisms paging or page-based virtual
A physical memory page frame address is contiguous 4K Byte units. It byte boundaries, fixed size.
A linear address specified by the page table, the page table and a page in the page offset value to point to a corresponding physical address indirectly. Drawings 9 It
--611--
Appendix 3 80x86 protection operating mode
Drawings 10 It shows a method to convert linear processor address into a physical address. By using two page tables, a linear processor address field of the page
directory ( DIR) , Page field ( PAGE) And an offset field ( OFFSET) Translated into a corresponding physical address. Addressing mechanism uses page directory field value as an
index of the linear address of the page directory, the page table field using the index value as specified in the page table directory pages, using a page table offset field as
Linear Address: Page directory page table entry page offset value
CR3
Just a simple page table 32 An array of page bit indicator. Page table itself is also a memory, so it contains 4K Bytes of memory, can hold 1K More 32 Bit key.
This uses two page tables to locate a memory page. The highest level is a page directory, page directory can be positioned up to 1K Second-level page table, and each page
table may be located up to two 1K Memory pages. Therefore, a page directory location of all page tables that can be addressed 1M Memory page ( 2 20 ). Since each page contains a
memory 4K byte( 2 12 ), A final page directory specified by the page table can be addressed 80386 The entire physical address space ( 2 * 20 2 12 = 2 32 ).
Current physical address of the page directory is stored in CPU Control register CR3 In, this register is also called a page directory base address register ( page directory
base register - PDBR ). Memory management software can choose to use a directory page, or a page directory for each task using only all the tasks, you can also use a
A page table page table entry used by all levels are the same, see Fig format 11 Fig.
31 12 11 0
U/ R/
Page frame address bits 31..12 Available
P
(PAGE FRAME ADDRESS) (AVAIL) 0 0 DA 0 0
S W
Among them, the page frame address ( PAGE FRAME ADDRESS) It specifies a physical memory starting address. Because the memory pages are located 4K
On the border, so its low 12 Bit is always 0 . In a page directory, the page frame address of the page table entry is the starting address of a page table; in a second stage page
table, the page frame address of the page table entry contains the page frame address of the desired memory operation.
Presence bits ( PRESENT - P ) To determine whether a page table entry can be used to address the conversion process. P = 1 It indicates that the item is available. When a
directory entry or a second entry level P = 0 , Then when the entry is invalid, address translation can not be used. At this time, all other than the entry
--612--
Appendix 3 80x86 protection operating mode
Special bits are available to the program; processor these bits are not tested.
when CPU When trying to use a page table entry for address translation, if any at this time a page table entry P = 0 , The processor will send abnormal signals page. For
software support paged virtual memory system, the page does not exist ( page-not-present) The exception handler can put the requested page into physical memory. At this time,
I visited ( Accessed - A ) And modified ( Dirty - D ) Bit provides information about the pages used. In addition to the modified bits of the page directory entries, these bits
Before a memory read or write operation, the processor has access to the provision of the relevant bits and secondary directory page table entry. Before a write to an
address covered by the page table entry two, the processor will set the two page table entry modified bit, and the page directory entry is modified bit unused. When demand for
memory exceeds the actual amount of physical memory, it supports paged virtual memory operating system can use these bits to determine which pages can be removed from
memory. The operating system must be reset and is responsible for detecting these bits.
Read / Write bit ( Read / Write - R / W ) And user / super user bits ( User / Supervisor - U / S ) Are not used for address conversion, but for protecting the mechanism of the
paging stage, while the processor is operating in the address translation process.
In order to increase the maximum efficiency of address conversion, the processor recently used page table data stored in the cache on the chip. Operating system
designers must refresh the cache when the current page table change, you can use one of two ways:
3. Multitasking( Multitasking )
In order to provide an effective, multi-tasking mechanism protected, 80x86 Use some special data structure. Support multi-task operation of registers and data
structures main task state segment ( Task State Segment ) And task register ( Task register ). Using these data structures, CPU It can quickly switch from one task to perform
• Wherein the read-only information processor set static field (the gray portion in the drawing);
• Each dynamic field is set when a task switching processor will update. Figure SS0: ESP0 Task stack pointer for storing run-time kernel mode. SS1: ESP1 with SS2:
ESP2 Respectively correspond to the privileged class run 1 with 2 When using the stack pointer, the two privilege levels in Linux Not used. And the task operating in the user
31 twenty three 15 7 0
0,000,000,000,000,000 GS 5C
0,000,000,000,000,000 FS 58
0,000,000,000,000,000 DS 54
0,000,000,000,000,000 SS 50
0,000,000,000,000,000 CS 4C
0,000,000,000,000,000 ES 48
EDI 44
ESI 40
--613--
Appendix 3 80x86 protection operating mode
EBP 3C
ESP 38
EBX 34
EDX 30
ECX 2C
EAX 28
0,000,000,000,000,000 SS2 18
ESP2 14
0,000,000,000,000,000 SS1 10
ESP1 0C
0,000,000,000,000,000 SS0 08
ESP0 04
Task State Segment TSS It may be in any position of the linear space. TSS Like other segments, using the descriptor is defined. access TSS Descriptor task
switching will result. Thus, in most systems will descriptor DPL (Descriptor privilege level) field is set to the highest privilege level 0 , So switching trusted software to
perform tasks can allow only. TSS Descriptor in global descriptor table only GDT in.
visible and non-visible part of the section. Visible portion of selectors for GDT Select a table TSS Descriptor, the processor used to store the invisible portion of the base address
and the segment limit value descriptor length. instruction LTR with STR A visible part modifications and read task register operands used by the instruction is a 16 Bit selector.
In addition, there is an offer for TSS Indirect, task gate descriptor references the protected ( Task Gete Descriptor ). This descriptor is the descriptor base address bits in a
general format 15..0 Field (first 3 , 4 Byte) is stored in a TSS Descriptor selector, and using which the privilege level field ( DPL) Usage rights to control descriptor is performing task
switching. See below for the interrupt descriptor table IDT DESCRIPTION descriptor.
In the following 4 Kind of case, CPU You will switch tasks performed:
1. A reference to the current task execution TSS Descriptor JMP or CALL instruction;
2. A reference to the current task execution of a task gate JMP or CALL instruction;
3. He cited the interrupt descriptor table ( IDT ) Task door interrupt or exception;
4. When nested task flag NT When set, a current task execution IRET instruction.
Interrupt and exception control is a special type of conversion. They alter the normal program flow away for further processing events (e.g., external events, error reporting,
or exception condition). The main difference is that interrupt the abnormal commonly used in the treatment interruption CPU External asynchronous events, and abnormal
--614--
Appendix 3 80x86 protection operating mode
It is the process CPU In the implementation process itself detected the problem.
There are two external interrupt sources: the CPU of INTR Maskable interrupt input pin and NMI The non-maskable interrupt input pin. Similarly, there are two types of
anomalies: the CPU Detected erroneous, or abandon the trap event and the programmed "soft interrupt" (such as INT 3 Instructions, etc.).
The processor using the identification number (interrupt number) to identify each type of interrupt or exception. The processor can identify nonmaskable interrupt NMI
And an abnormality identification number is determined in advance, the range 0 To 31 ( 0x00-0x1f ). At present, these numbers do not all use, undetermined number of Intel The
Maskable interrupt identification number of the interrupt by an external controller (e.g. 8259A Programmable Interrupt Controller) is determined, and CPU The notification
interrupt identification stage CPU . 8259A The interrupt number assigned can be programmed to specify the range of usable identification number is 32 To 255
( 0x20-0xff ). Linux The system will 32-47 Assigned to the maskable interrupt, the remaining 48-255 Used to identify other soft interrupt. when Linux
Interrupt Descriptor Table ( Interrupt Descriptor Table - IDT ) Each interrupt or exception processing corresponding event identification numbers and program instructions
associated with a character described. versus GDT with LDT similar, IDT Is a 8 Byte descriptor array, but its 1 A descriptor may contain items. Processor interrupt number by
multiplying the number of abnormal 8 To index IDT In the corresponding descriptor. IDT It can be located anywhere in physical memory. The processor is using IDT register( IDTR ) To
locate IDT of. Modify and copy IDT Instruction is LIDT with SIDT . versus GDT Like operating table, IDT Also use 6 Byte data memory address as an operand. The first two bytes long
In the interrupt descriptor table IDT It may contain any of a three descriptor:
• Trap Door ( Trap gates ); Drawings 13 Given the task gate, doors and trap doors
31 twenty three 15 7 0
31 twenty three 15 7 0
31 twenty three 15 7 0
--615--
Appendix 3 80x86 protection operating mode
Just like CALL Command can call a procedure or task as an interrupt or exception can "call" interrupt handler, the program is a process or a task. When
an interrupt or exception, CPU Use interrupt or exception identification number to index IDT Descriptor table. in case CPU When the index to break a door or trap
door, it calls the process; if it is a task gate, it will cause a task switch.
Interrupt gate or trap doors indirectly point to a process that will be executed in the context of the current mission. Gate descriptor segment selector points GDT Or current LDT
The executable segment descriptor. Offset field value gate descriptor points to the beginning of the interrupt or exception handling process.
80X86 Executing an interrupt or exception handling process with the way CALL Instruction calls a procedure is very similar, but slightly different both in the use of the stack.
Before the original interrupt instruction pointer onto the stack, the original flag register EFLAGS The content is pushed onto the stack. For the segment-related abnormalities, CPU An
For the interrupt process ends the processing returns to operation, the interrupt return instruction IRET versus RET Similar, but IRET To remove the push-down stack EFLAGS
Interrupt gate and trap doors difference is that the interrupt enable flag IF Impact. By the interrupt vector door interruptions caused by reset IF Because other interrupts
interfere with the current process to avoid interruptions. Subsequent IRET Instruction will be restored from the stack IF The original value; without interruption change generated by
IDT Table task gate descriptor indirectly points to a task state segment TSS . Task gate descriptor segment selector points GDT
Table a TSS Descriptor. When an interrupt or generate abnormal point IDT In a task gate descriptor, it will cause the task switching, interrupt processing which will separate
task. Linux The system does not use the task gate descriptor.
--616--
appendix
16 10 DLE 59 3B ; 102 66 f
17 11 DC1 60 3C < 103 67 g
18 12 DC2 61 3D = 104 68 h
19 13 DC3 62 3E > 105 69 i
20 14 DC4 63 3F ? 106 6A j
twenty one 15 NAK 64 40 @ 107 6B k
twenty two 16 SYN 65 41 A 108 6C l
twenty three 17 ETB 66 42 B 109 6D m
twenty four 18 CAN 67 43 C 110 6E n
25 19 EM 68 44 D 111 6F o
26 1A SUB 69 45 E 112 70 p
27 1B ESC 70 46 F 113 71 q
28 1C FS 71 47 G 114 72 r
29 1D GS 72 48 H 115 73 s
30 1E RS 73 49 I 116 74 t
31 1F US 74 4A J 117 75 u
32 20 (Space) 75 4B K 118 76 v
33 twenty one ! 76 4C L 119 77 w
34 twenty two " 77 4D M 120 78 x
35 twenty three # 78 4E N 121 79 y
36 twenty four $ 79 4F O 122 7A z
37 25 % 80 50 P 123 7B {
38 26 & 81 51 Q 124 7C |
39 27 ' 82 52 R 125 7D }
40 28 ( 83 53 S 126 7E ~
41 29 ) 84 54 T 127 7F DEL
42 2A * 85 55 U
--617--
index
index
Since the kernel code is relatively large, a lot of variables / functions to be used / called in a lot of program source code, and therefore more difficult to index them. This index
gives the definition of its main program file name, line number and page numbers based on a variable or function name.
__GNU_EXEC_MACROS__ include / a.out.h, 4, Pretreatment __NR_fstat include / unistd.h, 88, Pretreatment is defined as
__LIBRARY__ init / main.c, 7, Pretreatment is defined __NR_ftime include / unistd.h, 95, Pretreatment is defined as
as macro macro
lib / close.c, 7, Pretreatment is defined as macro __NR_getegid include / unistd.h, 110, Pretreatment is defined as
lib / _exit.c, 7, Pretreatment is defined as macro __NR_geteuid include / unistd.h, 109, Pretreatment is defined as
macro
lib / open.c, 7, Pretreatment is defined as macro
__NR_getgid include / unistd.h, 107, Pretreatment is defined as
lib / execve.c, 7, Pretreatment is defined as macro
macro
lib / setsid.c, 7, Pretreatment is defined as macro
__NR_getpgrp include / unistd.h, 125, Pretreatment is defined as
lib / string.c, 13, Pretreatment is defined as macro
macro
lib / wait.c, 7, Pretreatment is defined as macro
__NR_getpid include / unistd.h, 80, Pretreatment is defined as
lib / write.c, 7, Pretreatment is defined as macro
macro
__NR_access include / unistd.h, 93, Pretreatment is defined as
__NR_getppid include / unistd.h, 124, Pretreatment is defined as
macro
macro
__NR_acct
__NR_getuid include / unistd.h, 84, Pretreatment is defined as
include / unistd.h, 111, Pretreatment is defined as macro
macro
__NR_alarm
__NR_gtty include / unistd.h, 92, Pretreatment is defined as
include / unistd.h, 87, Pretreatment is defined as macro
macro
__NR_break
__NR_ioctl include / unistd.h, 114, Pretreatment is defined as
include / unistd.h, 77, Pretreatment is defined as macro
macro
__NR_brk
__NR_kill include / unistd.h, 97, Pretreatment is defined as
include / unistd.h, 105, Pretreatment is defined as macro
macro
__NR_chdir
__NR_link include / unistd.h, 69, Pretreatment is defined as
include / unistd.h, 72, Pretreatment is defined as macro
macro
__NR_chmod include / unistd.h, 75, Pretreatment is defined as
__NR_lock include / unistd.h, 113, Pretreatment is defined as
macro
macro
__NR_chown include / unistd.h, 76, Pretreatment is defined as
__NR_lseek include / unistd.h, 79, Pretreatment is defined as
macro
macro
__NR_chroot
__NR_mkdir include / unistd.h, 99, Pretreatment is defined as
include / unistd.h, 121, Pretreatment is defined as macro
macro
__NR_close
__NR_mknod include / unistd.h, 74, Pretreatment is defined as
include / unistd.h, 66, Pretreatment is defined as macro
macro
__NR_creat
__NR_mount include / unistd.h, 81, Pretreatment is defined as
include / unistd.h, 68, Pretreatment is defined as macro
macro
__NR_dup
__NR_mpx include / unistd.h, 116, Pretreatment is defined as
include / unistd.h, 101, Pretreatment is defined as macro
macro
__NR_dup2
__NR_nice include / unistd.h, 94, Pretreatment is defined as
include / unistd.h, 123, Pretreatment is defined as macro
macro
__NR_execve include / unistd.h, 71, Pretreatment is defined as
__NR_open include / unistd.h, 65, Pretreatment is defined as
macro
macro
__NR_exit
__NR_pause include / unistd.h, 89, Pretreatment is defined as
include / unistd.h, 61, Pretreatment is defined as macro
macro
__NR_fcntl
__NR_phys include / unistd.h, 112, Pretreatment is defined as
include / unistd.h, 115, Pretreatment is defined as macro
macro
--618--
index
include / unistd.h, 102, Pretreatment is defined as macro __NR_utime include / unistd.h, 90, Pretreatment is defined as
__NR_prof macro
include / unistd.h, 104, Pretreatment is defined as macro __NR_waitpid include / unistd.h, 67, Pretreatment is defined as
__NR_ptrace macro
include / unistd.h, 86, Pretreatment is defined as macro __NR_write include / unistd.h, 64, Pretreatment is defined as
__NR_read macro
include / unistd.h, 63, Pretreatment is defined as macro __va_rounded_size include / stdarg.h, 9, Pretreatment is
__NR_rmdir macro
include / unistd.h, 100, Pretreatment is defined as macro _BLK_H kernel / blk_drv / blk.h, 2, Pretreatment is defined as macro
__NR_setgid
include / unistd.h, 106, Pretreatment is defined as macro _BLOCKABLE kernel / sched.c, 24, Pretreatment is defined
__NR_setsid
include / unistd.h, 126, Pretreatment is defined as macro _CONFIG_H include / config.h, 2, Pretreatment is defined as
__NR_setuid macro
include / unistd.h, 83, Pretreatment is defined as macro _CONST_H include / const.h, 2, Pretreatment is defined as
__NR_setup macro
include / unistd.h, 60, Pretreatment is defined as macro _ctmp include / ctype.h, 14, Defined as a variable
__NR_sgetmask include / unistd.h, 128, Pretreatment is defined
--619--
index
include / sys / wait.h, 7, Pretreatment is defined as macro _S include / ctype.h, 9, Pretreatment is defined as macro
_I_FLAG
kernel / chr_drv / tty_io.c, 29, Pretreatment is defined as macro kernel / sched.c, 23, Pretreatment is defined as macro
_L _SC_ARG_MAX include / unistd.h, 33, Pretreatment is defined
include / ctype.h, 5, Pretreatment is defined as macro as macro
_L_FLAG _SC_CHILD_MAX include / unistd.h, 34, Pretreatment is
kernel / chr_drv / tty_io.c, 28, Pretreatment is defined as macro defined as macro
_LDT _SC_CLOCKS_PER_SEC include / unistd.h, 35, Pretreatment
include / sched.h, 156, Pretreatment is defined as macro is defined as macro
_LOW _SC_JOB_CONTROL include / unistd.h, 38, Pretreatment is
include / sys / wait.h, 6, Pretreatment is defined as macro defined as macro
_MM_H _SC_NGROUPS_MAX include / unistd.h, 36, Pretreatment is
include / mm.h, 2, Pretreatment is defined as macro defined as macro
_N_BADMAG include / a.out.h, 36, Pretreatment is defined _SC_OPEN_MAX include / unistd.h, 37, Pretreatment is
as macro defined as macro
_N_HDROFF include / a.out.h, 40, Pretreatment is defined as _SC_SAVED_IDS include / unistd.h, 39, Pretreatment is
macro defined as macro
_N_SEGMENT_ROUND include / a.out.h, 95, Pretreatment _SC_VERSION include / unistd.h, 40, Pretreatment is defined
is defined as macro as macro
_N_TXTENDADDR include / a.out.h, 97, Pretreatment is _SCHED_H include / sched.h, 2, Pretreatment is defined as
_PC_CHOWN_RESTRICTED include / unistd.h, 51, Pretreatment _set_seg_desc include / asm / system.h, 42, Pretreatment is defined as
defined as macro
_PC_NAME_MAX include / unistd.h, 46, Pretreatment is include / time.h, 10, Pretreatment is defined as macro
defined as macro include / stddef.h, 10, Pretreatment is defined as macro
_PC_NO_TRUNC include / unistd.h, 49, Pretreatment is
include / string.h, 9, Pretreatment is defined as macro
defined as macro
_SP include / ctype.h, 11, Pretreatment is defined as macro
_PC_PATH_MAX include / unistd.h, 47, Pretreatment is
defined as macro
_STDARG_H include / stdarg.h, 2, Pretreatment is defined as
_PC_PIPE_BUF include / unistd.h, 48, Pretreatment is defined
macro
as macro
_STDDEF_H include / stddef.h, 2, Pretreatment is defined as
_PC_VDISABLE include / unistd.h, 50, Pretreatment is defined
macro
as macro
_STRING_H_ include / string.h, 2, Pretreatment is defined as
_POSIX_CHOWN_RESTRICTED include / unistd.h, 7, Pretreatment
macro
is defined as macro
_SYS_STAT_H include / sys / stat.h, 2, Pretreatment is defined
_POSIX_NO_TRUNC include / unistd.h, 8, Pretreatment is
as macro
defined as macro
_SYS_TYPES_H include / sys / types.h, 2, Pretreatment is defined
_POSIX_VDISABLE include / unistd.h, 9, Pretreatment is
as macro
defined as macro
_SYS_UTSNAME_H include / sys / utsname.h, 2, Pretreatment is
_POSIX_VERSION include / unistd.h, 5, Pretreatment is
defined as macro
defined as macro
_SYS_WAIT_H include / sys / wait.h, 2, Pretreatment is defined
_PTRDIFF_T
as macro
include / sys / types.h, 15, Pretreatment is defined as macro
_syscall0
--620--
index
include / unistd.h, 133, Pretreatment is defined as macro include / termios.h, 133, Pretreatment is defined as macro
_TERMIOS_H include / termios.h, 2, Pretreatment is defined as B150 include / termios.h, 138, Pretreatment is defined as macro
macro
include / time.h, 5, Pretreatment is defined as macro B200 include / termios.h, 139, Pretreatment is defined as macro
_TIMES_H
include / sys / times.h, 2, Pretreatment is defined as macro B2400 include / termios.h, 144, Pretreatment is defined as macro
_TSS
include / sched.h, 155, Pretreatment is defined as macro B300 include / termios.h, 140, Pretreatment is defined as macro
_TTY_H
include / tty.h, 10, Pretreatment is defined as macro B38400 include / termios.h, 148, Pretreatment is defined as macro
_U
include / ctype.h, 4, Pretreatment is defined as macro B4800 include / termios.h, 145, Pretreatment is defined as macro
_X
include / ctype.h, 10, Pretreatment is defined as macro B75 include / termios.h, 135, Pretreatment is defined as macro
ABRT_ERR
include / hdreg.h, 47, Pretreatment is defined as macro B9600 include / termios.h, 146, Pretreatment is defined as macro
access function
include / unistd.h, 189, Defined as a function prototype bad_rw_intr kernel / blk_drv / hd.c, 242, Defined as a
acct function
include / unistd.h, 190, Defined as a function prototype BADNESS fs / buffer.c, 205, Pretreatment is defined as
add_request macro
kernel / blk_drv / ll_rw_blk.c, 64, Defined as a function BCD_TO_BIN init / main.c, 74, Pretreatment is defined
add_timer as macro
include / sched.h, 144, Defined as a function prototype beepcount kernel / chr_drv / console.c, 697, Defined as a variable
alarm blk_dev
include / unistd.h, 191, Defined as a function prototype kernel / blk_drv / ll_rw_blk.c, 32, defined as struct Types of
kernel / chr_drv / tty_io.c, 17, Pretreatment is defined as macro blk_dev_init init / main.c, 46, Defined as a function
argv prototype
init / main.c, 165, Defined as a variable kernel / blk_drv / ll_rw_blk.c, 157, Defined as a function
argv_rc blk_dev_struct kernel / blk_drv / blk.h, 45, defined as struct Types
init / main.c, 162, Defined as a variable of
asctime block_read fs / read_write.c, 18, Defined as a function
kernel / chr_drv / console.c, 77, Defined as a variable BLOCK_SIZE include / fs.h, 49, Pretreatment is defined
B0 as macro
--621--
index
BLOCK_SIZE_BITS include / fs.h, 50, Pretreatment is include / termios.h, 132, Pretreatment is defined as macro
block_write prototype
fs / read_write.c, 19, Defined as a function prototype cfgetospeed include / termios.h, 217, Defined as a function
include / fs.h, 176, Defined as a function prototype cfsetospeed include / termios.h, 219, Defined as a function
bottom prototype
kernel / chr_drv / console.c, 73, Defined as a variable change_ldt fs / exec.c, 154, Defined as a
bounds function
kernel / traps.c, 48, Defined as a function prototype change_speed kernel / chr_drv / tty_ioctl.c, 24, Defined as a
bread function
fs / buffer.c, 267, Defined as a function CHARS include / tty.h, 30, Pretreatment is defined as macro
bread_page fs / buffer.c, 296, Defined as a chdir include / unistd.h, 194, Defined as a function prototype
function
include / fs.h, 190, Defined as a function prototype check_disk_change fs / buffer.c, 113, Defined
breada as a function
fs / buffer.c, 322, Defined as a function include / fs.h, 168, Defined as a function prototype
include / fs.h, 191, Defined as a function prototype chmod include / sys / stat.h, 51, Defined as a function prototype
brelse
fs / buffer.c, 253, Defined as a function include / unistd.h, 195, Defined as a function prototype
include / fs.h, 188, Defined as a function prototype chown include / unistd.h, 196, Defined as a function prototype
brk
include / unistd.h, 192, Defined as a function prototype chr_dev_init init / main.c, 47, Defined as a function
BRKINT prototype
include / termios.h, 84, Pretreatment is defined as macro kernel / chr_drv / tty_io.c, 347, Defined as a function
bucket_desc lib / malloc.c, 52, defined as struct Types clear_block fs / bitmap.c, 13, Pretreatment is defined as
of macro
buffer_block include / fs.h, 66, Defined as CLOCAL include / termios.h, 161, Pretreatment is defined as macro
a type
BUFFER_END include / const.h, 4, Pretreatment is defined clock include / time.h, 30, Defined as a function prototype
as macro
buffer_head include / fs.h, 68, defined as struct Types clock_t include / time.h, 16, Defined as a type
of
buffer_init fs / buffer.c, 348, Defined as a CLOCKS_PER_SEC include / time.h, 14, Pretreatment is
include / fs.h, 31, Defined as a function prototype close include / unistd.h, 198, Defined as a function prototype
BUSY_STAT include / hdreg.h, 31, Pretreatment is defined as CODE_SPACE mm / memory.c, 49, Pretreatment is defined
macro as macro
CBAUD con_init
--622--
index
include / tty.h, 66, Defined as a function prototype fs / exec.c, 46, Defined as a function
kernel / chr_drv / console.c, 617, Defined as a function CRTSCTS include / termios.h, 163, Pretreatment is defined as macro
con_write
include / tty.h, 73, Defined as a function prototype crw_ptr fs / char_dev.c, 19, Defined as a type
coprocessor_error kernel / traps.c, 58, Defined as a CS5 include / termios.h, 152, Pretreatment is defined as macro
function prototype
coprocessor_segment_overrun kernel / traps.c, 52, Defined CS6 include / termios.h, 153, Pretreatment is defined as macro
as a function prototype
copy_mem kernel / fork.c, 39, Defined as a CS8 include / termios.h, 155, Pretreatment is defined as macro
function
copy_page csi_at
mm / memory.c, 54, Pretreatment is defined as macro kernel / chr_drv / console.c, 391, Defined as a function
function csi_L
copy_strings fs / exec.c, 104, Defined as a kernel / chr_drv / console.c, 401, Defined as a function
function csi_m
copy_to_cooked include / tty.h, 75, Defined as a function kernel / chr_drv / console.c, 299, Defined as a function
prototype csi_M
kernel / chr_drv / tty_io.c, 145, Defined as a function kernel / chr_drv / console.c, 421, Defined as a function
macro
kernel / chr_drv / console.c, 411, Defined as a function
function
CSTOPB include / termios.h, 156, Pretreatment is defined as macro
CPARENB
include / termios.h, 158, Pretreatment is defined as macro
ctime include / time.h, 36, Defined as a function prototype
CPARODD
include / termios.h, 159, Pretreatment is defined as macro
include / termios.h, 110, Pretreatment is defined as macro current_drive kernel / blk_drv / floppy.c, 115, Defined as a
CREAD variable
include / termios.h, 157, Pretreatment is defined as macro CURRENT_TIME include / sched.h, 142, Pretreatment is
include / unistd.h, 199, Defined as a function prototype current_track kernel / blk_drv / floppy.c, 120, Defined as a
create_block fs / inode.c, 145, Defined as a d_inode include / fs.h, 83, defined as struct Types of
function
d_super_block include / fs.h, 146, defined as struct Types
include / fs.h, 177, Defined as a function prototype
of
create_tables
--623--
index
DEFAULT_MAJOR_ROOT tools / build.c, 37, Pretreatment divide_error kernel / traps.c, 43, Defined as a function
DEFAULT_MINOR_ROOT tools / build.c, 38, Pretreatment DMA_READ include / fdreg.h, 68, Pretreatment is defined as
kernel / blk_drv / blk.h, 81, Pretreatment is defined as macro do_divide_error kernel / traps.c, 97, Defined as
DEVICE_NAME kernel / blk_drv / blk.h, 63, Pretreatment is defined do_double_fault kernel / traps.c, 87, Defined as
as macro a function
kernel / blk_drv / blk.h, 71, Pretreatment is defined as macro do_execve fs / exec.c, 182, Defined as a
function
kernel / blk_drv / blk.h, 80, Pretreatment is defined as macro
do_exit kernel / exit.c, 102, Defined as a function
device_not_available kernel / traps.c, 50, Defined as a
function prototype
kernel / blk_drv / blk.h, 65, Pretreatment is defined as macro kernel / signal.c, 13, Defined as a function prototype
kernel / blk_drv / blk.h, 74, Pretreatment is defined as macro mm / memory.c, 31, Defined as a function prototype
kernel / blk_drv / blk.h, 83, Pretreatment is defined as macro do_fd_request kernel / blk_drv / floppy.c, 417, Defined as a
DEVICE_OFF function
kernel / blk_drv / blk.h, 67, Pretreatment is defined as macro do_floppy_timer kernel / sched.c, 245, Defined as
--624--
index
kernel / traps.c, 129, Defined as a function include / termios.h, 173, Pretreatment is defined as macro
do_segment_not_present kernel / traps.c, 159, Defined ECHONL include / termios.h, 175, Pretreatment is defined as macro
as a function
do_signal ECHOPRT include / termios.h, 179, Pretreatment is defined as
do_stack_segment kernel / traps.c, 164, Defined EDEADLK include / errno.h, 54, Pretreatment is defined as
as a function macro
double_fault kernel / traps.c, 51, Defined as a function EFBIG include / errno.h, 46, Pretreatment is defined as macro
prototype
DRIVE_INFO init / main.c, 59, Pretreatment is defined EIO include / errno.h, 24, Pretreatment is defined as macro
as macro
drive_info init / main.c, 102, defined as struct Types EISDIR include / errno.h, 40, Pretreatment is defined as macro
of
DRQ_STAT EMFILE include / errno.h, 43, Pretreatment is defined as macro
ECHOE ENOSYS
--625--
index
include / errno.h, 57, Pretreatment is defined as macro include / unistd.h, 203, Defined as a function prototype
ENOTEMPTY include / errno.h, 58, Pretreatment is defined as EXTA include / termios.h, 149, Pretreatment is defined as macro
macro
EOF_CHAR include / tty.h, 40, Pretreatment is defined as F_GETLK include / fcntl.h, 28, Pretreatment is defined as
macro macro
ERASE_CHAR include / tty.h, 38, Pretreatment is defined F_SETFL include / fcntl.h, 27, Pretreatment is defined as
as macro macro
include / errno.h, 17, Defined as a variable F_WRLCK include / fcntl.h, 39, Pretreatment is defined as
include / errno.h, 48, Pretreatment is defined as macro FD_CLOEXEC include / fcntl.h, 33, Pretreatment is defined
ESRCH as macro
include / errno.h, 22, Pretreatment is defined as macro FD_DATA include / fdreg.h, 17, Pretreatment is defined as
ETXTBSY macro
include / errno.h, 45, Pretreatment is defined as macro FD_DCR include / fdreg.h, 20, Pretreatment is defined as macro
EXDEV
include / errno.h, 37, Pretreatment is defined as macro FD_DIR include / fdreg.h, 19, Pretreatment is defined as macro
exec
include / a.out.h, 6, defined as struct Types of FD_DOR include / fdreg.h, 18, Pretreatment is defined as macro
execl
include / unistd.h, 204, Defined as a function prototype FD_READ include / fdreg.h, 62, Pretreatment is defined as
execle macro
include / unistd.h, 206, Defined as a function prototype FD_RECALIBRATE include / fdreg.h, 60, Pretreatment is
include / unistd.h, 205, Defined as a function prototype FD_SEEK include / fdreg.h, 61, Pretreatment is defined as
execv macro
include / unistd.h, 202, Defined as a function prototype FD_SENSEI include / fdreg.h, 64, Pretreatment is defined as
execve macro
include / unistd.h, 201, Defined as a function prototype FD_SPECIFY include / fdreg.h, 65, Pretreatment is defined as
execvp macro
--626--
index
FD_STATUS include / fdreg.h, 16, Pretreatment is defined as include / fdreg.h, 10, Defined as a function prototype
fs / file_dev.c, 17, Defined as a function fn_ptr include / sched.h, 38, Defined as a type
file_table
fs / file_table.c, 9, Defined as a variable fork include / unistd.h, 210, Defined as a function prototype
find_empty_process kernel / fork.c, 135, Defined free_bucket_desc lib / malloc.c, 92, Defined
as a function as a variable
find_entry fs / namei.c, 91, Defined as a free_dind fs / truncate.c, 29, Defined as a
function function
as macro function
FIRST_TASK include / sched.h, 7, Pretreatment is defined as include / fs.h, 195, Defined as a function prototype
flock prototype
include / fcntl.h, 43, defined as struct Types of mm / memory.c, 89, Defined as a function
floppy free_page_tables include / sched.h, 30, Defined as a function
kernel / blk_drv / floppy.c, 114, Defined as a variable prototype
floppy_change include / fs.h, 169, Defined as a function mm / memory.c, 105, Defined as a function
prototype free_s include / kernel.h, 10, Defined as a function prototype
floppy_deselect include / fdreg.h, 13, Defined as a function lib / malloc.c, 182, Defined as a function
prototype free_super fs / super.c, 40, Defined as a
kernel / blk_drv / floppy.c, 125, Defined as a function function
floppy_init init / main.c, 49, Defined as a function fstat include / sys / stat.h, 52, Defined as a function prototype
prototype
kernel / blk_drv / floppy.c, 457, Defined as a function include / unistd.h, 233, Defined as a function prototype
floppy_interrupt FULL include / tty.h, 29, Pretreatment is defined as macro
include / fdreg.h, 11, Defined as a function prototype gdt include / head.h, 9, Defined as a variable
--627--
index
GDT_DATA include / head.h, 13, Pretreatment is defined as getegid include / unistd.h, 215, Defined as a function prototype
macro
general_protection kernel / traps.c, 56, Defined as a getpgrp include / unistd.h, 250, Defined as a function prototype
function prototype
get_empty_inode fs / inode.c, 194, Defined gid_t include / sys / types.h, 25, Defined as a type
as a function
include / fs.h, 183, Defined as a function prototype gmtime include / time.h, 37, Defined as a function prototype
a function gotoxy
get_free_page include / mm.h, 6, Defined as a function kernel / chr_drv / console.c, 88, Defined as a function
get_fs_byte hd
include / asm / segment.h, 1, Defined as a function kernel / blk_drv / hd.c, 59, Defined as a variable
get_hash_table fs / buffer.c, 183, Defined as HD_CURRENT include / hdreg.h, 16, Pretreatment is defined
a function as macro
include / fs.h, 185, Defined as a function prototype HD_DATA include / hdreg.h, 10, Pretreatment is defined as
get_limit macro
include / sched.h, 228, Pretreatment is defined as macro HD_ERROR include / hdreg.h, 11, Pretreatment is defined as
get_new macro
kernel / signal.c, 40, Defined as a function HD_HCYL include / hdreg.h, 15, Pretreatment is defined as
macro
get_seg_long kernel / traps.c, 28, Pretreatment is defined as kernel / blk_drv / hd.c, 52, defined as struct Types of
include / fs.h, 197, Defined as a function prototype hd_interrupt kernel / blk_drv / hd.c, 67, Defined as a function
get_termio prototype
kernel / chr_drv / tty_ioctl.c, 76, Defined as a function HD_LCYL include / hdreg.h, 14, Pretreatment is defined as
get_termios macro
kernel / chr_drv / tty_ioctl.c, 56, Defined as a function HD_NSECTOR include / hdreg.h, 12, Pretreatment is defined
getblk as macro
fs / buffer.c, 206, Defined as a function hd_out kernel / blk_drv / hd.c, 180, Defined as a function
--628--
index
HD_SECTOR include / hdreg.h, 13, Pretreatment is defined as include / fs.h, 182, Defined as a function prototype
hd_struct
kernel / blk_drv / hd.c, 56, defined as struct Types of IGNPAR include / termios.h, 85, Pretreatment is defined as macro
head
kernel / blk_drv / floppy.c, 117, Defined as a variable IMAXBEL include / termios.h, 96, Pretreatment is defined as
HOUR
kernel / mktime.c, 21, Pretreatment is defined as macro IN_ORDER kernel / blk_drv / blk.h, 40, Pretreatment is defined as
HUPCL macro
include / termios.h, 160, Pretreatment is defined as macro inb include / asm / io.h, 5, Pretreatment is defined as macro
HZ
include / sched.h, 5, Pretreatment is defined as macro inb_p include / asm / io.h, 17, Pretreatment is defined as macro
I_CRNL macro
kernel / chr_drv / tty_io.c, 42, Pretreatment is defined as macro INDEX_STAT include / hdreg.h, 25, Pretreatment is defined as
--629--
index
interruptible_sleep_on include / sched.h, 146, Defined as a ISTRIP include / termios.h, 88, Pretreatment is defined as macro
function prototype
kernel / sched.c, 167, Defined as a function isupper include / ctype.h, 25, Pretreatment is defined as macro
INTMASK
kernel / chr_drv / tty_io.c, 19, Pretreatment is defined as macro isxdigit include / ctype.h, 26, Pretreatment is defined as macro
invalid_op
kernel / traps.c, 49, Defined as a function prototype IXANY include / termios.h, 94, Pretreatment is defined as macro
invalidate
mm / memory.c, 39, Pretreatment is defined as macro IXON include / termios.h, 93, Pretreatment is defined as macro
ioctl_ptr fs / ioctl.c, 15, Defined as a kernel_mktime init / main.c, 52, Defined as a function
type prototype
include / asm / system.h, 20, Pretreatment is defined as macro KILL_CHAR include / tty.h, 39, Pretreatment is defined as
irq13 macro
kernel / traps.c, 61, Defined as a function prototype kill_session kernel / exit.c, 46, Defined as a
is_digit function
kernel / vsprintf.c, 16, Pretreatment is defined as macro KILLMASK kernel / chr_drv / tty_io.c, 18, Pretreatment is defined as
isalnum
include / ctype.h, 16, Pretreatment is defined as macro L_ECHO kernel / chr_drv / tty_io.c, 34, Pretreatment is defined as macro
isalpha
include / ctype.h, 17, Pretreatment is defined as macro L_ECHOCTL kernel / chr_drv / tty_io.c, 37, Pretreatment is defined as
isascii macro
include / ctype.h, 28, Pretreatment is defined as macro L_ECHOE kernel / chr_drv / tty_io.c, 35, Pretreatment is defined as macro
iscntrl
include / ctype.h, 18, Pretreatment is defined as macro L_ECHOK kernel / chr_drv / tty_io.c, 36, Pretreatment is defined as macro
isdigit
include / ctype.h, 19, Pretreatment is defined as macro L_ECHOKE kernel / chr_drv / tty_io.c, 38, Pretreatment is defined as
isgraph macro
include / ctype.h, 20, Pretreatment is defined as macro L_ISIG kernel / chr_drv / tty_io.c, 33, Pretreatment is defined as macro
ISIG
include / termios.h, 169, Pretreatment is defined as macro LAST include / tty.h, 28, Pretreatment is defined as macro
islower
include / ctype.h, 21, Pretreatment is defined as macro last_pid kernel / fork.c, 22, Defined as a variable
isprint
include / ctype.h, 22, Pretreatment is defined as macro LAST_TASK include / sched.h, 8, Pretreatment is defined as
ispunct macro
include / ctype.h, 23, Pretreatment is defined as macro last_task_used_math include / sched.h, 137, Defined
isspace as a variable
include / ctype.h, 24, Pretreatment is defined as macro kernel / sched.c, 63, Defined as a variable
--630--
index
macro function
LDT_DATA include / head.h, 18, Pretreatment is defined as math_error kernel / math / math_emulate.c, 37, Defined as a function
macro
kernel / vsprintf.c, 31, Pretreatment is defined as macro MAX_ARG_PAGES fs / exec.c, 39, Pretreatment is
lf defined as macro
kernel / chr_drv / console.c, 204, Defined as a function MAX_ERRORS kernel / blk_drv / hd.c, 34, Pretreatment is defined
link as macro
include / unistd.h, 218, Defined as a function prototype kernel / blk_drv / floppy.c, 60, Pretreatment is defined as macro
ll_rw_block include / fs.h, 187, Defined as a function MAX_HD kernel / blk_drv / hd.c, 35, Pretreatment is defined as macro
prototype
kernel / blk_drv / ll_rw_blk.c, 145, Defined as a function MAX_REPLIES kernel / blk_drv / floppy.c, 65, Pretreatment is defined as
lldt macro
include / sched.h, 158, Pretreatment is defined as macro MAY_EXEC fs / namei.c, 29, Pretreatment is defined as
localtime macro
include / time.h, 38, Defined as a function prototype MAY_READ fs / namei.c, 31, Pretreatment is defined as
lock_buffer macro
kernel / blk_drv / ll_rw_blk.c, 42, Defined as a function MAY_WRITE fs / namei.c, 30, Pretreatment is defined
macro variable
tools / build.c, 57, Defined as a function include / asm / memory.h, 8, Pretreatment is defined as macro
main_memory_start init / main.c, 100, Defined memmove include / string.h, 346, Defined as a
as a variable function
MAJOR memory_end init / main.c, 98, Defined as a
kernel / blk_drv / floppy.c, 41, Pretreatment is defined as macro MIN fs / file_dev.c, 14, Pretreatment is defined as macro
lib / malloc.c, 117, Defined as a function MINUTE kernel / mktime.c, 20, Pretreatment is defined as macro
MAP_NR
mm / memory.c, 46, Pretreatment is defined as macro mkdir
--631--
index
include / sys / stat.h, 53, Defined as a function prototype N_SETV include / a.out.h, 184, Pretreatment is defined as macro
mkfifo
include / sys / stat.h, 54, Defined as a function prototype N_STAB include / a.out.h, 153, Pretreatment is defined as macro
mknod
include / unistd.h, 220, Defined as a function prototype N_STROFF include / a.out.h, 64, Pretreatment is defined as
mktime macro
include / time.h, 33, Defined as a function prototype N_SYMOFF include / a.out.h, 60, Pretreatment is defined as
mode_t macro
include / sys / types.h, 28, Defined as a type N_TEXT include / a.out.h, 131, Pretreatment is defined as macro
moff_timer
kernel / sched.c, 203, Defined as a variable N_TRELOFF include / a.out.h, 52, Pretreatment is defined as
mon_timer macro
kernel / sched.c, 202, Defined as a variable N_TXTADDR include / a.out.h, 69, Pretreatment is defined as
month macro
kernel / mktime.c, 26, Defined as a variable N_TXTOFF include / a.out.h, 43, Pretreatment is defined as
mount macro
include / unistd.h, 221, Defined as a function prototype N_TYPE include / a.out.h, 150, Pretreatment is defined as macro
move_to_user_mode include / asm / system.h, 1, Pretreatment is NAME_LEN include / fs.h, 36, Pretreatment is defined as
N_BADMAG include / a.out.h, 31, Pretreatment is defined as include / fs.h, 178, Defined as a function prototype
N_BSS
include / a.out.h, 137, Pretreatment is defined as macro NCCS include / termios.h, 53, Pretreatment is defined as macro
N_COMM function
include / a.out.h, 140, Pretreatment is defined as macro include / fs.h, 192, Defined as a function prototype
N_DATADDR include / a.out.h, 100, Pretreatment is defined as include / fs.h, 194, Defined as a function prototype
N_EXT
include / a.out.h, 147, Pretreatment is defined as macro NL1 include / termios.h, 109, Pretreatment is defined as macro
N_FN
include / a.out.h, 143, Pretreatment is defined as macro NLDLY include / termios.h, 107, Pretreatment is defined as macro
N_INDR
include / a.out.h, 164, Pretreatment is defined as macro nlink_t include / sys / types.h, 30, Defined as a type
N_MAGIC
include / a.out.h, 18, Pretreatment is defined as macro nlist include / a.out.h, 111, defined as struct Types of
N_SETA
include / a.out.h, 178, Pretreatment is defined as macro NMAGIC include / a.out.h, 25, Pretreatment is defined as
N_SETB macro
include / a.out.h, 181, Pretreatment is defined as macro nmi kernel / traps.c, 45, Defined as a function prototype
N_SETD
include / a.out.h, 180, Pretreatment is defined as macro NOFLSH include / termios.h, 176, Pretreatment is defined as macro
N_SETT
include / a.out.h, 179, Pretreatment is defined as macro nop
--632--
index
include / asm / system.h, 18, Pretreatment is defined as macro O_NDELAY include / fcntl.h, 17, Pretreatment is defined as
NPAR macro
kernel / chr_drv / console.c, 54, Pretreatment is defined as macro O_NLCR kernel / chr_drv / tty_io.c, 46, Pretreatment is defined as macro
npar
kernel / chr_drv / console.c, 75, Defined as a variable O_NLRET kernel / chr_drv / tty_io.c, 48, Pretreatment is defined as macro
NR_FILE include / fs.h, 45, Pretreatment is defined as O_RDONLY include / fcntl.h, 8, Pretreatment is defined as
macro macro
NR_HASH include / fs.h, 47, Pretreatment is defined as O_RDWR include / fcntl.h, 10, Pretreatment is defined as
macro macro
kernel / blk_drv / hd.c, 53, Defined as a variable O_WRONLY include / fcntl.h, 9, Pretreatment is defined as
NR_REQUEST
kernel / blk_drv / blk.h, 15, Pretreatment is defined as macro off_t include / sys / types.h, 32, Defined as a type
NRDEVS
fs / char_dev.c, 83, Pretreatment is defined as macro OLCUC include / termios.h, 100, Pretreatment is defined as macro
O_CRNL
ORIG_ROOT_DEV init / main.c, 60, Pretreatment is
kernel / chr_drv / tty_io.c, 47, Pretreatment is defined as macro
defined as macro
O_EXCL
ORIG_VIDEO_COLS kernel / chr_drv / console.c, 43, Pretreatment is
include / fcntl.h, 12, Pretreatment is defined as macro
defined as macro
O_LCUC
ORIG_VIDEO_EGA_AX
kernel / chr_drv / tty_io.c, 49, Pretreatment is defined as macro
--633--
index
kernel / chr_drv / console.c, 45, Pretreatment is defined as macro pause include / unistd.h, 224, Defined as a function prototype
ORIG_X
kernel / chr_drv / console.c, 39, Pretreatment is defined as macro PIPE_EMPTY include / fs.h, 61, Pretreatment is defined
ORIG_Y as macro
kernel / chr_drv / console.c, 40, Pretreatment is defined as macro PIPE_FULL include / fs.h, 62, Pretreatment is defined as
origin macro
kernel / chr_drv / console.c, 69, Defined as a variable PIPE_HEAD include / fs.h, 58, Pretreatment is defined as
outb macro
include / asm / io.h, 1, Pretreatment is defined as macro PIPE_SIZE include / fs.h, 60, Pretreatment is defined as
outb_p macro
include / asm / io.h, 11, Pretreatment is defined as macro PIPE_TAIL include / fs.h, 59, Pretreatment is defined as
output_byte macro
kernel / blk_drv / floppy.c, 194, Defined as a function PLUS kernel / vsprintf.c, 29, Pretreatment is defined as macro
overflow
kernel / traps.c, 47, Defined as a function prototype port_read kernel / blk_drv / hd.c, 61, Pretreatment is defined as macro
prototype pos
page_fault kernel / chr_drv / console.c, 71, Defined as a variable
kernel / traps.c, 57, Defined as a function prototype printbuf init / main.c, 42, Defined as a
include / a.out.h, 92, Pretreatment is defined as macro init / main.c, 151, Defined as a function
include / mm.h, 4, Pretreatment is defined as macro printk include / kernel.h, 7, Defined as a function prototype
PAGING_PAGES mm / memory.c, 45, Pretreatment is ptrdiff_t include / sys / types.h, 16, Defined as a type
defined as macro
include / kernel.h, 5, Defined as a function prototype put_fs_byte include / asm / segment.h, 25, Defined as a
kernel / panic.c, 16, Defined as a function put_fs_long include / asm / segment.h, 35, Defined as a
par function
kernel / chr_drv / console.c, 75, Defined as a variable put_fs_word include / asm / segment.h, 30, Defined as a
PARENB
include / termios.h, 165, Pretreatment is defined as macro mm / memory.c, 197, Defined as a function
partition ques
include / hdreg.h, 52, defined as struct Types of kernel / chr_drv / console.c, 76, Defined as a variable
--634--
index
read macro
include / unistd.h, 226, Defined as a function prototype restore_cur kernel / chr_drv / console.c, 440, Defined as a function
READ
include / fs.h, 26, Pretreatment is defined as macro result
read_inode fs / inode.c, 17, Defined as a function kernel / blk_drv / floppy.c, 212, Defined as a function
prototype ri
fs / inode.c, 294, Defined as a function kernel / chr_drv / console.c, 214, Defined as a function
fs / read_write.c, 16, Defined as a function prototype ROOT_INO include / fs.h, 37, Pretreatment is defined as
read_super fs / super.c, 100, Defined as a rs_init include / tty.h, 65, Defined as a function prototype
function
include / fs.h, 28, Pretreatment is defined as macro rs_write include / tty.h, 72, Defined as a function prototype
recalibrate
kernel / blk_drv / hd.c, 39, Defined as a variable fs / char_dev.c, 95, Defined as a function
kernel / blk_drv / floppy.c, 44, Defined as a variable rw_interrupt kernel / blk_drv / floppy.c, 250, Defined as a
recalibrate_floppy function
kernel / blk_drv / floppy.c, 362, Defined as a function rw_kmem fs / char_dev.c, 44, Defined as a
release function
kernel / exit.c, 19, Defined as a function rw_mem fs / char_dev.c, 39, Defined as a
relocation_info include / a.out.h, 193, defined as struct Types function
of rw_memory fs / char_dev.c, 65, Defined as a
remove_from_queues fs / buffer.c, 131, Defined function
as a function rw_port fs / char_dev.c, 49, Defined as a function
reply_buffer
kernel / blk_drv / floppy.c, 66, Defined as a variable rw_ram
--635--
index
fs / char_dev.c, 34, Defined as a function include / sys / stat.h, 39, Pretreatment is defined as macro
S_IFIFO saved_x
include / sys / stat.h, 25, Pretreatment is defined as macro kernel / chr_drv / console.c, 431, Defined as a variable
S_IFMT saved_y
include / sys / stat.h, 20, Pretreatment is defined as macro kernel / chr_drv / console.c, 432, Defined as a variable
include / sys / stat.h, 47, Pretreatment is defined as macro schedule include / sched.h, 33, Defined as a function prototype
S_IRUSR
include / sys / stat.h, 37, Pretreatment is defined as macro kernel / sched.c, 104, Defined as a function
S_IRWXG scr_end
include / sys / stat.h, 41, Pretreatment is defined as macro kernel / chr_drv / console.c, 70, Defined as a variable
S_IRWXO scrdown
include / sys / stat.h, 46, Pretreatment is defined as macro kernel / chr_drv / console.c, 170, Defined as a function
S_IRWXU scrup
include / sys / stat.h, 36, Pretreatment is defined as macro kernel / chr_drv / console.c, 107, Defined as a function
S_ISBLK sector
include / sys / stat.h, 33, Pretreatment is defined as macro kernel / blk_drv / floppy.c, 116, Defined as a variable
S_ISCHR seek
include / sys / stat.h, 32, Pretreatment is defined as macro kernel / blk_drv / floppy.c, 46, Defined as a variable
S_ISDIR SEEK_CUR include / unistd.h, 29, Pretreatment is defined as
S_IXUSR
send_break
--636--
index
kernel / chr_drv / tty_ioctl.c, 51, Defined as a function SIG_DFL include / signal.h, 45, Pretreatment is defined as macro
send_sig
kernel / exit.c, 35, Defined as a function SIG_IGN include / signal.h, 46, Pretreatment is defined as macro
set_base
include / sched.h, 211, Pretreatment is defined as macro SIG_SETMASK include / signal.h, 43, Pretreatment is defined
set_bit as macro
fs / super.c, 22, Pretreatment is defined as macro SIG_UNBLOCK include / signal.h, 42, Pretreatment is defined
include / asm / system.h, 33, Pretreatment is defined as macro sigaddset include / signal.h, 58, Defined as a function prototype
set_ldt_desc
include / asm / system.h, 66, Pretreatment is defined as macro SIGALRM include / signal.h, 26, Pretreatment is defined as
set_limit macro
include / sched.h, 212, Pretreatment is defined as macro SIGCHLD include / signal.h, 29, Pretreatment is defined as
set_origin macro
kernel / chr_drv / console.c, 97, Defined as a function SIGCONT include / signal.h, 30, Pretreatment is defined as
set_system_gate macro
include / asm / system.h, 39, Pretreatment is defined as macro sigdelset include / signal.h, 59, Defined as a function prototype
set_termio
kernel / chr_drv / tty_ioctl.c, 97, Defined as a function sigemptyset include / signal.h, 60, Defined as a function
set_termios prototype
kernel / chr_drv / tty_ioctl.c, 66, Defined as a function sigfillset include / signal.h, 61, Defined as a function prototype
set_trap_gate
include / asm / system.h, 36, Pretreatment is defined as macro SIGFPE include / signal.h, 20, Pretreatment is defined as macro
set_tss_desc
include / asm / system.h, 65, Pretreatment is defined as macro SIGHUP include / signal.h, 12, Pretreatment is defined as macro
setgid
include / unistd.h, 230, Defined as a function prototype SIGILL include / signal.h, 15, Pretreatment is defined as macro
setpgid
include / unistd.h, 228, Defined as a function prototype SIGINT include / signal.h, 13, Pretreatment is defined as macro
setpgrp
include / unistd.h, 227, Defined as a function prototype SIGIOT include / signal.h, 18, Pretreatment is defined as macro
setsid
include / unistd.h, 251, Defined as a function prototype sigismember include / signal.h, 62, Defined as a function
setuid prototype
include / unistd.h, 229, Defined as a function prototype SIGKILL include / signal.h, 21, Pretreatment is defined as macro
setup_DMA
kernel / blk_drv / floppy.c, 160, Defined as a function SIGN kernel / vsprintf.c, 28, Pretreatment is defined as macro
setup_rw_floppy
kernel / blk_drv / floppy.c, 269, Defined as a function sigpending include / signal.h, 63, Defined as a function
share_page
mm / memory.c, 344, Defined as a function sigprocmask include / signal.h, 64, Defined as a function
show_stat prototype
kernel / sched.c, 37, Defined as a function SIGQUIT include / signal.h, 14, Pretreatment is defined as macro
show_task
kernel / sched.c, 26, Defined as a function SIGSEGV include / signal.h, 23, Pretreatment is defined as
macro SIGSTKFLT
--637--
index
include / signal.h, 28, Pretreatment is defined as macro include / fdreg.h, 34, Pretreatment is defined as macro
SIGSTOP ST1
include / signal.h, 31, Pretreatment is defined as macro kernel / blk_drv / floppy.c, 68, Pretreatment is defined as macro
include / time.h, 11, Defined as a type ST2_MAM include / fdreg.h, 46, Pretreatment is defined as
include / string.h, 10, Defined as a type ST2_SEH include / fdreg.h, 49, Pretreatment is defined as
skip_atoi macro
kernel / vsprintf.c, 18, Defined as a function ST2_SNS include / fdreg.h, 48, Pretreatment is defined as
sleep_if_empty macro
kernel / chr_drv / tty_io.c, 122, Defined as a function ST2_WC include / fdreg.h, 50, Pretreatment is defined as macro
sleep_if_full
kernel / chr_drv / tty_io.c, 130, Defined as a function ST3
sleep_on kernel / blk_drv / floppy.c, 70, Pretreatment is defined as macro
include / sched.h, 145, Defined as a function prototype ST3_HA include / fdreg.h, 55, Pretreatment is defined as macro
kernel / blk_drv / floppy.c, 67, Pretreatment is defined as macro START_CHAR include / tty.h, 41, Pretreatment is defined
ST0_DS as macro
include / fdreg.h, 30, Pretreatment is defined as macro startup_time include / sched.h, 140, Defined as a
ST0_ECE variable
include / fdreg.h, 33, Pretreatment is defined as macro init / main.c, 53, Defined as a variable
include / fdreg.h, 31, Pretreatment is defined as macro stat include / sys / stat.h, 6, defined as struct Types of
ST0_INTR
include / fdreg.h, 35, Pretreatment is defined as macro include / sys / stat.h, 55, Defined as a function prototype
--638--
index
STATUS_BUSY include / fdreg.h, 24, Pretreatment is defined include / string.h, 277, Defined as a function
strftime
kernel / sys.c, 168, Defined as a function
include / time.h, 39, Defined as a function prototype
sys_call_table include / sys.h, 74, Defined as a
STRINGIFY tools / build.c, 44, Pretreatment is defined as
variable
macro
sys_chdir fs / open.c, 75, Defined as a
strlen
function
We include / string.h, 263, Defined as a function
include / sys.h, 13, Defined as a function prototype
strncat
sys_chmod fs / open.c, 105, Defined as a
include / string.h, 68, Defined as a function
function
strncmp
include / sys.h, 16, Defined as a function prototype
include / string.h, 107, Defined as a function
strrchr function
include / string.h, 145, Defined as a function include / sys.h, 62, Defined as a function prototype
include / string.h, 236, Defined as a function fs / fcntl.c, 16, Defined as a function prototype
strtok
--639--
index
include / sys.h, 7, Defined as a function prototype sys_kill include / sys.h, 38, Defined as a function prototype
sys_dup fs / fcntl.c, 42, Defined as a include / sys.h, 10, Defined as a function prototype
sys_execve include / sys.h, 12, Defined as a function include / sys.h, 20, Defined as a function prototype
sys_fcntl fs / fcntl.c, 47, Defined as a include / sys.h, 15, Defined as a function prototype
include / sys.h, 3, Defined as a function prototype sys_mpx include / sys.h, 57, Defined as a function prototype
include / sys.h, 29, Defined as a function prototype sys_nice include / sys.h, 35, Defined as a function prototype
sys_ftime
include / sys.h, 36, Defined as a function prototype kernel / sched.c, 378, Defined as a function
kernel / sched.c, 373, Defined as a function sys_pause include / sys.h, 30, Defined as a function
kernel / sched.c, 363, Defined as a function kernel / exit.c, 16, Defined as a function prototype
kernel / sched.c, 368, Defined as a function kernel / sys.c, 82, Defined as a function
sys_getpgrp include / sys.h, 66, Defined as a function sys_pipe fs / pipe.c, 71, Defined as a
prototype function
kernel / sys.c, 201, Defined as a function include / sys.h, 43, Defined as a function prototype
kernel / sched.c, 348, Defined as a function kernel / sys.c, 46, Defined as a function
sys_getppid include / sys.h, 65, Defined as a function sys_ptrace include / sys.h, 27, Defined as a function
prototype prototype
kernel / sched.c, 353, Defined as a function kernel / sys.c, 26, Defined as a function
kernel / sched.c, 358, Defined as a function include / sys.h, 4, Defined as a function prototype
kernel / sys.c, 36, Defined as a function kernel / sys.c, 41, Defined as a function
function function
include / sys.h, 55, Defined as a function prototype include / sys.h, 41, Defined as a function prototype
--640--
index
include / sys.h, 47, Defined as a function prototype kernel / sys.c, 97, Defined as a function
kernel / sys.c, 72, Defined as a function sys_umask include / sys.h, 61, Defined as a function
kernel / sys.c, 51, Defined as a function sys_uname include / sys.h, 60, Defined as a function
sys_setuid function
include / sys.h, 24, Defined as a function prototype include / sys.h, 63, Defined as a function prototype
sys_setup function
include / sys.h, 1, Defined as a function prototype include / sys.h, 31, Defined as a function prototype
kernel / blk_drv / hd.c, 71, Defined as a function sys_waitpid include / sys.h, 8, Defined as a function
kernel / signal.c, 63, Defined as a function sysbeep kernel / chr_drv / console.c, 79, Defined as a function prototype
sys_signal
include / sys.h, 49, Defined as a function prototype kernel / chr_drv / console.c, 699, Defined as a function
kernel / signal.c, 48, Defined as a function sysbeepstop kernel / chr_drv / console.c, 691, Defined as a
SYS_SIZE tools / build.c, 35, Pretreatment is defined as function
macro system_call kernel / sched.c, 51, Defined as a function
sys_stat fs / stat.c, 36, Defined as a TAB1 include / termios.h, 117, Pretreatment is defined as macro
function
include / sys.h, 19, Defined as a function prototype TAB2 include / termios.h, 118, Pretreatment is defined as macro
sys_stime
include / sys.h, 26, Defined as a function prototype TAB3 include / termios.h, 119, Pretreatment is defined as macro
kernel / sys.c, 31, Defined as a function table_list kernel / chr_drv / tty_io.c, 99, Defined as a variable
--641--
index
TASK_UNINTERRUPTIBLE include / sched.h, 21, Pretreatment include / termios.h, 10, Pretreatment is defined as macro
task_union
kernel / sched.c, 53, defined as union Types of tell_father kernel / exit.c, 83, Defined as a
TASK_ZOMBIE include / sched.h, 22, Pretreatment is defined function
as macro termio include / termios.h, 44, defined as struct Types of
tcdrain
include / termios.h, 220, Defined as a function prototype termios include / termios.h, 54, defined as struct Types of
tcflow
include / termios.h, 221, Defined as a function prototype ticks_to_floppy_on include / fs.h, 170, Defined as a
TCFLSH function prototype
include / termios.h, 18, Pretreatment is defined as macro include / fdreg.h, 9, Defined as a function prototype
tcflush kernel / sched.c, 206, Defined as a function
include / termios.h, 222, Defined as a function prototype time include / unistd.h, 236, Defined as a function prototype
TCGETA
include / termios.h, 12, Pretreatment is defined as macro
include / time.h, 31, Defined as a function prototype
tcgetattr time_init init / main.c, 76, Defined as a
include / termios.h, 223, Defined as a function prototype
function
TCGETS TIME_REQUESTS kernel / sched.c, 264, Pretreatment is
include / termios.h, 8, Pretreatment is defined as macro
defined as macro
TCIFLUSH time_t include / sys / types.h, 11, Defined as a type
include / termios.h, 205, Pretreatment is defined as macro
TCIOFF
include / time.h, 6, Defined as a type
include / termios.h, 201, Pretreatment is defined as macro
timer_interrupt kernel / sched.c, 50, Defined as a function
TCIOFLUSH
prototype
include / termios.h, 207, Pretreatment is defined as macro
timer_list kernel / sched.c, 266, defined as struct Types of
TCION
include / termios.h, 202, Pretreatment is defined as macro
kernel / sched.c, 270, Defined as a variable
TCOFLUSH
times include / sys / times.h, 13, Defined as a function prototype
include / termios.h, 206, Pretreatment is defined as macro
TCOOFF
include / unistd.h, 237, Defined as a function prototype
include / termios.h, 199, Pretreatment is defined as macro
TIOCEXCL include / termios.h, 19, Pretreatment is defined as
TCOON
macro
include / termios.h, 200, Pretreatment is defined as macro
TIOCGPGRP include / termios.h, 22, Pretreatment is defined as
TCSADRAIN
macro
include / termios.h, 211, Pretreatment is defined as macro
TIOCGSOFTCAR include / termios.h, 32, Pretreatment is
TCSAFLUSH
defined as macro
include / termios.h, 212, Pretreatment is defined as macro
TIOCGWINSZ include / termios.h, 26, Pretreatment is defined as
TCSANOW
macro
include / termios.h, 210, Pretreatment is defined as macro
TIOCINQ include / termios.h, 34, Pretreatment is defined as macro
TCSBRK
include / termios.h, 16, Pretreatment is defined as macro
TIOCM_CAR include / termios.h, 192, Pretreatment is defined as
tcsendbreak
macro
include / termios.h, 224, Defined as a function prototype
TIOCM_CD include / termios.h, 195, Pretreatment is defined as
TCSETA
macro
include / termios.h, 13, Pretreatment is defined as macro
TIOCM_CTS include / termios.h, 191, Pretreatment is defined as
TCSETAF
macro
include / termios.h, 15, Pretreatment is defined as macro
TIOCM_DSR include / termios.h, 194, Pretreatment is defined as
tcsetattr
macro
include / termios.h, 225, Defined as a function prototype
TIOCM_DTR include / termios.h, 187, Pretreatment is defined as
TCSETAW
macro
include / termios.h, 14, Pretreatment is defined as macro
TIOCM_LE include / termios.h, 186, Pretreatment is defined as
TCSETS
macro
include / termios.h, 9, Pretreatment is defined as macro
TIOCM_RI include / termios.h, 196, Pretreatment is defined as
TCSETSF
macro
include / termios.h, 11, Pretreatment is defined as macro
TIOCM_RNG
TCSETSW
--642--
index
include / termios.h, 193, Pretreatment is defined as macro include / fs.h, 173, Defined as a function prototype
include / termios.h, 29, Pretreatment is defined as macro tty_init include / tty.h, 67, Defined as a function prototype
TIOCMGET
include / termios.h, 28, Pretreatment is defined as macro kernel / chr_drv / tty_io.c, 105, Defined as a function
TIOCMSET tty_intr
include / termios.h, 31, Pretreatment is defined as macro kernel / chr_drv / tty_io.c, 111, Defined as a function
TIOCNXCL tty_ioctl fs / ioctl.c, 13, Defined as a function
macro
kernel / chr_drv / tty_io.c, 51, defined as struct Types of
tm
tty_write fs / char_dev.c, 17, Defined as a function prototype
include / time.h, 18, defined as struct Types of
tmp_floppy_area
include / kernel.h, 8, Defined as a function prototype
kernel / blk_drv / floppy.c, 105, Defined as a variable
include / sched.h, 36, Defined as a function prototype
tms
include / tty.h, 70, Defined as a function prototype
include / sys / times.h, 6, defined as struct Types of
kernel / chr_drv / tty_io.c, 290, Defined as a function
toascii
TYPE
include / ctype.h, 29, Pretreatment is defined as macro
kernel / blk_drv / floppy.c, 53, Pretreatment is defined as macro
tolower
tzset include / time.h, 40, Defined as a function prototype
include / ctype.h, 31, Pretreatment is defined as macro
top
u_char include / sys / types.h, 33, Defined as a type
kernel / chr_drv / console.c, 73, Defined as a variable
TOSTOP
uid_t include / sys / types.h, 24, Defined as a type
include / termios.h, 177, Pretreatment is defined as macro
toupper
ulimit include / unistd.h, 238, Defined as a function prototype
include / ctype.h, 32, Pretreatment is defined as macro
track
umask include / sys / stat.h, 56, Defined as a function prototype
kernel / blk_drv / floppy.c, 118, Defined as a variable
transfer
include / unistd.h, 239, Defined as a function prototype
kernel / blk_drv / floppy.c, 309, Defined as a function
umode_t include / sys / types.h, 29, Defined as a type
trap_init
include / sched.h, 34, Defined as a function prototype
umount include / unistd.h, 240, Defined as a function prototype
kernel / traps.c, 181, Defined as a function
TRK0_ERR
un_wp_page mm / memory.c, 221, Defined as a
include / hdreg.h, 46, Pretreatment is defined as macro
function
truncate
uname include / sys / utsname.h, 14, Defined as a function prototype
fs / truncate.c, 47, Defined as a function
--643--
index
include / unistd.h, 241, Defined as a function prototype kernel / chr_drv / console.c, 64, Defined as a variable
unexpected_floppy_interrupt kernel / blk_drv / floppy.c, 353, Defined video_mem_start kernel / chr_drv / console.c, 63, Defined as a
as a function variable
unexpected_hd_interrupt kernel / blk_drv / hd.c, 237, Defined video_num_columns kernel / chr_drv / console.c, 59, Defined
as a function as a variable
unlink video_num_lines kernel / chr_drv / console.c, 61, Defined as a
kernel / blk_drv / blk.h, 101, Defined as a function video_port_reg kernel / chr_drv / console.c, 65, Defined as a
usage variable
tools / build.c, 52, Defined as a function video_size_row kernel / chr_drv / console.c, 60, Defined as a
USED variable
mm / memory.c, 47, Pretreatment is defined as macro video_type kernel / chr_drv / console.c, 58, Defined as a variable
user_stack
kernel / sched.c, 67, Defined as a variable VIDEO_TYPE_CGA kernel / chr_drv / console.c, 50, Pretreatment is
include / sys / types.h, 34, Defined as a type VIDEO_TYPE_EGAC kernel / chr_drv / console.c, 52, Pretreatment is
include / sys / types.h, 39, defined as struct Types of VIDEO_TYPE_EGAM kernel / chr_drv / console.c, 51, Pretreatment is
include / utime.h, 11, Defined as a function prototype VKILL include / termios.h, 67, Pretreatment is defined as macro
utsname
include / sys / utsname.h, 6, defined as struct Types of VLNEXT include / termios.h, 79, Pretreatment is defined as macro
va_arg
include / stdarg.h, 24, Pretreatment is defined as macro VMIN include / termios.h, 70, Pretreatment is defined as macro
va_end
include / stdarg.h, 22, Pretreatment is defined as macro VQUIT include / termios.h, 65, Pretreatment is defined as macro
include / termios.h, 77, Pretreatment is defined as macro VSTART include / termios.h, 72, Pretreatment is defined as macro
VEOF
include / termios.h, 68, Pretreatment is defined as macro VSTOP include / termios.h, 73, Pretreatment is defined as macro
VEOL
include / termios.h, 75, Pretreatment is defined as macro VSUSP include / termios.h, 74, Pretreatment is defined as macro
VEOL2
include / termios.h, 80, Pretreatment is defined as macro VSWTC include / termios.h, 71, Pretreatment is defined as macro
VERASE
include / termios.h, 66, Pretreatment is defined as macro VT0 include / termios.h, 125, Pretreatment is defined as macro
verify_area
include / kernel.h, 4, Defined as a function prototype VT1 include / termios.h, 126, Pretreatment is defined as macro
video_mem_end VTIME
--644--
index
include / termios.h, 69, Pretreatment is defined as macro kernel / blk_drv / hd.c, 169, Defined as a function
include / unistd.h, 246, Defined as a function prototype WIN_WRITE include / hdreg.h, 36, Pretreatment is defined as
wait_for_keypress fs / super.c, 19, Defined as a winsize include / termios.h, 36, defined as struct Types of
function prototype
kernel / chr_drv / tty_io.c, 140, Defined as a function WNOHANG include / sys / wait.h, 10, Pretreatment is defined as
wait_for_request macro
kernel / blk_drv / ll_rw_blk.c, 26, Defined as a variable WRERR_STAT include / hdreg.h, 29, Pretreatment is defined
as macro
kernel / blk_drv / blk.h, 52, Defined as a variable
write include / unistd.h, 247, Defined as a function prototype
wait_motor
kernel / sched.c, 201, Defined as a variable
WRITE include / fs.h, 27, Pretreatment is defined as macro
wait_on
include / fs.h, 175, Defined as a function prototype
write_inode fs / inode.c, 18, Defined as a function
wait_on_buffer fs / buffer.c, 36, Defined as
prototype
a function
wait_on_floppy_select kernel / blk_drv / floppy.c, 123, Defined fs / inode.c, 314, Defined as a function
include / sys / wait.h, 21, Defined as a function prototype WRITEA include / fs.h, 29, Pretreatment is defined as
kernel / sched.c, 188, Defined as a function WTERMSIG include / sys / wait.h, 16, Pretreatment is defined as
WIFEXITED
include / sys / wait.h, 13, Pretreatment is defined as macro XCASE include / termios.h, 171, Pretreatment is defined as macro
include / hdreg.h, 39, Pretreatment is defined as macro ZEROPAD kernel / vsprintf.c, 27, Pretreatment is defined as
WIN_READ macro
include / hdreg.h, 35, Pretreatment is defined as macro ZMAGIC include / a.out.h, 27, Pretreatment is defined as macro
as macro
win_result
--645--
index
--646--