Enabling paging causes reboot
Enabling paging causes reboot
When i'm implemented paging, all is compiled and linked fine, but when i start OS it immediately reboots. How to fix it?
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Enabling paging causes reboot
This is pretty elementary stuff and demonstrates that you probably don't understand what you are doing. (Have you read the Intel programmer's manual?) Most likely cause is an invalid page table. I was going to say that it was difficult to be sure as you hadn't posted your code. On reflection, that might only encourage you to post it in the expectation that someone would debug it for you.
The good news is that you now have an incentive to learn how to debug code. Take some time out to master this.
The good news is that you now have an incentive to learn how to debug code. Take some time out to master this.
Re: Enabling paging causes reboot
My code is from Setting Up Paging article.
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing
OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
Re: Enabling paging causes reboot
The code is probably not suited for the environment you set up. Anyway, we can't know what's wrong. I used the information from the wiki, and everything worked excellent.catnikita255 wrote:My code is from Setting Up Paging article.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
- Alan Kay
Re: Enabling paging causes reboot
It looks like you have identity mapped the first 4 MB of RAM. Is your code running at an address in that mapped space?catnikita255 wrote:My code is from Setting Up Paging article.
Re: Enabling paging causes reboot
Forgive for my poor english, but...
First of all you need to make sure that all page_dir and page_tables everything is 4kb aligned something like. 0x9A000, 0x9B000, 0x9C000 got it?
and then all that memory address must be insided of mapped address, let me try to explain... if you map the first 4MB all page dir and page table must be inside that
4MB memory, in case of your kernel be bigger then 4MB you need to map the first 2 page_dir[0] and page_dir[1] and so... got it?
load pagedir into cr3... and then change bit 31 into cr0 with something like set_cr0( get_cr0() | 0x80000000 );
try to halt system on isr 14...
like
printf("Address of fault %Xh\n", cr2);
for(;;);
this helps a lot...
sorry this is only that I can write, again sorry about my poor english
First of all you need to make sure that all page_dir and page_tables everything is 4kb aligned something like. 0x9A000, 0x9B000, 0x9C000 got it?
and then all that memory address must be insided of mapped address, let me try to explain... if you map the first 4MB all page dir and page table must be inside that
4MB memory, in case of your kernel be bigger then 4MB you need to map the first 2 page_dir[0] and page_dir[1] and so... got it?
load pagedir into cr3... and then change bit 31 into cr0 with something like set_cr0( get_cr0() | 0x80000000 );
try to halt system on isr 14...
like
printf("Address of fault %Xh\n", cr2);
for(;;);
this helps a lot...
sorry this is only that I can write, again sorry about my poor english
Re: Enabling paging causes reboot
That is incorrect. Page Directories and Page Tables use physical addresses and can be anywhere in available physical memory.all that memory address must be insided of mapped address, let me try to explain... if you map the first 4MB all page dir and page table must be inside that
4MB memory
Re: Enabling paging causes reboot
Again, my example/actual bootstrap code, maybe it helps?
Code: Select all
.set ALIGN, 1<<0 # align loaded modules on page boundaries
.set MEMINFO, 1<<1 # provide memory map
.set FLAGS, ALIGN | MEMINFO # this is the Multiboot 'flag' field
.set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header
.set CHECKSUM, -(MAGIC + FLAGS) # checksum of above, to prove we are multiboot
.section .multiboot
.long MAGIC
.long FLAGS
.long CHECKSUM
.section .stack, "aw", @nobits
stackBottom:
.skip 16384
stackTop:
.set KVIRT_BASE, 0xC0000000
.set KPAGE_NUM, (KVIRT_BASE >> 12)
.section .bss
.align 0x1000
pageDirectory:
.skip 0x1000 # Page directory
pageTables:
.skip 0x1000 # First identity-mapped 4MiB
.skip 0x1000 * 256 # 3GiB to 4GiB area
gdtPtr:
.skip 6 # GDT Pointer
gdt:
.skip 8 * 3 # Actual GDT
idtPtr:
.skip 6 # IDT Pointer
idt:
.skip 8 * 256 # Actual IDT
.section .boot
.global __start__
__start__:
# A Multiboot-compliant bootloader just yielded
# execution to the OS here. At this moment,
# everything is loaded at 1MiB, but the code
# thinks it's on 3GiB! The solution? Subtract
# 3GiB from *each* address used, so it resolves
# to the correct physical address. That's the job
# of the 'subl $KVIRT_BASE, %edx' stuff all around
# this function. Once the paging structures are fully
# calculated and loaded, __start__() can work with virtual
# addresses. It then passes control to realStart(), the
# routine responsible for parsing the Multiboot information (TODO),
# setting up the descriptor tables (GDT and IDT), and
# finally calling KernelInit. If something fails,
# criticalError() is a minimalistic asm version of KTPipe
# that writes some string in red/white to VGA memory and halts.
# Load the stack (I can't live up from the registers!)
movl $stackTop, %esp
subl $KVIRT_BASE, %esp
# Save Multiboot Information (%ebx) and Bootloader Magic (%eax)
push %eax
push %ebx
# Map the first 4MiB to the first page table
movl $pageDirectory, %edx
subl $KVIRT_BASE, %edx
movl $pageTables, %eax
subl $KVIRT_BASE, %eax
orl $0x00000003, %eax
movl %eax, (%edx)
# Identity map the first page table
movl $pageTables, %edi
subl $KVIRT_BASE, %edi
movl $1024, %ecx
movl %ecx, %ebx
.identmap:
movl %ebx, %eax
subl %ecx, %eax
movl %eax, %esi
shll $12, %esi
orl $0x00000003, %esi
movl $4, %edx
mull %edx
movl %edi, %edx
addl %eax, %edx
movl %esi, (%edx)
loop .identmap
# Map the first Gigabyte to 3GiB upwards
movl $pageTables, %edi
subl $KVIRT_BASE, %edi
addl $0x1000, %edi
movl $256, %ecx
movl $0, %edx
.highmap:
movl %ecx, %ebx
movl $1024, %ecx
.highmap2:
movl %edx, %eax
shll $12, %eax
orl $0x00000003, %eax
movl %eax, (%edi)
incl %edx
addl $4, %edi
loop .highmap2
movl %ebx, %ecx
loop .highmap
# Load the higher-half tables
movl $pageDirectory, %edx
subl $KVIRT_BASE, %edx
addl $3072, %edx
movl $256, %ecx
movl %ecx, %ebx
.filltop:
movl %ebx, %esi
subl %ecx, %esi
movl %edx, %edi
movl $0x1000, %eax
mull %esi
movl %edi, %edx
movl $pageTables, %edi
subl $KVIRT_BASE, %edi
addl $0x1000, %edi
addl %eax, %edi
orl $0x00000003, %edi
movl %edx, %ebp
movl $4, %eax
mull %esi
movl %ebp, %edx
addl %edx, %eax
movl %edi, (%eax)
loop .filltop
# Load the page directory
movl $pageDirectory, %edx
subl $KVIRT_BASE, %edx
movl %edx, %cr3
# Enable paging
movl %cr0, %edx
orl $0x80000000, %edx
movl %edx, %cr0
# Jump to some code that *really* assumes it's on $KVIRT_BASE
movl $realStart, %edx
jmp *%edx
.text
realStart:
# Load the virtual value of $stackTop
# And, to comply with the ABI, load %esp into %ebp
addl $KVIRT_BASE, %esp
movl %esp, %ebp
# Setup the Global Descriptor Table (GDT) Pointer
movl $gdtPtr, %edx
movl $gdt, %eax
movw $23, (%edx)
movl %eax, 2(%edx)
# Load the Null GDT Entry
push $0
push $0
push $0
push $0
push $0
call setGDTEntry
addl $20, %esp
# Load the Kernel Code GDT Entry
push $0xCF
push $0x9A
push $0xFFFFFFFF
push $0
push $1
call setGDTEntry
addl $20, %esp
# Load the Kernel Data GDT Entry
push $0xCF
push $0x92
push $0xFFFFFFFF
push $0
push $2
call setGDTEntry
addl $20, %esp
# Actually load the full GDT
movl $gdtPtr, %eax
lgdt (%eax) # Do it!
movw $0x10, %ax # Load the data segment registers
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
ljmp $0x08, $.gdtReady # Some black magic to load %cs
.gdtReady:
# Do the same as above, but with the Interrupt Descriptor Table (IDT) Pointer
movl $idtPtr, %edx
movl $idt, %eax
movw $384, (%edx)
movl %eax, 2(%edx)
# We'll load *all* the ISRs, so we need to use as less code as possible,
# but stack memory is infinite, as far as the processor is concerned :)
subl $192, %esp
#define ISR(no, who) \
movl $__inthand_ ## who ## __, %eax; \
movl %eax, no(%esp);
ISR(0, exc0)
ISR(4, exc1)
ISR(8, exc2)
ISR(12, exc3)
ISR(16, exc4)
ISR(20, exc5)
ISR(24, exc6)
ISR(28, exc7)
ISR(32, exc8)
ISR(36, exc9)
ISR(40, exc10)
ISR(44, exc11)
ISR(48, exc12)
ISR(52, exc13)
ISR(56, exc14)
ISR(60, exc15)
ISR(64, exc16)
ISR(68, exc17)
ISR(72, exc18)
ISR(76, exc19)
ISR(80, exc20)
ISR(84, exc21)
ISR(88, exc22)
ISR(92, exc23)
ISR(96, exc24)
ISR(100, exc25)
ISR(104, exc26)
ISR(108, exc27)
ISR(112, exc28)
ISR(116, exc29)
ISR(120, exc30)
ISR(124, exc31)
ISR(128, irq0)
ISR(132, irq1)
ISR(136, irq2)
ISR(140, irq3)
ISR(144, irq4)
ISR(148, irq5)
ISR(152, irq6)
ISR(156, irq7)
ISR(160, irq8)
ISR(164, irq9)
ISR(168, irq10)
ISR(172, irq11)
ISR(176, irq12)
ISR(180, irq13)
ISR(184, irq14)
ISR(188, irq15)
#undef ISR
# Actually set the IDT entries
movl $48, %ecx
.idtLoop:
movl %ecx, %ebx
movl $48, %esi
subl %ebx, %esi
movl (%esp, %esi, 4), %eax
push $0x8E
push $0x08
push %eax
push %esi
call setIDTEntry
addl $16, %esp
movl %ebx, %ecx
loop .idtLoop
addl $192, %esp # Free up that stack space
# Load the IDT and we'll be done
movl $idtPtr, %eax
lidt (%eax) # Do it!
# Reconfigure the PICs, so stupid stuff doesn't happens
inb $0x21, %al
movb %al, %bl
inb $0xA1, %al
movb %al, %cl
movb $0x11, %al
outb %al, $0x20
outb %al, $0xA0
movb $0x20, %al
outb %al, $0x21
movb $0x28, %al
outb %al, $0xA1
movb $0x04, %al
outb %al, $0x21
movb $0x02, %al
outb %al, $0xA1
movb $0x01, %al
outb %al, $0x21
outb %al, $0xA1
movb %bl, %al
outb %al, $0x21
movb %cl, %al
outb %al, $0xA1
# Get Multiboot Information (%ebx) and Bootloader Magic (%eax)
pop %ebx
pop %eax
# Check the Bootloader magic. If it's invalid, panic!
cmp $0x2BADB002, %eax
je .noerror
# Error! **** it up!
push $.ENOTMULTIBOOT # "Not using a Multiboot-compliant bootloader"
push $0x01 # Error Code
call criticalError
.noerror:
# Parse the first-level Multiboot Structure (TODO)
addl $KVIRT_BASE, %ebx # Physical to Virtual
# Call trivial global constructors
call _init
# Pass it to KernelInit()...
push %ebx
# Should I put a comment here? Anyway, I did it.
call KernelInit
# If KernelInit() somehow returns, halt the machine.
# Non-maskable interrupt? Don't worry! Just loop forever.
.hang:
cli
hlt
jmp .hang
setGDTEntry:
push %ebp
movl %esp, %ebp
push %esi # We need some extra memory
movl 8(%ebp), %eax # GDT Index
movl $gdt, %ecx
movl 12(%ebp), %edx # The base
movw %dx, 2(%ecx, %eax, 8) # Set low base
shrl $16, %edx
movb %dl, 4(%ecx, %eax, 8) # Set middle base
movb %dh, 7(%ecx, %eax, 8) # Set high base
movl 16(%ebp), %edx # The limit
movw %dx, (%ecx, %eax, 8) # Set low limit
movl 24(%ebp), %esi # Granularity
shrl $16, %edx
andl $0x0F, %edx
andl $0xF0, %esi
orl %esi, %edx
movb %dl, 6(%ecx, %eax, 8) # Set granularity
movl 20(%ebp), %edx # Access
movb %dl, 5(%ecx, %eax, 8) # Set access
pop %esi
movl %ebp, %esp
pop %ebp
ret
setIDTEntry:
push %ebp
movl %esp, %ebp
movl 8(%ebp), %eax # IDT Index
movl $idt, %ecx
movl 12(%ebp), %edx # The base
movw %dx, (%ecx, %eax, 8) # Set low base
shrl $16, %edx
movw %dx, 6(%ecx, %eax, 8) # Set high base
movl 16(%ebp), %edx # The selector
movw %dx, 2(%ecx, %eax, 8) # Set selector
movl 20(%ebp), %edx # Flags
movb %dl, 5(%ecx, %eax, 8) # Set flags
movb $0, 4(%ecx, %eax, 8) # Always 0
movl %ebp, %esp
pop %ebp
ret
criticalError:
# %ebx is the offset over VGA memory used
# by the criticalPrint* functions.
movl $0, %ebx
# "Fatal Error Code "
movl $.EERROR, %eax
call criticalPrintString
pop %eax # Error Code
call criticalPrintHex
movb $0x3A, %al # ':' Character
call criticalPrintChar
movb $0x20, %al # ' ' Character
call criticalPrintChar
pop %eax # Error Message
call criticalPrintString
movl $.EHALT, %eax
call criticalPrintString
# Halt
cli
hlt
criticalPrintString:
# Parameters:
# %eax: Address of null-terminated string to print
.strloop:
movb (%eax), %al
cmp $0x00, %al
je .strloopend
call criticalPrintChar
incl %eax
incl %ebx
jmp .strloop
.strloopend:
ret
criticalPrintHex:
# Parameters:
# %eax: Integer to print
movb $0x30, %al # '0' Character
call criticalPrintChar
incl %ebx
movb $0x78, %al # 'x' Character
call criticalPrintChar
incl %ebx
movl $8, %ecx
.hexloop:
movl %ecx, %esi
decl %esi
push %eax
movl %eax, %edi
movl $4, %eax
mull %esi
xchg %eax, %ecx
shrl %cl, %edi
xchg %eax, %ecx
movl %edi, %edx
push %ecx
movl $2, %ecx
.hexbitloop:
push %edx
andb $0x0F, %dl
# Get the real value...
.hextest:
cmpb $0x0A, %dl
jb .hextestdecimal
jae .hextesthexa
.hextestdecimal:
addb $0x30, %dl # Calculates character between '0' and '9'
jmp .hextestend
.hextesthexa:
subb $0x0A, %dl # For offsetting
addb $0x41, %dl
jmp .hextestend
.hextestend:
movb %dl, %al
call criticalPrintChar
incl %ebx
pop %edx
shrl $4, %edx
loop .hexbitloop
pop %ecx
pop %eax
loop .hexloop
ret
criticalPrintChar:
# Parameters:
# %al: Character to print
# %ebx: Offset over VGA Memory
# Uses:
# %dx: Actual value written to VGA Memory
movb $0x4F, %dh # White text on red background
movb %al, %dl # Mix it...
movw %dx, 0xB8000(,%ebx, 2) # Print!
ret
.section rodata
# Concatenated on every error
.EERROR:
.asciz "Fatal Error Code "
.EHALT:
.asciz ". System halted! Please reboot manually."
# The actual errors
.ENOTMULTIBOOT:
.asciz "Not using a Multiboot-compliant bootloader"
Happy New Code!
Hello World in Brainfuck :[/size]
Hello World in Brainfuck :
Code: Select all
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.