Linux-0.11 Kernel Memory Management get_free_page () function analysis

Source: Internet
Author: User


/*

*author:davidlin
*date:2014-11-11pm
*email: [email protected] or [email protected]
*world:the City of SZ, in China
*ver:000.000.001
*history:editor time do
1) Linpeng 2014-11-11 created this file!
2)
*/
Linux-0.11 Memory Management module is more difficult to understand in the source code part, now the author's personal understanding published
First hair Linux-0.11 kernel memory management get_free_page () function analysis

Have time to write other functions or files:)

/*
* Get Physical Address of first (actually last:-) free page, and mark it
* used. If no free pages left, return 0.

*/

 unsigned long get_free_page (void) {register unsigned long __res asm ("ax"); __ asm__ ("std ; repne ; scasb\n\t"      "jne 1f\n\t"       "movb $1,1 (%%edi) \n\t"      "sall $12,%%ecx\n\t"      " Addl %2,%%ecx\n\t "    " movl %%ecx,%%edx\n\t "    " movl $ 1024,%%ecx\n\t "    " leal 4092 (%%edx),%%edi\n\t "    " rep ;  stosl\n\t "    " movl %%edx,%%eax\n "    " 1: "    &NBSP: "=a"   (__res)     : "0"   (0), "I"   (LOW_MEM), "C"   (paging_pages) ,     "D"   (mem_map+paging_pages-1)     : "Di", "CX", "DX"); return  __res;} 

1. Function Purpose:
Looking for mem_map[0 ... ( PAGING_PAGES-1)], the item that is mem_map[i]==0, if found,
Returns the physical address, unable to find return 0
2. Tips:
Why not use C to implement this code?
I personally think that the C function will open up stack frames, which may contaminate the task stack,
At the same time, the function requires frequent calls, and the assembly instruction at the register level is more efficient than C:)
3. Code Analysis:
(1) Register unsigned long __res asm ("Ax");
The __res is a register-level variable, and the value is stored in the AX register, which means that the operation of the __res equals the operation of the AX register for efficiency considerations
(2) __asm__ ("STD; Repne; Scasb\n\t "
Cycle comparison, find the Mem_map[i]==0 page;
STD settings df=1, so SCASB performs a decrement operation, involving registers al, Ecx, es: (e) di three registers, in the definition of the function tail
: "0" (0), "I" (Low_mem), "C" (Paging_pages),
"D" (mem_map+paging_pages-1)
: "Di", "CX", "DX");
that there

Al = 0; If mem_map[i] = = 0, expressed as a free page, otherwise allocated occupied, Al saves 0 values for comparing

ECX = paging_pages; Number of main memory leaf tables

Es:di = (mem_map+paging_pages-1); Memory management Array Last item
The meaning of this instruction is from the array mem_map[0: ( PAGING_PAGES-1)] "The last item
MEM_MAP[PAGING_PAGES-1] Start, compare mem_map[i] is equal to 0 (0 values are saved in the AL register);
Each comparison, Es:di value minus 1, if not equal, Es:di value minus 1, that is mem_map[i--], continue to compare until ecx = = 0;
If they are equal, jump out of the loop

The C language is implemented as follows:

if (i = paging_pages-1; I! = 0; i--) {if (0! = Mem_map[i]) {continue;      Continue loop} else {break; Jump out of the loop}}

(3) "Jne 1f\n\t"
If Mem_map[0: ( PAGING_PAGES-1)] are not equal to 0,
Jump to tag 1f execution, NF for forward label, NB for backward label, n is the decimal number of value 1-10
(4) "Movb $1,1 (%%edi) \n\t"
Mem_map[i]==0 is mem_map[0. PAGING_PAGES-1)] In reverse order the first found equal to 0 of the target,
The lowest position of EDI is 1, which is mem_map[i]=1, which is marked as occupied by the page, not the idle bit
(5) "Sall $12,%%ecx\n\t"
At this time ecx save is mem_map[i] subscript I, that is, the relative number of pages,
Example:
Suppose Mem_map[0: ( PAGING_PAGES-1)] [last parameter]
MEM_MAP[PAGING_PAGES-1] = = 0, i.e. i = = (paging_pages-1),
So at this time *ecx = = paging_pages-1;
At this point the relative page address is 4k* (paging_pages-1),
1024 4-byte physical pages per page, 12-bit left shift equals 4096 (2 12-square),
(6) "Addl%2,%%ecx\n\t"
Add a low-end memory address to get the actual physical address
%2 equals LOW_MEM, defined in the following statement
"0" (0), "I" (Low_mem), "C" (Paging_pages),
Questions:
Why is 4k* (paging_pages-1) not the actual physical address?
The answer is the following when initializing:
Mem_map[0.. ( Paging_pages)] is the main memory management array
Management is only 1-16m space, that is paging_memory = ((16-1) *1024*1024)

Does not include 0-1m (0-1m, actually 0-640k is already occupied by the kernel)

         #define  LOW_MEM 0x100000          #define  PAGING_MEMORY  (15*1024*1024)           #define  PAGING_PAGES  (paging_memory>>12)           #define &NBSP;MAP_NR (addr)   (((addr)-low_mem) >>12)          void mem_init (LONG&NBSP;START_MEM,&NBSP;LONG&NBSP;END_MEM)          {            int i;             HIGH_MEMORY = end_mem;             for  (i=0 ; i<paging_pages ;  i++) {                mem_map[i ] = used;            }//all main memory areas are initialized to occupied       &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;I&NBSP;=&NBSP;MAP_NR (START_MEM);             end_mem -= start_mem;             end_mem >>= 12;             while  (end_mem-->0)              mem_map[i++]=0;        }


(7) "Movl%%ecx,%%edx\n\t"
The value of the ECX register is saved to the EDX register, and the actual physical address is saved to the EDX register.
(8) "Movl $1024,%%ecx\n\t"
Save 1024 to the ECX register because each page occupies 4096 bytes (4K),
Actual physical memory, 4 bytes per item, 1024 items.
(9) "Leal 4092 (%%edx),%%edi\n\t"
Because they are aligned by 4 bytes, each item occupies 4 bytes,
Take the last item of the current physical page 4096 = 4096-4 = 1023*4 = (1024-1).
Save the end of the physical page in the EDI register,
The address at ecx+4092 is stored in the EDI register.
(Ten) "rep; Stosl\n\t "
Start at ecx+4092, reverse direction, step 4, repeat 1024 times,
Fill the 1024 entries in the physical page with the value of the EAX register,
In the following code definition, EAX is initialized to 0 (al=0,eax =0,ax =0)
: "0" (0), "I" (Low_mem), "C" (Paging_pages),
So the physical page 1024 items are all zeroed.
(one) "Movl%%edx,%%eax\n"
Place the physical page start address into the EAX register,
In Intel's Eabi rules,
EAX registers are used to hold function return values
(12) "1:"
Label 1, for the "jne 1f\n\t" statement jump returns 0 values,
Attention:
The EAX register is only assigned in "Movl%%edx,%%eax\n",
EAX Register initial value is ' 0 ', if jump to label "1:" Place,
The return value is 0, which means there is no free physical page.
(+): "=a" (__res)
Output register list, there is only one, where a represents the EAX register
(+): "0" (0), "I" (Low_mem), "C" (Paging_pages),
"0" means the same register as the output of the same position above, i.e. "0" equals the output register eax,
That is, the EAX is both an output register and an input register,
Of course, in the case of minimal time granularity, eax cannot be used as an input or output register,
Can only be used as input or output registers;

"I" (low_mem) is%2, from the output register to the input register sequence number%0,%1,%2.....%n,
where "I" means immediate number, not the code of EDI, the code of EDI is "D";

"C" (paging_pages) means that the ECX register is stored in Paging_pages,
ECX Register Code "C".

(+) "D" (mem_map+paging_pages-1)
"D" uses the EDI register, which is the value saved by the EDI Register (MEM_MAP+PAGING_PAGES-1)
i.e.%%edi = &mem_map[paging_pages-1].
(+): "Di", "CX", "DX");
Keep registers, tell the compiler "Di", "CX", "DX" Three registers have been assigned,
In compiler compilation, these three registers are not assigned as input or output registers.
(+) return __res;
Returns the value saved by the __res.
Equivalent to the assembly of RET, implicitly returning the EAX register,
The C language is explicitly returned.

4. Assembly instructions and parsing of grammatical rules, referring to Intel's official document "Volume 2A instruction Set Reference (a-m)"
"Volume 2B instruction Set Reference (n-z)", GNU Assembly rules
(1) Std:
Mainly the ESI and/or EDI direction is set to decrement, corresponding to CLD (for direction set to increment)
1) operation
Sets the DF flag in the EFlags register. When the DF flag was set to 1, string operations
Decrement the index registers (ESI and/or EDI).
This instruction ' s operation are the same in non-64-bit modes and 64-bit mode.
2) operation
DF-1;
(2) Repne:
1) Description
Repeats A string instruction the number of times specified in the Count register or
Until the indicated condition of the ZF flag is no longer met. The REP (repeat), Repe
(Repeat while equal), Repne (repeat when not equal), REPZ (repeat while zero), and
REPNZ (repeat while not zero) mnemonics is prefixes that can is added to one of
The string instructions. The REP prefix can added to the INS, outs, MOVS, LODs,
and stos instructions, and the Repe, Repne, REPZ, and REPNZ prefixes can be
Added to the CMPS and SCAS instructions. (The REPZ and REPNZ prefixes are synonymous
Forms of the Repe and Repne prefixes, respectively.) The behavior of the REP
Prefix is undefined if used with non-string instructions.
The REP prefixes apply only to one string instruction at a time. To repeat a block of
Instructions, use the LOOP instruction or another looping construct. All of these
Repeat prefixes cause the associated instruction to being repeated until the count in
Register is decremented to 0. See Table 4-13.

2) operation

    if addresssize = 16        then             Use CX for CountReg;         else if addresssize = 64 and rex . W used            then use rcx  for CountReg; FI;        ELSE             use ecx for countreg;    fi ;     while countreg = 0        do             service pending interrupts   (If any);            execute  associated string instruction;            countreg <-  (countreg – 1);            if  Countreg = 0            then exit  while loop; fi;            if   (Repeat prefix is repz or repe)  and  (zf = 0)              or  (REPEAT&NBSP;PREFIX&NBSP;IS&NBSP;REPNZ &NBSP;OR&NBSP;REPNE)  and  (zf = 1)              THEN exit WHILE loop; FI;         OD;

(3) SCASB:
GNU Compendium
In assembly language, SCASB is a string manipulation instruction derived from the abbreviation "SCAN string Byte". The specific operation of this directive is:
-------------------------------------------------------------------------------
Code | Mnemonic | Description
-------------------------------------------------------------------------------
AE | SCAS M8 | Compare AL with a byte at ES: (E) DI and set status flags
-------------------------------------------------------------------------------
AF |  SCAS M16 | Compare AX with Word at ES: (E) DI and set status flags
-------------------------------------------------------------------------------
AF |  SCAS M32 | Compare EAX with Doubleword at ES (E) DI and set status flags
-------------------------------------------------------------------------------
AE | SCASB | Compare AL with a byte at ES: (E) DI and set status flags
-------------------------------------------------------------------------------
AF | SCASW | Compare AX with Word at ES: (E) DI and set status flags
-------------------------------------------------------------------------------
AF | SCASD | Compare EAX with Doubleword at ES: (E) DI and set status flags
-------------------------------------------------------------------------------
Calculates al-byte of [Es:edi], sets the value of the corresponding flag register;
Modify the value of the Register EDI: If the flag df is 0, then Inc EDI, or if DF is 1, then Dec EDI.
The SCASB instruction is often used in combination with the circular instruction REPZ/REPNZ. For example, the REPNZ SCASB statement indicates that a SCASB instruction is executed once the register is ecx>0 and the flag register is zf=0.
Compare register Al's value is not equal then repeat find word
(4) Sall
such as Sall,%ECX.
This instruction is the algorithm left shift, equivalent to the C language of the left shift operator <<
The SAL in the Intel Assembler Directive (shit arithmetic left).
According to the grammar rules,
Because it is a long-form operation (ECX),
So add an "L" to the Intel assembly instruction Sal,
That is converted into Sall.
(5) Stosl
The STOSL instruction is equivalent to saving the value in EAX to the address that Es:edi points to.
If the orientation position in the eflags is set (that is, the STD instruction is used before the STOSL command)
The EDI is reduced by 4, otherwise (with the CLD Directive) the EDI is increased by 4.
(6) Eax,ax,ah,al
00000000 00000000 00000000 00000000
|===============eax===============|--32 0, 4 bytes, 2 characters, 1 double word
|======ax=======|--16 0, 2 bytes, 1 words
|==ah===|-----------8 x 0, 1 bytes
|===al==|---8 x 0, 1 bytes

The EAX is a 32-bit transmitter that simply adds one more bit of data to the original 8086CPU register ax.
So eax and Ax are not independent at all, they are the relationship between the whole and the part.
for EAX direct assignment, changing the low 16 bit naturally changes the AX value,
and Ax can affect EAX overall. The same is true for the relationship between the Ah,al register and AX.

Reprint please indicate the source, thank:-)
Redatoms Come on, Levin and Chen Hao!
myblog:http://blog.csdn.net/linpeng12358
MyMail: [email protected] or [email protected]
mygithub:davillin1577
Welcome everybody!
:), please correct me,:)


This article is from the "mountain Ask the Boy" blog, please be sure to keep this source http://linpeng.blog.51cto.com/9779987/1596700

Linux-0.11 Kernel Memory Management get_free_page () function analysis

Contact Us

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

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

A Free Trial That Lets You Build Big!

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

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

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

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