the 1st edition: 20120316
the 2nd edition: 20160128
之前寫在 linker script 裡的變數
__bss_start__ =.;
.bss :
{
*(.bss)
}
__bss_end__ = .;
有 type 的區別。
當我使用 32 bit 暫存器時
# init bss
init_bss_asm:
movl $__bss_end__, %edi /* Destination */
movl $__bss_start__, %esi /* Source */
jmp 2f
1:
movl %esi, %eax
movb $0x0, (%eax)
addl $1, %esi
2:
cmpl %edi, %esi
jne 1b
ret
objdump -x p_kernel.o
000000a4 R_386_32 __bss_end__
000000a9 R_386_32 __bss_start__
而使用 16 bit 暫存器時
init_bss_asm:
movw $__bss_end__, %di /* Destination */
movw $__bss_start__, %si /* Source */
# movw $0x0, %ax
# movw %ax, %gs
jmp 2f
1:
movw %si, %ax
movb $0x0, (%eax)
# movb $0x1, (%eax)
# movb $0x1, %ds:(%eax)
add $1, %si
2:
cmpw %di, %si
jne 1b
ret
objdump -x p_kernel.o
000000a4 R_386_16 __bss_end__
000000a9 R_386_16 __bss_start__
遇到一個這樣的問題:
當我在 C 語言用了
u8 task_stack[0x9000];
這麼大的變數 (存放在 .bss section)
然後照樣 make 我的 kernel, 結果竟然跳出來令我傻眼的錯誤訊息:
descent@ubuntu:simple_os$ make p_kernel.elf
as -o p_kernel.o p_kernel.s
gcc -std=c99 -fno-stack-protector -ffreestanding -fno-builtin -g -c process.c
ld -nostdlib -M -g -o p_kernel.elf -Tk.ld p_kernel.o start.o process.o > p_kernel.elf.map
p_kernel.o: In function `init_bss_asm':
(.text+0xa5): relocation truncated to fit: R_386_16 against symbol `__bss_end__' defined in *ABS* section in p_kernel.elf
媽呀!這是什麼意思阿!
亂想的過程不重要, 反正最後就是 type 不對, bss 無法超過某個值, google 很久, code 亂改了很久, 終於被我猜到是這個問題。
修改成用 32 bit register, 這兩個變數 __bss_end__, __bss_start__ 的 type 就變成 R_386_32, 我也可以加大我的 .bss section。
真的把我嚇壞了。
20160127 補充:
在 porting simple_stdcpplib 到 x86 16 bit 環境時, 我又遇到這問題了:
x86.ld
1 ENTRY(begin)
2
3 SECTIONS
4 {
5 . = 0x100;
6
7 .text :
8 {
9 KEEP(*(booting))
10 KEEP(*(.isr_vector))
11 *(.text)
12 *(.text.*)
13 _etext = .;
14 _sidata = .;
15 }
16
17
18 .= ALIGN(32);
19 .rodata :
20 {
21 *(.rodata)
22 *(.rodata.*)
23 }
24
25 init_array :
26 {
27 __start_global_ctor__ = .;
28 *(.init_array)
29 __end_global_ctor__ = .;
30 _sidata = .;
31 }
32
33
34
35 /* Initialized data will initially be loaded in FLASH at the end of the .text section. */
36 /* .data : AT(0x5000) */
37 .data :
38 {
39 _data = .;
40
41 _sdata = .;
42 *(.ccm)
43
44 *(.data) /* Initialized data */
45 _edata = .;
46 }
47
48 .myheap (NOLOAD):
49 {
50 . = ALIGN(8);
51 *(.myheap)
52 . = ALIGN(8);
53 }
54
55 /*
56 .sig : AT(0x7DFE)
57 {
58 SHORT(0xaa55);
59 }
60 */
61 .bss :
62 {
63 _bss = .;
64 _sbss = .;
65 *(.bss) /* Zero-filled run time allocate data memory */
66 _ebss = .;
67 }
68 _estack = 0xa0000; /* 640k */
69 }
l
1 #arm-none-eabi-g++ -m32 -fno-common -g -DX86 -DX86_16 -I. -Ix86 -fno-exceptions -fno-rtti -ffreestanding -nostdlib -nodefaultlibs -std=c++11 -g -Wl,--build-id=none -Wl,-T./x86.ld -nostartfiles -o mymain.elf mymain.o -L. -lmystdcpp -lgcc
2 g++ -m32 -fno-common -g -DX86 -DX86_16 -I. -Ix86 -fno-exceptions -fno-rtti -ffreestanding -nostdlib -nodefaultlibs -std=c++11 -g -Wl,--build-id=none -Wl,-T./x86.ld -nostartfiles -o mymain.elf mymain.o -L. -lmystdcpp -lgcc
3 ./libmystdcpp.a(mem.o): In function `print_memarea()':
4 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:52:(.text+0x33): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
5 ./libmystdcpp.a(mem.o): In function `(anonymous namespace)::search_free_area(unsigned char)':
6 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:124:(.text+0x27a): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
7 ./libmystdcpp.a(mem.o): In function `(anonymous namespace)::mymalloc_internal(unsigned char)':
8 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:141:(.text+0x31d): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
9 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:147:(.text+0x35f): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
10 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:151:(.text+0x372): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
11 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:154:(.text+0x3a1): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
12 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:156:(.text+0x3c9): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
13 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:156:(.text+0x3d0): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
14 ./libmystdcpp.a(mem.o): In function `myfree(void*)':
15 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:191:(.text+0x4c6): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
16 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:194:(.text+0x4d0): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
17 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:194:(.text+0x4e0): additional relocation overflows omitted from the output
18 collect2: error: ld returned 1 exit status
19 makefile:85: recipe for target 'mymain.elf' failed
20 make: *** [mymain.elf] Error 1
看起來是在 access .bss section 的時候, .bss type 是 r_386_16, 但是我不知道怎麼改動其 type 為 r_386_32, 最後修改 x86.ld, 讓 .bss 放在 .text 後面, 很不優雅的解決這問題。
modify x86.ld
1 ENTRY(begin)
2
3 SECTIONS
4 {
5 . = 0x100;
6
7 .text :
8 {
9 KEEP(*(booting))
10 KEEP(*(.isr_vector))
11 *(.text)
12 *(.text.*)
13 _etext = .;
14 _sidata = .;
15 }
16 .bss :
17 {
18 _bss = .;
19 _sbss = .;
20 *(.bss) /* Zero-filled run time allocate data memory */
21 _ebss = .;
22 }
23
24
25 .= ALIGN(32);
26 .rodata :
27 {
28 *(.rodata)
29 *(.rodata.*)
30 }
31
32 init_array :
33 {
34 __start_global_ctor__ = .;
35 *(.init_array)
36 __end_global_ctor__ = .;
37 _sidata = .;
38 }
39
40
41
42 /* Initialized data will initially be loaded in FLASH at the end of the .text section. */
43 /* .data : AT(0x5000) */
44 .data :
45 {
46 _data = .;
47
48 _sdata = .;
49 *(.ccm)
50
51 *(.data) /* Initialized data */
52 _edata = .;
53 }
54
55 .myheap (NOLOAD):
56 {
57 . = ALIGN(8);
58 *(.myheap)
59 . = ALIGN(8);
60 }
61
62 /*
63 .sig : AT(0x7DFE)
64 {
65 SHORT(0xaa55);
66 }
67 */
68 _estack = 0xa0000; /* 640k */
69 }
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。