OSDev

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

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




Начать новую тему Ответить на тему  [ Сообщений: 160 ]  На страницу Пред.  1, 2, 3, 4, 5 ... 16  След.
Автор Сообщение
СообщениеДобавлено: 12 авг 2013, 17:31 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
maisvendoo писал(а):
По содержимому ESP видно что крах происходит при выполнении потока ядра, сразу после переключения на него
Всегда только в главном потоке? Проверь, растет ли глубина стеков других потоков с течением времени.

Цитата:
В нулевом кольце проталкивать нужно ... а в user mode ...
Я тебе уже давно рассказал, что нужно сделать, чтобы способ переключения не зависел от CPL задачи в момент прерывания.

Какой смысл делать sti перед iret? Зачем заталкивать/выталкивать сегментные регистры через дополнительный регистр? Зачем портить es, fs, gs? Зачем в сегментные регистры данных помещать селектор сегмента кода (или это ошибка в комментарии)? Каково назначение "add esp,8", тоже не понял.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 12 авг 2013, 17:59 
Аватара пользователя

Зарегистрирован: 25 июл 2013, 08:45
Сообщения: 141
Откуда: Новочеркасск
Этот код тоже слизан вчистую с примера. Что-то я разобрал, что-то так и не понял. Буду переделывать это заново
phantom-84 писал(а):
селектор сегмента кода

да, ошибка в коментах


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 12 авг 2013, 18:45 
Аватара пользователя

Зарегистрирован: 16 май 2007, 23:46
Сообщения: 1126
Цитата:
Код:
      add    $8, %esp       /* Убираем из стека код ошибки */
                            /* и помещаем туда номер ISR */

      sti                   /* Вновь разрешаем прерывания */
      IRET

У IRQ нету кода ошибки. Код ошибки только у ловушек. Если хочешь чтобы было с кодом так его надо вначале туда поместит, но вообще я бы убрал лишний код.
Вот мне интересно автор знает зачем ему тут STI понадобился? Думаю что нет. Да и вообще тут другое должно быть.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 12 авг 2013, 18:54 
Аватара пользователя

Зарегистрирован: 25 июл 2013, 08:45
Сообщения: 141
Откуда: Новочеркасск
pavia писал(а):
У IRQ нету кода ошибки. Код ошибки только у ловушек. Если хочешь чтобы было с кодом так его надо вначале туда поместит, но вообще я бы убрал лишний код.
Вот мне интересно автор знает зачем ему тут STI понадобился? Думаю что нет. Да и вообще тут другое должно быть.

Это всё ещё остатки г...о кода из примера по разработке ОС. Пока не перепишу всё ядро, чувствую косяки не исчезнут

Да вот и pusha это не просто так, а передача параметров Сишному обработчику. Я пока три недели ковырялся много вот таких несуразиц отловил у себя


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 12 авг 2013, 19:06 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
pusha/popa как раз-таки нужны (не только для Си). Я тебе показывал максимально упрощенную и эффективную переключалку. Что мешает опираться на нее?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 13 авг 2013, 15:03 
Аватара пользователя

Зарегистрирован: 25 июл 2013, 08:45
Сообщения: 141
Откуда: Новочеркасск
phantom-84 писал(а):
Я тебе показывал максимально упрощенную и эффективную переключалку. Что мешает опираться на нее?

Просто, если можно, хотел бы прояснить кое-что. Туго я соображаю что-то.

Поковырялся сейчас в отладке. Стек ползет на всех потоках, и это из-за того что я прыгаю на следующий поток прямо из обработчика, и при повторном входе в прерывание просходит снова проталкивание ряда значений в стек, а выталкивание их обходится этим моим джампом. И поскольку стеки находятся на расстоянии 0х405С друг от друга рано или поздно они затирают друг друга и описатели потоков.

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 13 авг 2013, 15:18 
Аватара пользователя

Зарегистрирован: 16 май 2007, 23:46
Сообщения: 1126
Я лично через iret переключаю jmp не использую.
Правда не понятно почему около 55 прерываний работает нормально, а после стек рушится.

Код:
var
 TickCount:QWord;

procedure Timer_int;
asm
PUSH DS
PUSH 10h
POP  DS
PUSHA
XCHG    BX, BX
MOV     AL,20h          // посылаем сигнал конца
OUT     MASTER8259A,AL  // прерывания
MOV     EAX,1
ADD     DWord PTR DS:[TickCount],EAX
XOR     EAX, EAX
ADC     DWord PTR DS:[TickCount+4],EAX     
CALL    TaskSwitch
POPA
PUSH    EAX
MOV     AL, Byte PTR DS:[debugmode]
CMP     AL, dmCMD
JE      @End
MOV     EAX, DS:[TaskCorrectState]
CALL    TaskStateSave
MOV     EAX, DS:[TaskNewState]
CALL    TaskStateLoad
@End:
POP     EAX
POP     DS
IRETD
end;

procedure TaskStateSave;
assembler;
asm
MOV  DS:[TCPUState(EAX).BaseReg._EBX], EBX
MOV  DS:[TCPUState(EAX).BaseReg._ECX], ECX
MOV  DS:[TCPUState(EAX).BaseReg._EDX], EDX
MOV  DS:[TCPUState(EAX).BaseReg._ESI], ESI
MOV  DS:[TCPUState(EAX).BaseReg._EDI], EDI

MOV  EBX, DWord PTR SS:[ESP+4]
MOV  DS:[TCPUState(EAX).BaseReg._EAX], EBX

MOV  EBX, DWord PTR SS:[ESP+12]
MOV  DWord PTR DS:[TCPUState(EAX).BaseReg._EIP], EBX
MOV  EBX, DWord PTR SS:[ESP+12+4]
MOV  Word PTR DS:[TCPUState(EAX).BaseReg._CS], BX

MOV  EBX, DWord PTR SS:[ESP+12+8]
MOV  DWord PTR DS:[TCPUState(EAX).BaseReg._EFlags],EBX

PUSH CS
POP  EBX

AND  CX, 3
AND  BX, 3
CMP  BX,CX
JE   @els

MOV  EBX, DWord PTR SS:[ESP+12+12]
MOV  DWord PTR DS:[TCPUState(EAX).BaseReg._ESP],EBX

MOV  EBX, DWord PTR SS:[ESP+12+16]
MOV  Word PTR DS:[TCPUState(EAX).BaseReg._SS],BX

JMP  @end_els
@els:
MOV  EBX, ESP
ADD  EBX,12+16
MOV  DWord PTR DS:[TCPUState(EAX).BaseReg._ESP],EBX

PUSH SS
POP  EBX
MOV  Word PTR DS:[TCPUState(EAX).BaseReg._SS],BX

@end_els:

PUSH EBP
POP  EBX;
MOV  DWord PTR DS:[TCPUState(EAX).BaseReg._EBP],EBX

PUSH ES
POP  EBX
MOV  Word PTR DS:[TCPUState(EAX).BaseReg._ES],BX

PUSH FS
POP  EBX
MOV  Word PTR DS:[TCPUState(EAX).BaseReg._FS],BX

PUSH GS
POP  EBX
MOV  Word PTR DS:[TCPUState(EAX).BaseReg._GS],BX

MOV  BX, Word PTR SS:[ESP+8]
MOV  Word PTR DS:[TCPUState(EAX).BaseReg._DS],BX

end;

procedure TaskStateLoad;
assembler;
asm
MOV  BX, Word PTR DS:[TCPUState(EAX).BaseReg._DS]
MOV  Word PTR SS:[ESP+8], BX

MOV  BX, Word PTR DS:[TCPUState(EAX).BaseReg._GS]
PUSH EBX
POP  GS

MOV  BX, Word PTR DS:[TCPUState(EAX).BaseReg._FS]
PUSH EBX
POP  FS

MOV  BX, Word PTR DS:[TCPUState(EAX).BaseReg._ES]
PUSH EBX
POP  ES

MOV  BX, Word PTR DS:[TCPUState(EAX).BaseReg._CS]
MOV  Word PTR SS:[ESP+12+4], BX

MOV  EBX, DWord PTR DS:[TCPUState(EAX).BaseReg._EBP]
PUSH EBX
POP  EBP

MOV  CX, Word PTR DS:[TCPUState(EAX).BaseReg._CS]
PUSH CS
POP  EBX
AND  CX, 3
AND  BX, 3
CMP  BX,CX
JE   @els
MOV  EBX, DWord PTR DS:[TCPUState(EAX).BaseReg._ESP]
MOV  DWord PTR SS:[ESP+12+12], EBX

MOV  BX, Word PTR DS:[TCPUState(EAX).BaseReg._SS]
MOV  DWord PTR SS:[ESP+12+16], EBX

JMP  @end_els
@els:
NOP
@end_els:

MOV  EBX, DWord PTR DS:[TCPUState(EAX).BaseReg._EIP]
MOV  DWord PTR SS:[ESP+12], EBX

MOV  EBX, DWord PTR DS:[TCPUState(EAX).BaseReg._EFlags]
MOV  DWord PTR SS:[ESP+12+8], EBX

MOV  EBX, DS:[TCPUState(EAX).BaseReg._EAX]
MOV  DWord PTR SS:[ESP+4], EBX

MOV  EDI, DS:[TCPUState(EAX).BaseReg._EDI]
MOV  ESI, DS:[TCPUState(EAX).BaseReg._ESI]
MOV  EDX, DS:[TCPUState(EAX).BaseReg._EDX]
MOV  ECX, DS:[TCPUState(EAX).BaseReg._ECX]
MOV  EBX, DS:[TCPUState(EAX).BaseReg._EBX]
end;



Код:
procedure Task1;
begin
repeat

PosX:=0;PosY:=1;
StrWriteLn('Task1');
until false;
end;

procedure Task2;
begin
repeat
PosX:=0;PosY:=1;
StrWriteLn('Task2');
until false;
end;


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 13 авг 2013, 18:33 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
maisvendoo писал(а):
Поковырялся сейчас в отладке. Стек ползет на всех потоках, и это из-за того что я прыгаю на следующий поток прямо из обработчика, и при повторном входе в прерывание просходит снова проталкивание ряда значений в стек, а выталкивание их обходится этим моим джампом.
Ну так не обходи выталкивание.

Цитата:
Основная идея твоего алгоритма в том что при выходе из обработчика IRQ0 в EIP выталкивается адрес инструкции в следующем потоке из очереди, как я понимаю. Хотелось бы просто по пунктам этот алгоритм разобрать: вот произошло прерывание таймера и что необходимо сделать чтобы перескочить на новую задачу
Наверно можно сделать и при выходе, но я сделал "посередине", чтобы иметь возможность обращаться к переключалке на любом уровне вложенности подпрограмм, причем не только внутри обработчика, но и за его пределами, что нужно в реальной системе. Я давал ссылку на место, где опубликован код. Он очень короткий, к тому же часть его закомментирована (а кое-что я вообще не стал писать, например, загрузку в cr3, потому что это добавить элементарно).

Код переключалки:
Код:
  proc SwitchToNext ; cs=KCODE, ds=es=ss=KDATA
  push fs
  push gs
  pushf
  cli
; раскомментируйте, если не хотите получать [current] на входе в подпрограмму
;  mov eax,[current]
  mov [eax+TS.stackpointer],esp
  mov eax,[eax+TS.next]
  mov esp,[eax+TS.stackpointer]
  mov [current],eax
  popf
  pop gs
  pop fs
  ret
Как видно, имеем простой кадр возобновления:
Код:
TS-04:  стартовый адрес возобновления
TS-08:  FS
TS-12:  GS
TS-16:  EFLAGS
TS читай пока, как "вершина стека". Если вы используете [current] в качестве входного параметра и передаете его в стеке (а не в eax, как предполагает мой код), добавьте его в конец кадра (под TS). Если в прологе сишной функции что-то сохраняется в стеке, это тоже нужно добавить в кадр. Перед первым запуском потока этот кадр нужно сформировать в его стеке "вручную" (stackpointer должен указывать на его начало, т.е. быть равным TS-16), потом он будет формироваться автоматически (при обращении к переключалке).

Примерный код обработчика:
Код:
  proc IRQ0Handler
  pusha
  push ds
  push es

  push ss
  pop ds ; ds <- KDATA
  push ss
  pop es ; es <- KDATA

  mov al,20h
  out 20h,al

  mov eax,[current]
  call SwitchToNext

  pop es
  pop ds
  popa
  iret
Обратите внимание, что pusha/popa нужно не для переключения, а для самого обработчика (реальный обработчик может быть значительно сложнее; эти команды просто сохраняют регистровый контекст прерванного кода). Также обратите внимание, что выполнение EOI должно происходить перед обращением к переключалке (после переключения на новую задачу мы можем оказаться не в обработчике, т.е. мы могли бы потерять EOI на длительное время, если бы разместили код для EOI после обращения к переключалке).

Чтобы это все работало на прикладном уровне, нужно разместить структуру потока (TS) в вершине стека, а current совместить с TSS.esp0.


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

Зарегистрирован: 16 май 2007, 23:46
Сообщения: 1126
phantom-84, а почему в состояние задачи не сохраняешь регистры общего назначения?
По моему коду можешь что нибудь сказать?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 13 авг 2013, 19:11 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
pavia писал(а):
а почему в состояние задачи не сохраняешь регистры общего назначения?
Посмотри внимательно, в этом нет абсолютно никакой необходимости.

Цитата:
По моему коду можешь что нибудь сказать?
Пока нет.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 160 ]  На страницу Пред.  1, 2, 3, 4, 5 ... 16  След.

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


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

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


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

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