Doszedłem do punktu z moim hobby x86_64 UEFI jądro gdzie kod użytkownika wywołuje kod systemowy, ale generuje ogólny błąd ochrony z kodem błędu 0 przy 0x1B: 0x0 (0x1B jest selektorem segmentu kodu trybu użytkownika). Po wykonaniu tego kroku zdałem sobie sprawę, że SYSRET nie powraca do adresu przechowywanego w RCX, ale zamiast tego jest ustawiony na zero. Debuguję za pomocą qemu-system-x86_64 z lub bez KVM. Załączono dwa zrzuty ekranu dotyczące tego zjawiska. Czy ktoś mógłby mi to wyjaśnić i powiedzieć, co mam zrobić źle?Dlaczego SYSRET powraca do adresu 0, gdy RCX ma poprawny adres zwrotny?
MSR 0xC0000080 = 0x0000000000000501
MSR 0xC0000081 = 0x001B00083D906D79
MSR 0xC0000082 = 0x000000003D906D79
MSR 0xC0000083 = 0x000000003D906D79
MSR 0xC0000084 = 0x0000000000000300
Przerwania wyłączone przy użyciu wpisów Cli i Local APIC.
GDT:
{ 0, 0, 0, 0x9A, 0x20, 0 }; // 0x08 ring 0 code
{ 0, 0, 0, 0x92, 0x00, 0 }; // 0x10 ring 0 data
{ 0, 0, 0, 0xFA, 0x20, 0 }; // 0x1B ring 3 code
{ 0, 0, 0, 0xF2, 0x00, 0 }; // 0x23 ring 3 data
{ 0, 0, 0, 0xFA, 0x20, 0 }; // 0x2B ring 3 code
{ 0, 0, 0, 0xF2, 0x00, 0 }; // 0x33 ring 3 data
typedef struct PACKED ENTRY
{
U16 limit_0_15;
U16 base_0_15;
U8 base_16_23;
U8 access;
U8 granularity;
U8 base_24_31;
} ENTRY, *PENTRY;
EDIT: Po przeczytaniu ponownie instrukcję, zauważyłem, że w trybie długiego powrotu CS będzie (STAR.SYSRET_CS + 16) | 3, więc powieliłem deskryptory segmentów trybu użytkownika, aby mieć pewność, ale wyniki są takie same.
Czy przybyłeś na rozwiązanie? Mam do czynienia z tym samym problemem. –
Nie. Na razie używam przerwań. – YaniMan