mirror of
https://github.com/0xAX/linux-insides
synced 2024-10-31 03:20:14 +00:00
commit
088540d0f6
@ -210,7 +210,7 @@ ENDPROC(memcpy)
|
|||||||
|
|
||||||
Yeah, we just moved to C code and now assembly again :) First of all, we can see that `memcpy` and other routines which are defined here, start and end with the two macros: `GLOBAL` and `ENDPROC`. `GLOBAL` is described in [arch/x86/include/asm/linkage.h](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/include/asm/linkage.h) which defines the `globl` directive and its label. `ENDPROC` is described in [include/linux/linkage.h](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/include/linux/linkage.h) and marks the `name` symbol as a function name and ends with the size of the `name` symbol.
|
Yeah, we just moved to C code and now assembly again :) First of all, we can see that `memcpy` and other routines which are defined here, start and end with the two macros: `GLOBAL` and `ENDPROC`. `GLOBAL` is described in [arch/x86/include/asm/linkage.h](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/include/asm/linkage.h) which defines the `globl` directive and its label. `ENDPROC` is described in [include/linux/linkage.h](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/include/linux/linkage.h) and marks the `name` symbol as a function name and ends with the size of the `name` symbol.
|
||||||
|
|
||||||
The implementation of `memcpy` is simple. At first, it pushes values from the `si` and `di` registers to the stack to preserve their values because they will change during the `memcpy`. `memcpy` and other functions in copy.S use `fastcall` calling conventions. So it gets its incoming parameters from the `ax`, `dx` and `cx` registers. Calling `memcpy` looks like this:
|
The implementation of `memcpy` is simple. At first, it pushes values from the `si` and `di` registers to the stack to preserve their values because they will change during the `memcpy`. As we can see in the `REALMODE_CFLAGS` in `arch/x86/Makefile`, the kernel build system uses the `-mregparm=3` option of GCC, so functions get the first three parameters from `ax`, `dx` and `cx` registers. Calling `memcpy` looks like this:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
memcpy(&boot_params.hdr, &hdr, sizeof hdr);
|
memcpy(&boot_params.hdr, &hdr, sizeof hdr);
|
||||||
@ -304,7 +304,7 @@ GLOBAL(memset)
|
|||||||
ENDPROC(memset)
|
ENDPROC(memset)
|
||||||
```
|
```
|
||||||
|
|
||||||
As you can read above, it uses the `fastcall` calling conventions like the `memcpy` function, which means that the function gets its parameters from the `ax`, `dx` and `cx` registers.
|
As you can read above, it uses the same calling conventions as the `memcpy` function, which means that the function gets its parameters from the `ax`, `dx` and `cx` registers.
|
||||||
|
|
||||||
The implementation of `memset` is similar to that of memcpy. It saves the value of the `di` register on the stack and puts the value of`ax`, which stores the address of the `biosregs` structure, into `di` . Next is the `movzbl` instruction, which copies the value of `dl` to the lower 2 bytes of the `eax` register. The remaining 2 high bytes of `eax` will be filled with zeros.
|
The implementation of `memset` is similar to that of memcpy. It saves the value of the `di` register on the stack and puts the value of`ax`, which stores the address of the `biosregs` structure, into `di` . Next is the `movzbl` instruction, which copies the value of `dl` to the lower 2 bytes of the `eax` register. The remaining 2 high bytes of `eax` will be filled with zeros.
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ At the end, we can see the call to the `extract_kernel` function:
|
|||||||
popq %rsi
|
popq %rsi
|
||||||
```
|
```
|
||||||
|
|
||||||
Again we set `rdi` to a pointer to the `boot_params` structure and preserve it on the stack. In the same time we set `rsi` to point to the area which should be usedd for kernel uncompression. The last step is preparation of the `extract_kernel` parameters and call of this function which will uncompres the kernel. The `extract_kernel` function is defined in the [arch/x86/boot/compressed/misc.c](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/compressed/misc.c) source code file and takes six arguments:
|
Again we set `rdi` to a pointer to the `boot_params` structure and preserve it on the stack. In the same time we set `rsi` to point to the area which should be used for kernel uncompression. The last step is preparation of the `extract_kernel` parameters and call of this function which will uncompres the kernel. The `extract_kernel` function is defined in the [arch/x86/boot/compressed/misc.c](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/compressed/misc.c) source code file and takes six arguments:
|
||||||
|
|
||||||
* `rmode` - pointer to the [boot_params](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973//arch/x86/include/uapi/asm/bootparam.h#L114) structure which is filled by bootloader or during early kernel initialization;
|
* `rmode` - pointer to the [boot_params](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973//arch/x86/include/uapi/asm/bootparam.h#L114) structure which is filled by bootloader or during early kernel initialization;
|
||||||
* `heap` - pointer to the `boot_heap` which represents start address of the early boot heap;
|
* `heap` - pointer to the `boot_heap` which represents start address of the early boot heap;
|
||||||
@ -383,10 +383,10 @@ Links
|
|||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
* [address space layout randomization](https://en.wikipedia.org/wiki/Address_space_layout_randomization)
|
* [address space layout randomization](https://en.wikipedia.org/wiki/Address_space_layout_randomization)
|
||||||
* [initrd](http://en.wikipedia.org/wiki/Initrd)
|
* [initrd](https://en.wikipedia.org/wiki/Initrd)
|
||||||
* [long mode](http://en.wikipedia.org/wiki/Long_mode)
|
* [long mode](https://en.wikipedia.org/wiki/Long_mode)
|
||||||
* [bzip2](http://www.bzip.org/)
|
* [bzip2](http://www.bzip.org/)
|
||||||
* [RDdRand instruction](http://en.wikipedia.org/wiki/RdRand)
|
* [RdRand instruction](https://en.wikipedia.org/wiki/RdRand)
|
||||||
* [Time Stamp Counter](http://en.wikipedia.org/wiki/Time_Stamp_Counter)
|
* [Time Stamp Counter](https://en.wikipedia.org/wiki/Time_Stamp_Counter)
|
||||||
* [Programmable Interval Timers](http://en.wikipedia.org/wiki/Intel_8253)
|
* [Programmable Interval Timers](https://en.wikipedia.org/wiki/Intel_8253)
|
||||||
* [Previous part](https://github.com/0xAX/linux-insides/blob/master/Booting/linux-bootstrap-4.md)
|
* [Previous part](https://github.com/0xAX/linux-insides/blob/master/Booting/linux-bootstrap-4.md)
|
||||||
|
Loading…
Reference in New Issue
Block a user