LINUX.ORG.RU

Посоветуйте курс лекций по программированию в x86-64 long mode

 , , ,


1

2

Стало интересным попробовать себя в osdev, точнее в самых основах osdev - в программировании современных x86-64 процессоров в long mode режиме (не путать с 32-х битным защищённым режимом).

Хотел бы найти курс лекций, желательно на русском, где хорошо и доходчиво объясняют что к чему, как в этом режиме вообще программировать и как реализовывать самые базовые части ОС, например простой планировщик задач.

Можете ли посоветовать что-то, по уровню подачи материала, похожее на курс лекций о C++ от Ильи Мещерина?

Обычный ассемблер 8086 я знаю, хотя и не пользовался им уже довольно давно.


Ответ на: комментарий от hummer

Меня интересует конкретная процессорная технология

Особенности конкретной модели процессорах – в даташитах разработчика процессора.

Особенности архитектуры – в документации разработчика этой ISA:

https://www.amd.com/system/files/TechDocs/24593.pdf#page=70

https://www.amd.com/system/files/TechDocs/24594.pdf#G12.1115827

https://www.amd.com/system/files/TechDocs/24592.pdf#G8.884864

vM ()
Ответ на: комментарий от hummer

4.1.1. Общий обзор

Доступ к 64-битным регистрам и новым регистрам осуществляется через специальный REX-префикс. Таким образом, все опкоды команд, которые работают с 64-битными регистрами, увеличиваются в размере как минимум на 1 байт, и возникает серьёзная проблема оптимизации кода. Поэтому рекомендуется везде, где возможно, использовать 32-битные регистры

Разумно. Но почему же Руслан Зуфярыч не следует своей же рекомендации в своих учебно-демонстрационных примерах?

Функция ZeroPage_4K из part4\sample4.2\LM_CODE.ASM на прилагаемом к книге CD (архив с исходниками можно скачать с официального сайта книги http://assembler-x86-64.ru/) делает что-то вроде memset( $rdi, 0, 0x1000), обнуляя страницу 8-байтовыми словами.

ZeroPage_4K:
;IN
;   RDI - 4K page addr for NULL
	push rdi
	push rax
	push rcx

	xor rax, rax
	mov rcx, 1000h/8
	rep stosq

	pop rcx
	pop rax
	pop rdi
	ret

Зачем здесь использовать 64-разрядную

563:   48 31 c0                xor    %rax,%rax

вместо, например, более короткой 32-разрядной?

   0:   31 c0                   xor    %eax,%eax

В других примерах уже добавляется не 1 байт, а целая лишняя инструкция:

Листинг 4.6а

LM_CODE_START:
	mov rdi, PLM4_BASE_ADDRESS
	call ZeroPage_4K

	xor rax, rax    ;// ЗАЧЕМ?
	mov eax, LM_CODE_START
	and eax, 0FFFFF000h
	mov rbx, rax
	call AllocPage_4K

А код из листинга 4.4г (с.217) уже и выглядит сомнительно:

xor rdi, rdi
mov edi, [NextAvail4KPage]
shl rdi, 12 ; rdi = адрес следующей доступной страницы
add rdi, PLM4_BASE_ADDRESS
call 	ZeroPage_4K
mov 	rax, rdi
or 	eax, 3 ; rax = PD table addr or Present or Write
mov 	rdx, rax
mov 	[r8], eax
shr 	rax, 32
mov 	[r8+4], eax  ;//< ЧТО В EAX?
inc 	dword [NextAvail4KPage]
mov 	r10, rdx ; r10 = PDP entry
vM ()
Ответ на: комментарий от vM

Зачем здесь использовать 64-разрядную xor rax, rax вместо, например, более короткой 32-разрядной xor eax, eax?

Затем, что stosq записывает в пямять весь rax, а не только его младшую половину eax и инструкция stosq более эффективна, чем stosd.

	xor rax, rax    ;// ЗАЧЕМ?
	mov eax, LM_CODE_START
	and eax, 0FFFFF000h
	mov rbx, rax
	call AllocPage_4K

Затем, что в rax передаётся физический адрес

    AllocPage_4K:
    ;IN
    ; RAX физический адрес
    ; RBX виртуальный адрес
hummer ()
Ответ на: комментарий от hummer

А мужики обнуляли:

(gdb) x /i $pc
=> 0x7ffff7dd6090 <_start>:	xor    %eax,%eax
(gdb) p $rax=-010000
$5 = -4096
(gdb) i r rax
rax            0xfffffffffffff000	-4096
(gdb) ni
0x00007ffff7dd6092 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) i r rax
rax            0x0	0
(gdb) 

Попробуйте на своём процессоре обнулить, или в qemu, или в любимом симуляторе самого Руслан Зуфярыча.

Может быть, мой старенький Intel(R) Core(TM) испортился, или прошивка от старости погнулась:

vendor_id	: GenuineIntel
cpu family	: 6
model		: 58
model name	: Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz
stepping	: 9
microcode	: 0x15
cpu MHz		: 798.239
cache size	: 3072 KB
physical id	: 0
siblings	: 4
core id		: 0
cpu cores	: 2
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 13
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm cpuid_fault epb pti tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm arat pln pts
bugs		: cpu_meltdown spectre_v1 spectre_v2
bogomips	: 3392.49
clflush size	: 64
cache_alignment	: 64
address sizes	: 36 bits physical, 48 bits virtual
vM ()
Ответ на: комментарий от hummer

Как уже отметили в обсуждении по Вашей ссылке, это поведение документировано в руководствах AMD по AMD64 ISA Посоветуйте курс лекций по программированию в x86-64 long mode (комментарий)

В первых 64-разрядных микропроцессорах 1990-х никаких половинок и четвертинок и не было предусмотрено.

А дизайнеры архитектуры AMD64 исходили в том числе (но не только) из того, что большая часть кода будет портированным 32-разрядным чудо-кодом, написанным 32-разрядными чудо-программистами. И в этом чудо-коде хватает подобного чуда:

size_t s;
int c = get_count(); 
if (0<=c) s = c;

Когда чудо-программист пишет s = c, он, как правило, не имеет ввиду memcpy(&s, &c, sizeof c ), хотя, если (sizeof s) == (sizeof c), такая реализация не создаёт серьёзных проблем.

Желательно, чтобы ISA позволяла компилятору эффективно выразить мысли чудо-программиста прошлых лет.

vM ()
Ответ на: комментарий от hummer

Если Вы начнёте с MIPS, A64 или RISC-V, то Вам не придётся всё время себе напоминать, что x64 – это не 8086 с удвоенным количеством регистров учетверённой ширины, а совсем другая гибридная 64-32-разрядная архитектура, хоть и с широкими возможностями эмуляции x86-legacy. И изучать её целесообразно, начиная с 64-bit Long mode, затем перейти к Compatibilty Long mode, по желанию и возможности SMM. И только потом, по мере необходимости, переходить к legacy режимам. Например, стартовому INIT Real mode, когда будете сбрасывать в него дополнительные ядра. Но на этом этапе Вы уже столкнётесь с особенностями конкретной реализации x64 (разными версиями AMD64, EMT64T, xxxx64 etc.) Тем более это касается виртуализации, которую надо иметь ввиду с самого начала работы на демкой или супервизором.

Конечно, желание программировать свою машину – естественное желание программиста. Можно начать с маршрутизатора, попробовать переключить его на свою демку самодельным модулем ядра, не меняя прошивку. Можно и с настольного моноблока или ноутбука. Но тогда, я думаю, труды Руслан Зуфярыча не для Вас.

Программирование с мелом НА АССЕМБЛЕРЕ у доски полезно, чтобы помочь студентам уяснить идею, но оно скрывает от программиста важные на практике детали конкретной процессорной технологии.

vM ()
Ответ на: комментарий от hummer

Маршрутизатор и гаджеты на армах у Вас, возможно, тоже есть. Их можно программировать так же, как и десктоп.

Если у настольного есть встроенная графика, можно попробовать настроить один выход на эмуляцию MDA, другой – на эмуляцию основного цветного адаптера. Обычно firmware этого не делает. И запустить на одном из AP самодельный клон CP/M-86, общающийся с 64-разрядными мониторами на других ядрах ;)

vM ()
Ответ на: комментарий от hummer

Даже уважаемый автор уныло обсуждаемой книжки про на ассемблере к концу 2010-х, как уже было отмечено на предыдущей странице, перешёл на фантастоту 18+.

И я уныло покидаю унылый тред, не буду мешать тосковать в одиночестве.

anonymous ()