From user to kernel mode, step by step

Now that we have a very silly system call (sys_hello_world), let us see how it is called, step by step, monitoring the processor mode.
We may put breakpoint at sys_hello_world and run it step by step (using s or n). You must try it.
The big problem is that gdb is looking to the kernel source code while init is running in user mode. We can not debug init using gdb. Thus, we will make a trick, that is, we will get an address of some instruction to be executed by init. Run the gdb till this instruction, disassembly running step by step utll find the svc instruction that makes the software interrupt. At this moment, we leave the user mode and go to the kernel mode.
To get an address inside init, we do:

student@a3974e81f3d7:~/src/initramfs/build/initramfs_root$ arm-linux-gnueabi-nm  init 

in particular, hello_world:
$ arm-linux-gnueabi-nm  init|grep hello_world 
000105b4 T hello_world

Now, as usual, in one terminal make qemu ... -s -S runs and in another
Connect via gdb to qemu:

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/student/src/linux/vmlinux...done.
Remote debugging using :1234
0x00000000 in ?? ()
(gdb) b sys_hello_world
Breakpoint 1 at 0xc019b370: file sys_hello_world/sys_hello_world.c, line 6.
(gdb) b *000105b4
Invalid number "000105b4".
(gdb) b *0x000105b4
Breakpoint 2 at 0x105b4
(gdb) c
Continuing.

Breakpoint 2, 0x000105b4 in ?? ()

Now we can debut it, step by step. But gdb may show everything a friendlier way. Just type: C-x A (control x seguido de A). It is very likely that docker is not adjusted to your screen: just minimize and maximize your screen and it will be solved. In order to see more windows: C-x 2
You will get the following screen:
Look at the cpsr. We are in user mode.
I run till the instruction svc which makes the software interrupt:
The next si (step instruction) we go to the kernel!
Everything changed, specially the cpsr that says we are at the kernel. Now you may see the source code. Just make one more step and C-2. You will see:

You see the point where you enter in the kernel. It is in entry-common.S. The registers will be saved and the proper system call treatment will be called looking at the system call number. Run step by step and try to understand.
This System Call number is extracted from the svc instruction which is in lr - 4, accessed in 
USER(  ldreq   r10, [lr, #-4]          )       @ get SWI instruction
In
   eorne   scno, r10, #__NR_OABI_SYSCALL_BASE
you see that the register scno receives the sys call number, but looking directly to the assembly code (C-x 2) you see that scno is the R7 register which contains 400 according to the expected in the source code. A few steps more and we get into sys_hello_world code as in:
Certainly we are in a new world, with new tools; fantastic!

Comentários

Postar um comentário

Postagens mais visitadas deste blog

Basics on ARM processor

Assignments - 1

Assignments 2- 2021