I am trying to read kernel image and calculate a checksum value of this image. Firstly, I used a smc instruction to trigger a exception, and in the exception handler, I tried to read the first bytes of the image. I don't really know what the address is, but from some documents, I know the kernel image is decompressed in address like 0x20008000, 0x30008000 or 0xC0008000(they call this ZRELADDR, i don't really know whether this is the right address...). So I tried to read the memory like this:
uint32_t test; test = * (uint32_t *)0x30008000; DMSG("test : %x\n",test);
But the system crashed with a data abort exception,
core data-abort at address 0x30008000 fsr 0x00000005 ttbr0 0x7df7006a ttbr1 0x7df7006a cidr 0x0 cpu #0 cpsr 0x200001b3 r0 0x00000090 r4 0x7df4bf51 r8 0x00000000 r12 0x00000000 r1 0x09010000 r5 0x806665e0 r9 0x00000000 sp 0x7df77f50 r2 0x0000000d r6 0x7f002000 r10 0x00000000 lr 0x7df273ff r3 0x30008000 r7 0x7df77f60 r11 0x00000000 pc 0x7df052f0 ERR TEE-CORE:tee_pager_handle_fault:602: Unexpected page fault! Trap CPU PANIC: tee_pager_handle_fault core/arch/arm/mm/tee_pager.c:603
I guess I am on the wrong way. Does anyone know how to read the kernel image in runtime environment?
Thanks for your help!
EDIT:Thanks for your reply. I am talking about secure kernel. I am trying to check the integrity of the kernel under TrustZone, and to insure the kernel haven't be compromised. So I guess a checksum like hash value may help me. Also, I am a novice who is trying to be familiar with the memory system of arm, so I tried to start with simple read some certain memory address. I have tried to read 0xc0000000 as Artless Noise said, but the same error occurs again. Again I tried to find "_test" and "stext" address in System.map, which is 0x80008000, and error occurs again.
The beginning of the RAM is usually mapped at 0xC0000000. This depends on CONFIG_PAGE_OFFSET:
- VMSPLIT_3G: 0xC0000000 - VMSPLIT_2G: 0x80000000 - VMSPLIT_1G: 0x40000000
Note that this is a virtual address if you have an MMU (usual case), the physical address will depend on your actual architecture (it may or may not be 0x00000000). The kernel is loaded a few pages after that, at an offset of 0x8000.
So, you can probably find the (uncompressed) kernel at 0xC0008000 but it may as well be located somewhere else.
You can also try to ioremap() offset 0x8000 of your RAM.
Can you give us a bit more information on the particular SoC you are working on?
If you are in secure mode and you believe that in secure mode it access physical address then from below these macro you can deduce the physical address.
The physical address at which kernel loads is PHYS_OFFSET + TEXT_OFFSET (text offset is 0x8000),
PHYS_OFFSET definition will be depend on the CONFIG_ARM_PATCH_PHYS_VIRT patch.
if CONFIG_ARM_PATCH_PHYS_VIRT is defined, then PHYS_OFFSET will be equal to __pv_phys_offset otherwise PHYS_OFFSET will be defined as CONFIG_PHYS_OFFSET in your kernel config file.
User contributions licensed under CC BY-SA 3.0