From owner-freebsd-hackers@FreeBSD.ORG Mon Nov 22 21:20:16 2010 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2ADC2106576C for ; Mon, 22 Nov 2010 21:20:13 +0000 (UTC) (envelope-from sergio.g.delreal@gmail.com) Received: from mail-ew0-f54.google.com (mail-ew0-f54.google.com [209.85.215.54]) by mx1.freebsd.org (Postfix) with ESMTP id 07C4A8FC14 for ; Mon, 22 Nov 2010 21:20:12 +0000 (UTC) Received: by ewy3 with SMTP id 3so4185165ewy.13 for ; Mon, 22 Nov 2010 13:20:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:in-reply-to :references:date:message-id:subject:from:to:content-type; bh=4pVCkDCAADjphwCyOe9gWBlhf1kPrxA9XVrj9CzSiFA=; b=WgD4emOnasgzXpuFyAx1Q+wVw2Ah8/WSL+D+saYMZHs1UzM2kEx89cpiKgxluCzdAj 9eLKoiG2yVA8t19RRSqJ7fvQEWMeseFdW7R1pcL3neq/a163RqOrfYEjc0D+cCmpreEZ IDUG7abJqDEzKktQAbWuLtUtkbd2RoG4ILDOE= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; b=W50Xhe8QvWzqqVhS0R1tsgYSudU9oNbPpqvw2JxA2GUhZrdWHdLp5EffED5kKUMvSU hKRjyajzzLhC06Up0yMTl7LkC7lRub4d27Wa34DSw0C2fWm1JPJcBz7F1khMWiYwdb2j /ymY4wW9ypqJDSQkiadB4Mp0c3WpSkISRs6Yo= MIME-Version: 1.0 Received: by 10.213.9.200 with SMTP id m8mr4831717ebm.27.1290460811350; Mon, 22 Nov 2010 13:20:11 -0800 (PST) Received: by 10.213.19.205 with HTTP; Mon, 22 Nov 2010 13:20:11 -0800 (PST) In-Reply-To: <201011220920.15431.jhb@freebsd.org> References: <201011220920.15431.jhb@freebsd.org> Date: Mon, 22 Nov 2010 16:20:11 -0500 Message-ID: From: =?ISO-8859-1?Q?Sergio_Andr=E9s_G=F3mez_del_Real?= To: John Baldwin , freebsd-hackers@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 Cc: Subject: Re: Quick i386 question... X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Nov 2010 21:20:16 -0000 Maybe my issue does not belong here, because it is not FreeBSD-related, but I can't find any other source for this kind of technical issue. My problem is that I am trying to design and now implement a small and simple operating system. I know that it is very difficult to follow for someone not familiar to the system design, but I am going to try to describe my problem: In the following code the first thing is to zero 5MB of memory from 5MB-10MB. This is in call clear_mem. Then in the call to set_pae the PDPTE's are copied to PDPTEs, that is, address 0x00500000 (5MB). The control string is at pae_ctrl_str, and the reserved bits are set to 0. The call to map_monitor maps the first 256 entries of the first page table referenced by the page directory from the first PDPTE. The call to map_kernel does the same with the 257's entry. The mappings are to identical physical addresses. After that, PDPTE is shifted 5 bits to the left and loaded to cr3, so the address for the PDPTE's is 0x500000 (5MB). Next PAE is set and then %cr0 is loaded to %eax, bits 30 and 29 (starting from 0) are turned off and bit 31 (for paging) is turned on. When I copy it to %cr0 I get a General-Protection Exception. The eip that caused it is from the movl %eax, %cr0 instruction. What I have read from Intel, the only way to get a GP at this instruction is to write reserved bits to the PDPTE's or with a bad combination in setting the bits in %cr0. I can't seem to be able to see any of this faults. I would appreciate if someone could find the source of the problem, because setting page-table structures and activating page-table seems quite simple. .set PDPTEs, 0x00500000 # PDPTE's address (5MB) .set PG_ENABLE, 0x80000000 # enable paging .set PDT_1, 0x00501000 # Page-directory table address .set PTE_D1_E1, 0x00505000 # Page-table address . . . cld # up we go for string ops movl $0x500000, %edi # start of memory block movl $0x500000, %ecx # number of bytes to zeroe call clear_mem # clear %ecx bytes from %edi memory address call set_pae # set PDPT's for PAE call map_monitor # map the monitor program to identical physical pages call map_kernel # also the kernel movl $PDPTEs, %eax # load address for PDPT's shll $5, %eax # first 5 bits are ignored movl %eax, %cr3 # save movl %cr4, %eax # load register orl $0x20, %eax # set PAE bit movl %eax, %cr4 # enable PAE addressing movl %cr0, %eax # load %cr0 orl $0x60000000, %eax # clear CD and NW bits movl %eax, %cr0 # save orl $PG_ENABLE, %eax # enable paging movl %eax, %cr0 # save # HERE I GET THE GP EXCEPTION . . . /* * Zero contigious blocks of memory. */ clear_mem: rep # clear stosb # memory block ret /* * We use the PAE extension service of i386 processor to be able to create * virtual-memory data structures in addresses above (2^20)-1 bytes. */ set_pae: movl $PDPTEs, %edi # pointer to PDPTE's movl $pae_ctrl_str, %esi # control string 1: lodsl # load value testl %eax, %eax # end of control? jz 2f # yes movl %eax, (%edi) # PDPTE1 word 1 lodsl # load value movl %eax, 4(%edi) # PDPTE1 word 2 addl $8, %edi # next entry jmp 1b 2: ret /* * The strategy is to map the low-memory addresses to identical physical * addresses. * Each entry maps a 4KB page, so we loop 256 times to map the first MB * to identical physical memory. */ map_monitor: movl $PDT_1, %edi # pointer to first page directory movl $map_monitor_ctrl_str, %esi # monitor's page table lodsl movl %eax, (%edi) # page directory entry 1 word 1 lodsl movl %eax, 4(%edi) # page directory entry 1 word 2 movl $PTE_D1_E1, %edi # pointer to first page table of first page directory movl $mon_pag, %esi # pointer to first page entry movl $256, %ecx # loop (map) number of entries (4096 * 256 == 1MB) call pages_loop ret /* * Kernel's virtual address starts at 0x00100000. Map kernel size starting * from that address to physical address to which the kernel was loaded, being * 0x100000. */ map_kernel: movl kernel_size, %eax # load kernel size in sectors (THIS VALUE IS 1) shll $9, %eax # to bytes shrl $13, %eax # to pages incl %ecx # one more movl %eax, %ecx # loop times 1: movl $PTE_D1_E1, %edi # pointer to first page table of first page directory addl $0x800, %edi # point to kernel's first entry in table movl $kern_pag, %esi # pointer to first page entry call pages_loop ret /* * Routine to map a contigious block of virtual-memory to a contigious block * of physical-memory. */ pages_loop: lodsl # load first word movl %eax, %ebx # save it lodsl # load second word movl %eax, %edx # save it testl %ecx, %ecx jz end_pages_loop 1: movl %ebx, (%edi) movl %edx, 4(%edi) addl $8, %edi # next entry in table shrl $12, %ebx addl $0x1000, %ebx # add one page (4096 bytes) shll $12, %ebx orl $0xb, %ebx loop 1b end_pages_loop: ret map_monitor_ctrl_str: mon_pag_tab: .long 0x0500000b, 0x00000005 # page directory table 1 .long 0x00000000 mon_pag: .long 0x0000000b, 0x00000000 # first page (0x0) pae_ctrl_str: .long 0x01000009, 0x00000005 # PDPTE 1 .long 0x02000009, 0x00000005 # PDPTE 1 .long 0x03000009, 0x00000005 # PDPTE 1 .long 0x04000009, 0x00000005 # PDPTE 1 .long 0x00000000 map_kernel_ctrl_str: kern_pag: .long 0x0000000b, 0x00000001 # first page (0x100000)