#ld #att
Вопрос:
Я недавно изучаю язык ассемблера и пытаюсь создать ядро для своей крошечной ОС, но пока я пытался связать коды, появилось предупреждение: командная строка
ld -b elf64-x86-64 -o system head.o main.o -T Kernel.lds
и раковина дает мне
ld: warning: cannot find entry symbol _start; defaulting to ffff800000100000
Но на самом деле я написал глобальный символ «_start» в своей голове.S.
Вот код в head.S:
//======= GDT_Table
.section .data
.globl GDT_Table
GDT_Table:
.quad 0x0000000000000000 /*0 NULL descriptor 00*/
.quad 0x0020980000000000 /*1 KERNEL Code 64-bit Segment 08*/
.quad 0x0000920000000000 /*2 KERNEL Data 64-bit Segment 10*/
.quad 0x0020f80000000000 /*3 USER Code 64-bit Segment 18*/
.quad 0x0000f20000000000 /*4 USER Data 64-bit Segment 20*/
.quad 0x00cf9a000000ffff /*5 KERNEL Code 32-bit Segment 28*/
.quad 0x00cf92000000ffff /*6 KERNEL Data 32-bit Segment 30*/
.fill 10,8,0 /*8 ~ 9 TSS (jmp one segment <7>) in long-mode 128-bit 40*/
GDT_END:
GDT_POINTER:
GDT_LIMIT: .word GDT_END - GDT_Table - 1
GDT_BASE: .quad GDT_Table
//======= IDT_Table
.globl IDT_Table
IDT_Table:
.fill 512,8,0
IDT_END:
IDT_POINTER:
IDT_LIMIT: .word IDT_END - IDT_Table - 1
IDT_BASE: .quad IDT_Table
//======= TSS64_Table
.globl TSS64_Table
TSS64_Table:
.fill 13,8,0
TSS64_END:
TSS64_POINTER:
TSS64_LIMIT: .word TSS64_END - TSS64_Table - 1
TSS64_BASE: .quad TSS64_Table
//======= init table
.align 8
.org 0x1000
__PML4E:
.quad 0x102007
.fill 255,8,0
.quad 0x102007
.fill 255,8,0
.org 0x2000
__PDPTE:
.quad 0x103003
.fill 511,8,0
.org 0x3000
__PDE:
.quad 0x000083
.quad 0x200083
.quad 0x400083
.quad 0x600083
.quad 0x800083
.quad 0xe0000083 /*0x a00000*/
.quad 0xe0200083
.quad 0xe0400083
.quad 0xe0600083
.quad 0xe0800083 /*0x1000000*/
.quad 0xe0a00083
.quad 0xe0c00083
.quad 0xe0e00083
.fill 499,8,0
.section .text
.globl _start
_start:
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %ss
mov $0x7e00 %esp
//======= load GDTR
lgdt GDT_POINTER(%rip)
//======= load IDTR
lidt IDT_POINTER(%rip)
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
mov $0x7e00 %rsp
//======= load cr3
movq $0x101000, %rax
movq %rax, %cr3
movq switch_seg(%rip), %rax
pushq $0x08
pushq %rax
lretq
//======= 64-bit mode code
switch_seg:
.quad entry64
entry64:
movq $0x10, %rax
mov %rax, %ds
mov %rax, %es
mov %rax, %gs
mov %rax, %ss
mov $0xffff800000007e00, %rsp /* rsp address */
movq go_to_kernel(%rip), %rax /* movq address */
pushq $0x08
pushq %rax
lretq
go_to_kernel:
.quad Start_Kerneladdress
Файл Makefile выглядит следующим образом:
all: system
objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O binary system kernel.bin
head.o: head.S
gcc -E head.S > head.s
as --64 -o head.o head.s
main.o: main.c
gcc -mcmodel=large -fno-builtin -m64 -c main.c
system: head.o main.o
ld -b elf64-x86-64 -o system head.o main.o -T Kernel.lds
Среда Ubuntu-20.04 как wsl2 в Windows10.