Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ia32/src/boot/boot.S

    r1d3d2cf rfb45c7b  
    22 * Copyright (c) 2001 Jakub Jermar
    33 * Copyright (c) 2005 Martin Decky
     4 * Copyright (c) 2011 Martin Sucha
    45 * All rights reserved.
    56 *
     
    9798        pm_status $status_prot
    9899       
     100#include "vesa_prot.inc"
     101       
     102#ifndef PROCESSOR_i486
     103       
     104        pm_status $status_prot2
     105       
    99106        movl $(INTEL_CPUID_LEVEL), %eax
    100107        cpuid
     
    105112        cpuid
    106113        bt $(INTEL_PSE), %edx
    107         jc pse_supported
     114        jnc pse_unsupported
     115               
     116                /* Map kernel and turn paging on */
     117                pm_status $status_pse
     118                call map_kernel_pse
     119                jmp stack_init
     120       
     121#endif /* PROCESSOR_i486 */
    108122       
    109123        pse_unsupported:
    110124               
    111                 pm_error $err_pse
    112        
    113         pse_supported:
    114        
    115 #include "vesa_prot.inc"
    116        
    117         /* Map kernel and turn paging on */
    118         call map_kernel
     125                /* Map kernel and turn paging on */
     126                pm_status $status_non_pse
     127                call map_kernel_non_pse
     128       
     129        stack_init:
    119130       
    120131        /* Create the first stack frame */
     
    122133        movl %esp, %ebp
    123134       
    124         pm2_status $status_prot2
     135        pm2_status $status_prot3
    125136       
    126137        /* Call arch_pre_main(grub_eax, grub_ebx) */
     
    140151                jmp hlt0
    141152
    142 /** Setup mapping for the kernel.
     153/** Setup mapping for the kernel (PSE variant)
    143154 *
    144155 * Setup mapping for both the unmapped and mapped sections
     
    146157 *
    147158 */
    148 .global map_kernel
    149 map_kernel:
     159.global map_kernel_pse
     160map_kernel_pse:
     161        /* Paging features */
    150162        movl %cr4, %ecx
    151163        orl $(1 << 4), %ecx      /* PSE on */
     
    158170        xorl %ebx, %ebx
    159171       
    160         floop:
     172        floop_pse:
    161173                movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax
    162174                orl %ebx, %eax
     
    169181                incl %ecx
    170182                cmpl $512, %ecx
    171                 jl floop
     183                jl floop_pse
    172184       
    173185        movl %esi, %cr3
     
    177189        movl %ebx, %cr0
    178190        ret
     191
     192/** Setup mapping for the kernel (non-PSE variant).
     193 *
     194 * Setup mapping for both the unmapped and mapped sections
     195 * of the kernel. For simplicity, we map the entire 4G space.
     196 *
     197 */
     198map_kernel_non_pse:
     199        /* Paging features */
     200        movl %cr4, %ecx
     201        andl $(~(1 << 5)), %ecx  /* PAE off */
     202        movl %ecx, %cr4
     203       
     204        call calc_kernel_end
     205        call find_mem_for_pt
     206       
     207        mov kernel_end, %esi
     208        mov free_area, %ecx
     209       
     210        cmpl %esi, %ecx
     211        jbe use_kernel_end
     212               
     213                mov %ecx, %esi
     214               
     215                /* Align address down to 4k */
     216                andl $(~4095), %esi
     217               
     218        use_kernel_end:
     219               
     220                /* Align address to 4k */
     221                addl $4095, %esi
     222                andl $(~4095), %esi
     223               
     224                /* Allocate space for page tables */
     225                movl %esi, pt_loc
     226                movl $ballocs, %edi
     227                andl $0x7fffffff, %edi
     228               
     229                movl %esi, (%edi)
     230                addl $4, %edi
     231                movl $(2 * 1024 * 1024), (%edi)
     232               
     233                /* Fill page tables */
     234                xorl %ecx, %ecx
     235                xorl %ebx, %ebx
     236               
     237                floop_pt:
     238                        movl $((1 << 1) | (1 << 0)), %eax
     239                        orl %ebx, %eax
     240                        movl %eax, (%esi, %ecx, 4)
     241                        addl $(4 * 1024), %ebx
     242                       
     243                        incl %ecx
     244                        cmpl $(512 * 1024), %ecx
     245                       
     246                        jl floop_pt
     247               
     248                /* Fill page directory */
     249                movl $(page_directory + 0), %esi
     250                movl $(page_directory + 2048), %edi
     251                xorl %ecx, %ecx
     252                movl pt_loc, %ebx
     253               
     254                floop:
     255                        movl $((1 << 1) | (1 << 0)), %eax
     256                        orl %ebx, %eax
     257                       
     258                        /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
     259                        movl %eax, (%esi, %ecx, 4)
     260                       
     261                        /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
     262                        movl %eax, (%edi, %ecx, 4)
     263                        addl $(4 * 1024), %ebx
     264                       
     265                        incl %ecx
     266                        cmpl $512, %ecx
     267                       
     268                        jl floop
     269               
     270                movl %esi, %cr3
     271               
     272                movl %cr0, %ebx
     273                orl $(1 << 31), %ebx  /* paging on */
     274                movl %ebx, %cr0
     275               
     276                ret
     277
     278/** Calculate unmapped address of the end of the kernel. */
     279calc_kernel_end:
     280        movl $hardcoded_load_address, %edi
     281        andl $0x7fffffff, %edi
     282        movl (%edi), %esi
     283        andl $0x7fffffff, %esi
     284       
     285        movl $hardcoded_ktext_size, %edi
     286        andl $0x7fffffff, %edi
     287        addl (%edi), %esi
     288        andl $0x7fffffff, %esi
     289       
     290        movl $hardcoded_kdata_size, %edi
     291        andl $0x7fffffff, %edi
     292        addl (%edi), %esi
     293        andl $0x7fffffff, %esi
     294        movl %esi, kernel_end
     295       
     296        ret
     297
     298/** Find free 2M (+4k for alignment) region where to store page tables */
     299find_mem_for_pt:
     300        /* Check if multiboot info is present */
     301        cmpl $MULTIBOOT_LOADER_MAGIC, grub_eax
     302        je check_multiboot_map
     303               
     304                ret
     305       
     306        check_multiboot_map:
     307               
     308                /* Copy address of the multiboot info to ebx */
     309                movl grub_ebx, %ebx
     310               
     311                /* Check if memory map flag is present */
     312                movl (%ebx), %edx
     313                andl $(1 << 6), %edx
     314                jnz use_multiboot_map
     315                       
     316                        ret
     317               
     318        use_multiboot_map:
     319               
     320                /* Copy address of the memory map to edx */
     321                movl 48(%ebx), %edx
     322                movl %edx, %ecx
     323               
     324                addl 44(%ebx), %ecx
     325               
     326                /* Find a free region at least 2M in size */
     327                check_memmap_loop:
     328                       
     329                        /* Is this a free region? */
     330                        cmp $1, 20(%edx)
     331                        jnz next_region
     332                       
     333                        /* Check size */
     334                        cmp $0, 16(%edx)
     335                        jnz next_region
     336                       
     337                        cmpl $(2 * 1024 * 1024 + 4 * 1024), 12(%edx)
     338                        jbe next_region
     339                       
     340                        cmp $0, 8(%edx)
     341                        jz found_region
     342               
     343                next_region:
     344                       
     345                        cmp %ecx, %edx
     346                        jbe next_region_do
     347                       
     348                                ret
     349               
     350                next_region_do:
     351                       
     352                        addl (%edx), %edx
     353                        addl $4, %edx
     354                        jmp check_memmap_loop
     355                       
     356                found_region:
     357                       
     358                        /* Use end of the found region */
     359                        mov 4(%edx), %ecx
     360                        add 12(%edx), %ecx
     361                        sub $(2 * 1024 * 1024), %ecx
     362                        mov %ecx, free_area
     363                       
     364                        ret
    179365
    180366/** Print string to EGA display (in light red) and halt.
     
    521707grub_eax:
    522708        .long 0
    523 
    524709grub_ebx:
    525710        .long 0
    526711
    527 err_pse:
    528         .asciz "Page Size Extension not supported. System halted."
     712pt_loc:
     713        .long 0
     714kernel_end:
     715        .long 0
     716free_area:
     717        .long 0
    529718
    530719status_prot:
    531720        .asciz "[prot] "
     721status_pse:
     722        .asciz "[pse] "
     723status_non_pse:
     724        .asciz "[non_pse] "
    532725status_vesa_copy:
    533726        .asciz "[vesa_copy] "
     
    538731status_prot2:
    539732        .asciz "[prot2] "
     733status_prot3:
     734        .asciz "[prot3] "
    540735status_main:
    541736        .asciz "[main] "
Note: See TracChangeset for help on using the changeset viewer.