Wang, Baojun wrote:
在 2008-06-05四的 15:32 +0530,Chetan Nanda写道:
Hi All,
I was reading the boot code for MIPS.
in head.S file before jumping to 'start_kernel' it calculate the stack
pointer address as follow:
"
PTR_LA $28, init_thread_union
PTR_ADDIU sp, $28, _THREAD_SIZE - 32
make sp point to the stack top so that we can allocate stack space
later, -32 is a reserved area for local variable, saved GPR, arguments
(function stack frame).. due to the abi
The MIPS ABI, whose official name is "System V Application Binary
Interface: MIPS(r) Processor Supplement, 3rd Edition", may be found at
http://math-atlas.sourceforge.net/devel/assembly/mipsabi32.pdf.. The
code generated by gcc does not conform to the MIPS ABI in all cases, but
it is the closest thing we have to a standard.
The init_thread_union item is a pre-allocated stack area. The PTR_LA
loads the address of the beginning of that item, but since the stack
grows down, toward smaller addresses, we need to set the stack pointer
to the highest address in the stack area. I'm pretty sure the MIPS ABI
doesn't mention anything about the 32-byte area as it doesn't address
the case of how kernel stacks should be initialized. It's not clear to
me what it's there for, but it might be helpful for detecting stack
underflows or for giving a little extra space before a buffer overflow
corrupts other kernel data structures.
set_saved_sp sp, t0, t1
set_saved_sp is defined (as a assembler macro) in
include/asm-mips/stackframe.h (if you're using vim, I think it will be
easy to use vim with cscope..)
We must load the stack pointer with pointer to a valid kernel stack
before calling any C code to handle interrupts or exceptions. The
assembly language macro set_saved_sp is how we store the kernel stack
pointer to use in such a case. The SAVE_SOME macro is generally used to
restore the stack pointer.
PTR_SUBU sp, 4 * SZREG # init stack pointer
SZREG is defined to the general purpose register size, it is 32bit in
MIPS32 and 64bit in MIPS64, so the last line allocates 16/32 bytes to
build a stack frame.. You could refer to the MIPS ABI if you need
further information (the kernel don't follow the standard ABI all the
time though..)
The MIPS ABI states that the caller of a function must reserve space for
four arguments, which are passed in the registers a0-a3, even if the
function being called is not being passed four arguments. Since SZREG is
the size of one register, 4 * SZREG reserves enough space for these four
arguments. See the section "C Stack Frame" on page 3-46 and Figures 3-37
and Figure 3-38 in the MIPS ABI for details about what C stack frames
look like.
Can anyone please explains me this 4 lines of code?
Why ' _THREAD_SIZE - 32' is added in 'sp' ?
What 'set_saved_sp' will do ?
and then why we subtract '4 * SZREG' from 'sp' ?
Please hep me to understand this code better.
Thanks,
Chetan Nanda