只谈一个问题:
head_common.S中__switch_data:
.long init_thread_union + THREAD_START_SP
init_thread_union 使用ctags无法跳转,且链接脚本中没有init_thread_union,使用grep搜索下发现这是在arch/unicore/kernel/init_task.c3 中的联合体变量名称(无法跳转,且不再链接脚本中,即该文件根本汇编文件并不像C文件那样,需要包含头文件,再加extern外部声明)。所以我们在head_common.S中用一个C中的联合体变量名加上了一个常数值。这是因为一个C中联合体变量名被当成了标号,就像汇编文件中的标号一样,所以可以用一个C中的联合体变量名加上了一个常数值。写了一个很小的测试(下程序无任何意义,形式!!!):
sramboot.S文件:
1 #include"regdef.h"
2 .set noreorder
3 .text
4 .globl start
5 start:
6 .set noat
7 la at,value
8 lw a1, 4(at)
9 jal my_add
10 nop
11 add a2, a0, a1
12 sw a2, 8(at)
call.S文件:
1 #include"regdef.h"
2 /*
3 extern union thread_union init_thread_union;
4 */
5 .set noreorder
6 .text
7 .globl my_add,value
8 my_add:
9 add a1,a1,3
10 jal start_kernel
11 j ra
12 add a1,a1,4
13 .data
14 value:
15 .word 10,20,0
16 .long init_thread_union+8
union.c文件:
1 #define __init_task_data __attribute__((__section__(".data.init_task")))
2 struct thread_info
3 {
4 int id;
5 int time;
6 };
7 union thread_union
8 {
9 struct thread_info thread_info;
10 unsigned long stack[16];
11 };
12
13 union thread_union init_thread_union __init_task_data=
14 {
15 {.id = 9, .time= 8,},
16 };
17 void start_kernel(void)
18 {
19 while(1);
20 }
Makefile文件
1 CROSS_COMPILE = mipsel-linux-
2 CC = $(CROSS_COMPILE)gcc
3 AS = $(CROSS_COMPILE)as
4 LD = $(CROSS_COMPILE)ld
5 OBJDUMP = $(CROSS_COMPILE)objdump
6 OBJCOPY = $(CROSS_COMPILE)objcopy
7 TEXTBASE =# -Ttext
8 DATABASE =
9 LDFLAGS = $(TEXTBASE) $(DATABASE) -T my.ld
10
11 test.bin:test.exe
12 $(OBJCOPY) -O binary test.exe test.bin
13
14 test.exe:union.o call.o sramboot.o
15 $(LD) sramboot.o call.o union.o $(LDFLAGS) -o test.exe
16 $(OBJDUMP) -D test.exe > test.dump
17
18 sramboot.o:sramboot.S
19 $(CC) -E sramboot.S -o sramboot.s
20 $(AS) sramboot.s -o sramboot.o
21 @rm sramboot.s
22
23 call.o:call.S
24 $(CC) -E call.S -o call.s
25 $(AS) call.s -o call.o
26 @rm call.s
27 union.o:union.c
28 $(CC) -c union.c -o union.o
29 clean:
30 @rm *.o *.exe *.bin *.dump
my.ld链接脚本文件:
1OUTPUT_FORMAT("elf32-tradlittlemips","elf32-tradbigmips","elf32-tradlittlemips")
2 OUTPUT_ARCH(mips)
3 ENTRY(start)
4 SECTIONS
5 {
6 . =0;
7 .init :
8 {
9 sramboot.o
10 }
11
12 .text :
13 {
14 *(.text)
15 }
16 .data :
17 {
18 . = ALIGN(32);
19 *(.data.init_task);
20 . = ALIGN(16);
21 *(.data)
22 }
23 .bss :
24 {
25 *(.bss)
26 }
27 }
test.sh原生二进制反汇编脚本:
1#! /bin/sh
2 mipsel-linux-objdump -D -m mips -b binary -EL -M no-aliases -z test.bin >my.dump
执行make生成的test.dump文件:
1
2 test.exe: file format elf32-tradlittlemips
3
4 Disassembly of section .init:
5
6 00000000 <start>:
7 0: 3c010000 lui at,0x0
8 4: 242100c0 addiu at,at,192
9 8: 8c250004 lw a1,4(at)
10 c: 0c000010 jal 40 <my_add>
11 10: 00000000 nop
12 14: 00853020 add a2,a0,a1
13 18: ac260008 sw a2,8(at)
14 1c: 00000000 nop
15 20: 90000072 lbu zero,114(zero)
16 ...
17 Disassembly of section .text:
18
19 00000040 <my_add>:
20 40: 20a50003 addi a1,a1,3
21 44: 0c000014 jal 50 <start_kernel>
22 48: 03e00008 jr ra
23 4c: 20a50004 addi a1,a1,4
24
25 00000050 <start_kernel>:
26 50: 27bdfff8 addiu sp,sp,-8
27 54: afbe0000 sw s8,0(sp)
28 58: 03a0f021 move s8,sp
29 5c: 1000ffff b 5c <start_kernel+0xc>
30 60: 00000000 nop
31 ...
32 Disassembly of section .data:
33
34 00000070 <init_thread_union-0x10>:
35 ...
36
37 00000080 <init_thread_union>:
38 80: 00000009 jalr zero,zero
39 84: 00000008 jr zero
40 88: 00000000 nop
41 ...
42
43 000000c0 <value>:
44 c0: 0000000a 0xa
45 c4: 00000014 0x14
46 c8: 00000000 nop
47 cc: 00000088 0x88
48 Disassembly of section .pdr:
49
50 00000000 <.pdr>:
51 0: 00000050 0x50
52 4: 40000000 mfc0 zero,$0
53 8: fffffff8 0xfffffff8
54 ...
55 14: 00000008 jr zero
56 18: 0000001e 0x1e
57 1c: 0000001f 0x1f
58 Disassembly of section .comment:
59
60 00000000 <.comment>:
61 0: 43434700 c0 0x1434700
62 4: 4728203a c1 0x128203a
63 8: 2029554e addi t1,at,21838
64 c: 2e312e34 sltiu s1,s1,11828
65 10: Address 0x0000000000000010 is out of bounds.
执行test.sh生成的my.dump文件:
1
2 test.bin: file format binary
3
4 Disassembly of section .data:
5
6 0000000000000000 <.data>:
7 0: 3c010000 lui at,0x0
8 4: 242100c0 addiu at,at,192
9 8: 8c250004 lw a1,4(at)
10 c: 0c000010 jal 0x40
11 10: 00000000 sll zero,zero,0x0
12 14: 00853020 add a2,a0,a1
13 18: ac260008 sw a2,8(at)
14 1c: 00000000 sll zero,zero,0x0
15 20: 90000072 lbu zero,114(zero)
16 24: 00000000 sll zero,zero,0x0
17 28: 00000000 sll zero,zero,0x0
18 2c: 00000000 sll zero,zero,0x0
19 30: 00000000 sll zero,zero,0x0
20 34: 00000000 sll zero,zero,0x0
21 38: 00000000 sll zero,zero,0x0
22 3c: 00000000 sll zero,zero,0x0
23 40: 20a50003 addi a1,a1,3
24 44: 0c000014 jal 0x50
25 48: 03e00008 jr ra
26 4c: 20a50004 addi a1,a1,4
27 50: 27bdfff8 addiu sp,sp,-8
28 54: afbe0000 sw s8,0(sp)
29 58: 03a0f021 addu s8,sp,zero
30 5c: 1000ffff beqz zero,0x5c
31 60: 00000000 sll zero,zero,0x0
32 64: 00000000 sll zero,zero,0x0
33 68: 00000000 sll zero,zero,0x0
34 6c: 00000000 sll zero,zero,0x0
35 70: 00000000 sll zero,zero,0x0
36 74: 00000000 sll zero,zero,0x0
37 78: 00000000 sll zero,zero,0x0
38 7c: 00000000 sll zero,zero,0x0
39 80: 00000009 jalr zero,zero
40 84: 00000008 jr zero
41 88: 00000000 sll zero,zero,0x0
42 8c: 00000000 sll zero,zero,0x0
43 90: 00000000 sll zero,zero,0x0
44 94: 00000000 sll zero,zero,0x0
45 98: 00000000 sll zero,zero,0x0
46 9c: 00000000 sll zero,zero,0x0
47 a0: 00000000 sll zero,zero,0x0
48 a4: 00000000 sll zero,zero,0x0
49 a8: 00000000 sll zero,zero,0x0
50 ac: 00000000 sll zero,zero,0x0
51 b0: 00000000 sll zero,zero,0x0
52 b4: 00000000 sll zero,zero,0x0
53 b8: 00000000 sll zero,zero,0x0
54 bc: 00000000 sll zero,zero,0x0
55 c0: 0000000a 0xa
56 c4: 00000014 dsllv zero,zero,zero
57 c8: 00000000 sll zero,zero,0x0
58 cc: 00000088 0x88