下面的实验,用到两个文件
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条指令就死机,毕竟这不是真正的内核代码入口,可以理解。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐