LINUX内核直接加载到内存当作UBOOT的一个应用运行
下面的实验,用到两个文件
1、LINUX 未OBJCOPY前的内核,称为vmlinux
2、 LINUX经OBJCOPY的内核, 称为vmlinux.bin
实验的第一步,要确定内核加载地址,解决我要把内核代码TFTP到内存位置
方法:
objdump -d vmlinux
重点关注头部信息
1_text值81001000。这个就是内核代码要加载的位置。
1
2 kernel/opensrc/linux/linux: file format elf32-tradlittlemips
3
4
5 Disassembly of section .text:
6
7 81001000 <_text>:
8 ...
9
10 81001400 <__kernel_entry>:
11 81001400: 084027b0 j 81009ec0 <kernel_entry>
12 81001404: 00000000 nop
13 81001408: 5452574f bnel v0,s2,81017148 <do_signal+0x160>
14 8100140c: 3a425444 xori v0,s2,0x5444
15
16 81001410 <__image_dtb>:
17 ...
18
19 81005420 <ret_from_exception>:
20 81005420: 41606000 di
21 81005424: 000000c0 ehb
22 81005428: 10000002 b 81005434 <__ret_from_irq>
23 8100542c: 00000000 nop
24
可以再打开vmlinux.bin,找一段指令对比,如__kernel_entry这段指令正好是在400处。
b0 27 40 08 20 20 20 20 4f 57 52 54 44 54 42
因此,可确认,vmlinux.bin应该放到81001000.=text
=> tftp 81001000 vmlinux.bin
Using eth@1e100000 device
TFTP from server 192.168.100.191; our IP address is 192.168.100.5
Filename 'vmlinux.bin'.
Load address: 0x81001000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
##########################################
3.8 MiB/s
done
Bytes transferred = 13964096 (d51340 hex)
=> md 81001400
81001400: 084027b0 00000000 5452574f 3a425444 .'@.....OWRTDTB:
81001410: 00000000 00000000 00000000 00000000 ................
81001420: 00000000 00000000 00000000 00000000 ................
81001430: 00000000 00000000 00000000 00000000 ................
81001440: 00000000 00000000 00000000 00000000 ................
81001450: 00000000 00000000 00000000 00000000 ................
81001460: 00000000 00000000 00000000 00000000 ................
81001470: 00000000 00000000 00000000 00000000 ................
81001480: 00000000 00000000 00000000 00000000 ................
81001490: 00000000 00000000 00000000 00000000 ................
810014a0: 00000000 00000000 00000000 00000000 ................
810014b0: 00000000 00000000 00000000 00000000 ................
810014c0: 00000000 00000000 00000000 00000000 ................
810014d0: 00000000 00000000 00000000 00000000 ................
810014e0: 00000000 00000000 00000000 00000000 ................
810014f0: 00000000 00000000 00000000 00000000 ................
=>
=> go 81001000
## Starting application at 0x81001000 ...
Linux version 4.4.198 (8@mp) (gcc version 5.4.0 (LEDE GCC 5.4.0 r2996-c71e13a) ) #22 SMP Fri Jan 13 15:23:16 CST 2023
SoC Type: MediaTek MT7621 ver:1 eco:3
bootconsole [early0] enabled
CPU0 revision is: 0001992f (MIPS 1004Kc)
Determined physical RAM map:
memory: 10000000 @ 00000000 (usable)
Log Memory: 65536
Initrd not found or empty - disabling initrd
Zone ranges:
DMA [mem 0x0000000000000000-0x0000000000ffffff]
Normal [mem 0x0000000001000000-0x000000000fffffff]
Movable zone start for each node
Early memory node ranges
node 0: [mem 0x0000000000000000-0x000000000fffffff]
Initmem setup node 0 [mem 0x0000000000000000-0x000000000fffffff]
VPE topology {2,2} total 4
Primary instruction cache 32kB, VIPT, 4-way, linesize 32 bytes.
Primary data cache 32kB, 4-way, PIPT, no aliases, linesize 32 bytes
MIPS secondary cache 256kB, 8-way, linesize 32 bytes.
No valid device tree found, continuing without
PERCPU: Embedded 10 pages/cpu @81fd9000 s9024 r8192 d23744 u40960
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 65024
Kernel command line: 81001000
PID hash table entries: 1024 (order: 0, 4096 bytes)
Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
Writing ErrCtl register=00044c04
Readback ErrCtl register=00044c04
Memory: 245476K/262144K available (7645K kernel code, 4085K rwdata, 1668K rodata, 284K init, 460K bss, 16668K reserved, 0K cma-reserved)
SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
Hierarchical RCU implementation.
NR_IRQS:256
Kernel panic - not syncing: Failed to find mtk,mt7621-sysc node
Rebooting in 1 seconds..
Reboot failed -- System halted
OK, LINUX内核直接加载到内存,当作UBOOT的一个应用运行起来了!!!!!
继续分析这个内核的入口,是否start_kernel也可以跳转过去执行。
答案是:这个地址能执行,但因为start_kernel之前还需要靠kernel_entry作一些初始化工作,这些工作跳过会导致内核执行不到打印BANNER就死了。
=> tftp 81001000 vmlinux.bin
Using eth@1e100000 device
TFTP from server 192.168.100.191; our IP address is 192.168.100.5
Filename 'vmlinux.bin'.
Load address: 0x81001000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
##########################################
3.7 MiB/s
done
Bytes transferred = 13964096 (d51340 hex)
=> md 81d19780
81d19780: 3c048193 27bdffb8 24841e60 afbf0044 ...<...'`..$D...
81d19790: afb40040 afb3003c afb20038 afb10034 @...<...8...4...
81d197a0: 0c40b3a3 afb00030 0c7465dc 00000000 ..@.0....et.....
81d197b0: 27a4002c 0c49dc52 24050004 3c020004 ,..'R.I....$...<
81d197c0: 244304c6 8fa2002c 00431026 afa2002c ..C$,...&.C.,...
81d197d0: 8f840000 ac820250 8f820000 8c440250 ....P.......P.D.
81d197e0: 3c028193 ac449874 41606000 000000c0 ...<t.D..``A....
81d197f0: 8f90000c 24140001 02002021 3c128193 .......$! .....<
81d19800: 24050001 0c40bef8 a2549848 02002021 ...$..@.H.T.! ..
81d19810: 0c40bf24 24050001 02002021 0c40beda $.@....$! ....@.
81d19820: 24050001 02002021 0c40bebc 24050001 ...$! ....@....$
81d19830: 3c058182 3c048182 24a52cb4 0c41b9c5 ...<...<.,.$..A.
81d19840: 248423b4 3c1081d4 0c74739c 27a4002c .#.$...<.st.,..'
81d19850: 2604584c 3c028193 8fb1002c 0c4845ff LX.&...<,....EH.
81d19860: ac406cc4 24440001 3c060100 0c74a047 .l@...D$...<G.t.
81d19870: 24050020 3c1381d6 2604584c 0c4845ff ..$...<LX.&.EH.
=> go 81d19780
## Starting application at 0x81D19780 ...
Ooops:
$ 0 : 00000000 00000001 f68846f5 000404c6
$ 4 : 543a2047 00000000 00000000 76dc4190
$ 8 : 00000008 81009d28 00000000 0000001f
$12 : 81d8d884 0000000c 00000000 0000000e
$16 : 00000002 8fe7ef08 81d19780 8fe7ef08
$20 : 8fe7ef4c 00000002 00000020 00001000
$24 : 00000000 00000007
$28 : be10a818 8fe7ec58 80007b40 81d197bc
Hi : 00000000
Lo : 00000004
epc : 81d197d4 (text 71f797d4)
ra : 81d197bc (text 71f797bc)
Status: 00000006
Cause : 40008014 (ExcCode 05)
BadVA : 8fe7ebfc
PrId : 0001992f
### ERROR ### Please RESET the board ###
即执行到81D197D4,81d197e4: ac449874 sw a0,-26508(v0),如下 :
81d19780 <start_kernel>:
81d19780: 3c048193 lui a0,0x8193
81d19784: 27bdffb8 addiu sp,sp,-72
81d19788: 24841e60 addiu a0,a0,7776
81d1978c: afbf0044 sw ra,68(sp)
81d19790: afb40040 sw s4,64(sp)
81d19794: afb3003c sw s3,60(sp)
81d19798: afb20038 sw s2,56(sp)
81d1979c: afb10034 sw s1,52(sp)
81d197a0: 0c40b3a3 jal 8102ce8c <set_task_stack_end_magic>
81d197a4: afb00030 sw s0,48(sp)
81d197a8: 0c7465dc jal 81d19770 <smp_setup_processor_id>
81d197ac: 00000000 nop
81d197b0: 27a4002c addiu a0,sp,44
81d197b4: 0c49dc52 jal 81277148 <get_random_bytes>
81d197b8: 24050004 li a1,4
81d197bc: 3c020004 lui v0,0x4
81d197c0: 244304c6 addiu v1,v0,1222
81d197c4: 8fa2002c lw v0,44(sp)
81d197c8: 00431026 xor v0,v0,v1
81d197cc: afa2002c sw v0,44(sp)
81d197d0: 8f840000 lw a0,0(gp)
81d197d4: ac820250 sw v0,592(a0)
81d197d8: 8f820000 lw v0,0(gp)
81d197dc: 8c440250 lw a0,592(v0)
81d197e0: 3c028193 lui v0,0x8193
81d197e4: ac449874 sw a0,-26508(v0)
81d197e8: 41606000 di
81d197ec: 000000c0 ehb
81d197f0: 8f90000c lw s0,12(gp)
这里得到另一个结论是:
内核kernel_entry可以通过UBOOT的GO指令来执行,内核基本上能够起来,基本等价于正常启动。如果参数传递正确,估计还能进一步往下走。
内核start_kernel的地址,虽然理论上任一个地址也可以直接go过去,但直接GO到这个地址,执行就会死得很快,30条指令就死机,毕竟这不是真正的内核代码入口,可以理解。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)