OSDev http://osdev.su/ |
|
Проблема с иниализацией системы http://osdev.su/viewtopic.php?f=6&t=286 |
Страница 1 из 1 |
Автор: | Гость [ 20 июл 2009, 20:59 ] |
Заголовок сообщения: | Проблема с иниализацией системы |
Мной пишется вторичный загрузчик (BootStrap). Предполагается, что в его задачи будет входить подкачка в память загрузчика ядра и переход в защищенный режим. А вот сама суть проблеммы: при любой попытке загрузить редистр дескрипторной таблицы прерываний с помощью инструкции lidt я получаю stack fault in kernel mode и иду нервно курить. Есди кто имеет возность, то объясните пожалуйста природу этого явления и, соответственно, как его лечить. вот тот рабочий код, который я сейчас пинаю: Код: .386P
.model tiny F_TASK_RAM_ADDRESS = 04500h ; first task address in memory KERNEL_RAM_ADDRESS = 02500h ; loader address in memory LOADER_RAM_ADDRESS = 08000h ; loader address in memory CODE segment byte public 'CODE' use16 assume CS:CODE assume DS:CODE assume ES:CODE assume FS:CODE assume GS:CODE assume SS:CODE org 7C00h START: cli cld ; Init segment registers xor AX, AX mov DS, AX mov ES, AX mov FS, AX mov GS, AX mov SS, AX ; Preparing for disk operations mov SI, 07E00h mov DX, 00010h mov [SI ], DX mov [SI + 3h], AL mov [SI + 4h], AX mov AH, 42h mov DL, 80h ; Read loader from disk to memory mov BL , LOADER_SIZE mov [SI + 02h], BL mov BX , LOADER_RAM_ADDRESS mov [SI + 06h], BX mov EBX , LOADER_HDD_ADDR_1 mov [SI + 08h], EBX mov EBX , LOADER_HDD_ADDR_2 mov [SI + 0Ch], EBX int 13h jc ERROR ; Read Kernel from disk to memory mov BL , KERNEL_SIZE mov [SI + 02h], BL mov BX , KERNEL_RAM_ADDRESS mov [SI + 06h], BX mov EBX , KERNEL_HDD_ADDR_1 mov [SI + 08h], EBX mov EBX , KERNEL_HDD_ADDR_2 mov [SI + 0Ch], EBX int 13h jc ERROR ; Read First task from disk to memory mov BL , F_TASK_SIZE mov [SI + 02h], BL mov BX , F_TASK_RAM_ADDRESS mov [SI + 06h], BX mov EBX , F_TASK_HDD_ADDR_1 mov [SI + 08h], EBX mov EBX , F_TASK_HDD_ADDR_2 mov [SI + 0Ch], EBX int 13h jc ERROR ; IDT xor EAX, EAX mov ECX, 0200h mov EDI, 0500h rep stosw lidt 0000h:7DA3h ; GDT mov BP, 0900h mov dword ptr [BP ], 000000000h mov dword ptr [BP + 04h], 000000000h mov dword ptr [BP + 08h], 00000FFFFh; mov dword ptr [BP + 0Ch], 000CF9200h; mov dword ptr [BP + 0Fh], 00000FFFFh; mov dword ptr [BP + 14h], 000CF9A00h; mov CX, 001F4h mov DI, 00918h rep stosw lgdt GDT_TABLE mov BX, 00010h mov DS, BX mov SS, BX mov ES, BX mov FS, BX mov GS, BX mov EAX, CR0 or EAX, 01h mov CR0, EAX jmp FLUSH_PREFETCH_QUEUE FLUSH_PREFETCH_QUEUE: jmp dword ptr DS:8000h ERROR: lea SI, ERROR_STRING PRINT: lodsb test AL, AL HANG: jz HANG mov AH, 0Eh mov BX, 01h int 10h jmp PRINT PLACEHOLDER db 092h DUP(0) IDT_T: IDT_TABLE df 0000000000000h GDT_TABLE df 0000009000400h ERROR_STRING db "Disk read ERROR ocurred on loading kernel loader!!!", 0 F_TASK_SIZE db 0000h F_TASK_HDD_ADDR_1 dd 0000h F_TASK_HDD_ADDR_2 dd 0000h KERNEL_SIZE db 0000h KERNEL_HDD_ADDR_1 dd 0000h KERNEL_HDD_ADDR_2 dd 0000h LOADER_SIZE db 0000h LOADER_HDD_ADDR_1 dd 0000h LOADER_HDD_ADDR_2 dd 0000h MAGIC_WORD dw 0AA55h CODE ENDS END START |
Автор: | Гость [ 21 июл 2009, 03:41 ] |
Заголовок сообщения: | Re: Проблема с иниализацией системы |
тоже мне проблема... побольше конопли курить нада и поменьше пейсать гуано кода. |
Автор: | SII [ 21 июл 2009, 11:17 ] |
Заголовок сообщения: | Re: Проблема с иниализацией системы |
Пример перехода в защищёнку вроде есть в интеловском мануале. Насколько помню, после собственно перехода в него надо инициализировать TSS и загрузить соответствующим образом TR, и только потом заниматься всем прочим. Но смотреть в документацию лень :) Пы.Сы. А нафиг _начальному_ загрузчику переходить в защищённый режим? |
Автор: | Гость [ 21 июл 2009, 17:13 ] |
Заголовок сообщения: | Re^2: Проблема с иниализацией системы |
Вот пример из INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986: Код: $TITLE ('Initial Task') NAME INIT init_stack SEGMENT RW DW 20 DUP(?) tos LABEL WORD init_stack ENDS init_data SEGMENT RW PUBLIC DW 20 DUP(?) init_data ENDS init_code SEGMENT ER PUBLIC ASSUME DS:init_data nop nop nop init_start: ; set up stack mov ax, init_stack mov ss, ax mov esp, offset tos mov a1,1 blink: xor a1,1 out 0e4h,a1 mov cx,3FFFh here: dec cx jnz here jmp SHORT blink hlt init_code ends END init_start, SS:init_stack, DS:init_data $TITLE('Protected Mode Transition -- 386 initialization') NAME RESET ;***************************************************************** ; Upon reset the 386 starts executing at address 0FFFFFFF0H. The ; upper 12 address bits remain high until a FAR call or jump is ; executed. ; ; Assume the following: ; ; ; - a short jump at address 0FFFFFFF0H (placed there by the ; system builder) causes execution to begin at START in segment ; RESET_CODE. ; ; ; - segment RESET_CODE is based at physical address 0FFFF0000H, ; i.e. at the start of the last 64K in the 4G address space. ; Note that this is the base of the CS register at reset. If ; you locate ROMcode above this address, you will need to ; figure out an adjustment factor to address things within this ; segment. ; ;***************************************************************** $EJECT ; ; Define addresses to locate GDT and IDT in RAM. ; These addresses are also used in the BLD386 file that defines ; the GDT and IDT. If you change these addresses, make sure you ; change the base addresses specified in the build file. GDTbase EQU 00001000H ; physical address for GDT base IDTbase EQU 00000400H ; physical address for IDT base PUBLIC GDT_EPROM PUBLIC IDT_EPROM PUBLIC START DUMMY segment rw ; ONLY for ASM386 main module stack init DW 0 DUMMY ends ;***************************************************************** ; ; Note: RESET CODE must be USEl6 because the 386 initally executes ; in real mode. ; RESET_CODE segment er PUBLIC USE16 ASSUME DS:nothing, ES:nothing ; ; 386 Descriptor template DESC STRUC lim_0_15 DW 0 ; limit bits (0..15) bas_0_15 DW 0 ; base bits (0..15) bas_16_23 DB 0 ; base bits (16..23) access DB 0 ; access byte gran DB 0 ; granularity byte bas_24_31 DB 0 ; base bits (24..31) DESC ENDS ; The following is the layout of the real GDT created by BLD386. ; It is located in EPROM and will be copied to RAM. ; ; GDT[O] ... NULL ; GDT[1] ... Alias for RAM GDT ; GDT[2] ... Alias for RAM IDT ; GDT[2] ... initial task TSS ; GDT[3] ... initial task TSS alias ; GDT[4] ... initial task LDT ; GDT[5] ... initial task LDT alias ; ; define entries in GDT and IDT. GDT_ENTRIES EQU 8 IDT_ENTRIES EQU 32 ; define some constants to index into the real GDT GDT_ALIAS EQU 1*SIZE DESC IDT_ALIAS EQU 2*SIZE DESC INIT_TSS EQU 3*SIZE DESC INIT_TSS_A EQU 4*SIZE DESC INIT_LDT EQU 5*SIZE DESC INIT_LDT_A EQU 6*SIZE DESC ; ; location of alias in INIT_LDT INIT_LDT_ALIAS EQU 1*SIZE DESC ; ; access rights byte for DATA and TSS descriptors DS_ACCESS EQU 010010010B TSS_ACCESS EQU 010001001B ; ; This temporary GDT will be used to set up the real GDT in RAM. Temp_GDT LABEL BYTE ; tag for begin of scratch GDT NULL_DES DESC <> ; NULL descriptor ; 32-Gigabyte data segment based at 0 FLAT_DES DESC <0FFFFH,0,0,92h,0CFh,0> GDT_eprom DP ? ; Builder places GDT address and limit ; in this 6 byte area. IDT_eprom DP ? ; Builder places IDT address and limit ; in this 6 byte area. ; ; Prepare operand for loadings GDTR and LDTR. TGDT_pword LABEL PWORD ; for temp GDT DW end_Temp_GDT_Temp_GDT -1 DD 0 GDT_pword LABEL PWORD ; for GDT in RAM DW GDT_ENTRIES * SIZE DESC -1 DD GDTbase IDT_pword LABEL PWORD ; for IDT in RAM DW IDT_ENTRIES * SIZE DESC -1 DD IDTbase end_Temp_GDT LABEL BYTE ; ; Define equates for addressing convenience. GDT_DES_FLAT EQU DS:GDT_ALIAS +GDTbase IDT_DES_FLAT EQU DS:IDT_ALIAS +GDTbase INIT_TSS_A_OFFSET EQU DS:INIT_TSS_A INIT_TSS_OFFSET EQU DS:INIT_TSS INIT_LDT_A_OFFSET EQU DS:INIT_LDT_A INIT_LDT_OFFSET EQU DS:INIT_LDT ; define pointer for first task switch ENTRY POINTER LABEL DWORD DW 0, INIT_TSS ;****************************************************************** ; ; Jump from reset vector to here. START: CLI ;disable interrupts CLD ;clear direction flag LIDT NULL_des ;force shutdown on errors ; ; move scratch GDT to RAM at physical 0 XOR DI,DI MOV ES,DI ;point ES:DI to physical location 0 MOV SI,OFFSET Temp_GDT MOV CX,end_Temp_GDT-Temp_GDT ;set byte count INC CX ; ; move table REP MOVS BYTE PTR ES:[DI],BYTE PTR CS:[SI] LGDT tGDT_pword ;load GDTR for Temp. GDT ;(located at 0) ; switch to protected mode MOV EAX,CR0 ;get current CRO MOV EAX,1 ;set PE bit MOV CRO,EAX ;begin protected mode ; ; clear prefetch queue JMP SHORT flush flush: ; set DS,ES,SS to address flat linear space (0 ... 4GB) MOV BX,FLAT_DES-Temp_GDT MOV US,BX MOV ES,BX MOV SS,BX ; ; initialize stack pointer to some (arbitrary) RAM location MOV ESP, OFFSET end_Temp_GDT ; ; copy eprom GDT to RAM MOV ESI,DWORD PTR GDT_eprom +2 ; get base of eprom GDT ; (put here by builder). MOV EDI,GDTbase ; point ES:EDI to GDT base in RAM. MOV CX,WORD PTR gdt_eprom +0 ; limit of eprom GDT INC CX SHR CX,1 ; easier to move words CLD REP MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI] ; ; copy eprom IDT to RAM ; MOV ESI,DWORD PTR IDT_eprom +2 ; get base of eprom IDT ; (put here by builder) MOV EDI,IDTbase ; point ES:EDI to IDT base in RAM. MOV CX,WORD PTR idt_eprom +0 ; limit of eprom IDT INC CX SHR CX,1 CLD REP MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI] ; switch to RAM GDT and IDT ; LIDT IDT_pword LGDT GDT_pword ; MOV BX,GDT_ALIAS ; point DS to GDT alias MOV DS,BX ; ; copy eprom TSS to RAM ; MOV BX,INIT_TSS_A ; INIT TSS A descriptor base ; has RAM location of INIT TSS. MOV ES,BX ; ES points to TSS in RAM MOV BX,INIT_TSS ; get inital task selector LAR DX,BX ; save access byte MOV [BX].access,DS_ACCESS ; set access as data segment MOV FS,BX ; FS points to eprom TSS XOR si,si ; FS:si points to eprom TSS XOR di,di ; ES:di points to RAM TSS MOV CX,[BX].lim_0_15 ; get count to move INC CX ; ; move INIT_TSS to RAM. REP MOVS BYTE PTR ES:[di],BYTE PTR FS:[si] MOV [BX].access,DH ; restore access byte ; ; change base of INIT TSS descriptor to point to RAM. MOV AX,INIT_TSS_A_OFFSET.bas_0_15 MOV INIT_TSS_OFFSET.bas_0_15,AX MOV AL,INIT_TSS_A_OFFSET.bas_16_23 MOV INIT_TSS_OFFSET.bas_16_23,AL MOV AL,INIT_TSS_A_OFFSET.bas_24_31 MOV INIT_TSS_OFFSET.bas_24_31,AL ; ; change INIT TSS A to form a save area for TSS on first task ; switch. Use RAM at location 0. MOV BX,INIT_TSS_A MOV WORD PTR [BX].bas_0_15,0 MOV [BX].bas_16_23,0 MOV [BX].bas_24_31,0 MOV [BX].access,TSS_ACCESS MOV [BX].gran,O LTR BX ; defines save area for TSS ; ; copy eprom LDT to RAM MOV BX,INIT_LDT_A ; INIT_LDT_A descriptor has ; base address in RAM for INIT_L MOV ES,BX ; ES points LDT location in RAM. MOV AH,[BX].bas_24_31 MOV AL,[BX].bas_16_23 SHL EAX,16 MOV AX,[BX].bas_0_15 ; save INIT_LDT base (ram) in EA MOV BX,INIT_LDT ; get inital LDT selector LAR DX,BX ; save access rights MOV [BX].access,DS_ACCESS ; set access as data segment MOV FS,BX ; FS points to eprom LDT XOR si,si ; FS:SI points to eprom LDT XOR di,di ; ES:DI points to RAM LDT MOV CX,[BX].lim_0_15 ; get count to move INC CX ; ; move initial LDT to RAM REP MOVS BYTE PTR ES:[di],BYTE PTR FS:[si] MOV [BX].access,DH ; restore access rights in ; INIT_LDT descriptor ; ; change base of alias (of INIT_LDT) to point to location in RAM. MOV ES:[INIT_LDT_ALIAS].bas_0_15,AX SHR EAX,16 MOV ES:[INIT_LDT_ALIAS].bas_16_23,AL MOV ES:[INIT_LDT_ALIAS].bas_24_31,AH ; ; now set the base value in INIT_LDT descriptor MOV AX,INIT_LDT_A_OFFSET.bas_0_15 MOV INIT_LDT_OFFSET.bas_0_15,AX MOV AL,INIT_LDT_A_OFFSET.bas_16_23 MOV INIT_LDT_OFFSET.bas_16_23,AL MOV AL,INIT_LDT_A_OFFSET.bas_24_31 MOV INIT_LDT_OFFSET.bas_24_31,AL ; ; Now GDT, IDT, initial TSS and initial LDT are all set up. ; ; Start the first task! ' JMP ENTRY_POINTER RESET_CODE ends END START, SS:DUMMY,DS:DUMMY Как видно из фрагмента Код: START: CLI ;disable interrupts CLD ;clear direction flag LIDT NULL_des ;force shutdown on errors они инициализируют IDTR в самом начале и если делать как они, то тогда все работает. Но меня интересует ПОЧЕМУ это уже не работает в том месте в котором это делаю я? Цитата: Пы.Сы. А нафиг _начальному_ загрузчику переходить в защищённый режим? А почему бы и нет? Свободное место в BootStrape позволяет это сделать. Предполагается, что, что загрузчик ядра будет уже 32-битным, поэтому первую фазу перехода в защищенный режим(инициализацию IDTR и GDTR) я делаю в BootStrap, при дальнем переходе на код загрузчика я одновременно перехожу и в 32-битный режим. Вторая фаза инициализации защищенного режима будет выполняться уже загрузчиком ядра. |
Автор: | Гость [ 21 июл 2009, 17:17 ] |
Заголовок сообщения: | Re^2: Проблема с иниализацией системы |
Цитата: тоже мне проблема... побольше конопли курить нада и поменьше пейсать гуано кода. Если ты пишешь такой хороший код и куришь так много конопли, чего ж ты тогда не можешь ответить на такой простой вопрос? Хвастаться своей крутизной иди в школу, там народ редко видел что-то кроме паскаля. Хотя по стилю ответа складывается такое ощущение, что ты там еще и учишься. |
Автор: | SII [ 21 июл 2009, 17:30 ] |
Заголовок сообщения: | Re^3: Проблема с иниализацией системы |
Цитата: А почему бы и нет? Свободное место в BootStrape позволяет это сделать. Предполагается, что, что загрузчик ядра будет уже 32-битным, поэтому первую фазу перехода в защищенный режим(инициализацию IDTR и GDTR) я делаю в BootStrap Потому что вменяемую ось не сделаешь, не обращаясь на начальном этапе к БИОСу, а это значит, что надо скакать из реального в защищённой и обратно (ну или делать V86). |
Автор: | Гость [ 21 июл 2009, 20:32 ] |
Заголовок сообщения: | Re^4: Проблема с иниализацией системы |
На первом этапе так и предполагалось делать по двум причинам: 1) ядро должно быть пуританским (чрезвычайно маленьким) и драйвера в ядро не входят, 2) чтобы была возможность постоянно наблюдать работу системы |
Автор: | Himik [ 22 июл 2009, 20:02 ] |
Заголовок сообщения: | Re: Проблема с иниализацией системы |
Может быть рабочий пример пригодится http://express-os.narod.ru/files/bs-fat12.asm Замечу только по поводу инициализации IDT - здесь строить пустую таблицу абсолютно бессмысленно. |
Автор: | Гость [ 23 июл 2009, 19:16 ] |
Заголовок сообщения: | Re^2: Проблема с иниализацией системы |
Всем спасибо за замечания и ответы. Корень проблемы был успешно найден и нейтрализован. Он заключался в том, что регистр IDTR используется процессором как в защищенном так и в реальном режимах. Только по разному. Поэтому после моей инициализации процессор жил до первого прерывания. |
Автор: | SII [ 23 июл 2009, 22:34 ] |
Заголовок сообщения: | Re^3: Проблема с иниализацией системы |
А ларчик просто открывался... Я мог бы и догадаться: ведь я читал про последовательность перехода из защищённого режима в реальный, где перед переходом выполняются определённые пляски с бубном вокруг IDTR. Но забыл-с. Вот что значит знать такие вещи главным образом в теории :) |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |