OSDev

для всех
Текущее время: 29 мар 2024, 10:55

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 4 ] 
Автор Сообщение
 Заголовок сообщения: Самый простой способ запустить SMP
СообщениеДобавлено: 17 апр 2017, 16:05 

Зарегистрирован: 15 сен 2015, 14:42
Сообщения: 5
Всем привет!

Пытался завести smp, исходники брал https://github.com/pdoane/osdev - не завелось) Но это другой разговор. И на какое время забросил все, пока не наткнулся на http://stackoverflow.com/questions/9809 ... -look-like

Там в камменте есть код запуска AP колхозным способом - без парсинга таблиц, напрямую писать в регистр(предполагая, что по этому адресу таки отражен регистр). Так делать нельзя

ICR_LOW = 0xFEE00300

Код:
MOV ESI, ICR_LOW       ; Load address of ICR low dword into ESI.
MOV EAX, 000C4500H     ; Load ICR encoding for broadcast INIT IPI
                       ; to all APs into EAX.
MOV [ESI], EAX         ; Broadcast INIT IPI to all APs
                       ; 10-millisecond delay loop.
MOV EAX, 000C46XXH     ; Load ICR encoding for broadcast SIPI IP
                       ; to all APs into EAX, where xx is the vector computed in step 10.
MOV [ESI], EAX         ; Broadcast SIPI IPI to all APs
                       ; 200-microsecond delay loop
MOV [ESI], EAX         ; Broadcast second SIPI IPI to all APs
                       ; Waits for the timer interrupt until the timer expires


У меня получился такой код


Вот что он должен делать:
-копировать trampoline код для AP по известному адресу, у нас это 0x1000 - вектор 0x01 (это то, что мы отправляем SIPI IP)
-выполнять INIT-SIPI-SIPI
-AP должен выполнить trampoline код, который инкрементирует переменную по известному адресу - 0x2000

Код:
.equ STARTUP_CODE_ADDRESS, 0x1000
.equ SPINLOCK_ADDRESS, 0x2000

/* PIC */
.equ PIC_ICR_ADDRESS, 0xFEE00300
.equ IA32_APIC_BASE, 0x1B

/* Must come before they are used. */
.equ CODE_SEG, 8
.equ DATA_SEG, gdt_data - gdt_start /* 10 */


.code16
.global _start
_start:
    cli
    xor %ax, %ax
    mov %ax, %ds

    lgdt gdt_descriptor

    mov %cr0, %eax
    orl $0x1, %eax
    mov %eax, %cr0

    ljmp $CODE_SEG, $protected_mode

.code32
protected_mode:
    mov $DATA_SEG, %ax
    mov %ax, %ds
    mov %ax, %es
    mov %ax, %fs
    mov %ax, %gs
    mov %ax, %ss

   /*
    Копируем trampoline код, теперь он доступен по адресу 0x1000
    */
    cld
    movl $init_len, %ecx
    movl $init, %esi
    movl $STARTUP_CODE_ADDRESS, %edi
    rep movsb

    /* Обнуляем SPINLOCK_ADDRESS - общая для всех процессоров переменная*/
    movb $0x00, SPINLOCK_ADDRESS
   
    /* Включаем APIC */
    movl $IA32_APIC_BASE, %ecx
    rdmsr
    bts $11, %eax
    wrmsr
   
    /* Load address of ICR low dword into ESI. */
    movl $PIC_ICR_ADDRESS, %esi
    /* Load ICR encoding for broadcast INIT IPI to all APs. */
    movl $0x000C4500, %eax
    /* Broadcast INIT IPI to all APs */
    movl %eax, (%esi)
   
   
    /* 10-millisecond delay loop. */
    movl $0x000fffff,%ecx
    delay10:
       dec   %ecx
       jnz   delay10
   
    /*
    Load ICR encoding for broadcast SIPI IP to all APs.
    The low byte of this is the vector which encodes the staring address for the processors!
    This address is multiplied by 0x1000: processors start at CS = vector * 0x100 and IP = 0.
       mov $0x000C4600 + STARTUP_CODE_ADDRESS / 0x1000, %eax
    */
    movl $0x000C4601, %eax

    /* Broadcast SIPI IPI to all APs. */
    movl %eax, (%esi)
   
    /* 200-microsecond delay loop. */

    /* Broadcast second SIPI IPI to all APs */
    movl %eax, (%esi)
   
/* Здесь ждем запуска 3-х процессоров */
not_started:
    cmpb $3, SPINLOCK_ADDRESS
    jne not_started

ok:
    movl $0x254B254F, 0xb8000 //print 'OK'
    hlt


/* Trampoline код */
.code16
init:
    cli
    cld
    xor %ax, %ax
    mov %ax, %ds
    mov %ax, %es
    mov %ax, %ss
   
    incb SPINLOCK_ADDRESS
           
    wbinvd
   
    hlt
.equ init_len, . - init

/* GDT */   
gdt_start:
gdt_null:
    .long 0x0
    .long 0x0
gdt_code:
    .word 0xffff
    .word 0x0
    .byte 0x0
    .byte 0b10011010
    .byte 0b11001111
    .byte 0x0
gdt_data:
    .word 0xffff
    .word 0x0
    .byte 0x0
    .byte 0b10010010
    .byte 0b11001111
    .byte 0x0
gdt_end:
gdt_descriptor:
    .word gdt_end - gdt_start
    .long gdt_start
   
.org 510
.word 0xaa55


Makefile
Код:
MAIN := main.img

$(MAIN): main.S
   $(AS) -o main.o '$<'
   $(LD) --oformat binary -o '$@' -Ttext 0x7C00 main.o
   
clean:
   rm -f '$(MAIN)'

run: $(MAIN)
   qemu -smp 4 -fda '$(MAIN)'
   


Последний раз редактировалось gdt 24 апр 2017, 19:37, всего редактировалось 4 раз(а).

Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 24 апр 2017, 14:36 

Зарегистрирован: 15 сен 2015, 14:42
Сообщения: 5
Теперь заработало. Я просто невероятно счастлив!)
Запутался в скобочках, $ и поинтерах в асме. Лог боша - бесценен.
А еще APIC нужно включать перед работой)

На свой вопрос про паузы INIT-SIPI-SIPI (10мс и 200мс) ответ получил: qemu и vmware - без делея работают, бош - нужно выдержать только первую задержку 10мс. Поэтому в коде есть loop между INIT и SIPI

Так же во всех эмуляторах и гипервизоре можно выполнить упрощенно INIT-SIPI. Хотя должно быть INIT - SIPI с нулевым вектором - SIPI с вектором.
qemu отрабатывает правильно, а бош и vmware почему-то выполняют SIPI с нулевым вектором, хотя должны отбросить этот вектор и ждать следующий SIPI.

Код:
00029807591i[APIC1 ] Deliver Start Up IPI
00029807591i[CPU1  ] CPU 1 started up at 0000:00000000 by APIC



Код в обновил. Хотелось бы вычистить код от мусора и сделать законченный учебный пример.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 25 апр 2017, 06:55 
Аватара пользователя

Зарегистрирован: 16 май 2007, 23:46
Сообщения: 1126
Это было бы замечательно.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 11 июн 2017, 21:49 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
Только лучше в intel-синтаксисе (ключ -masm=intel), а то выглядит архаично.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 4 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB