2005-04-16 15:20:36 -07:00
/*
* linux / arch / m68knommu / mm / init . c
*
* Copyright ( C ) 1998 D . Jeff Dionne < jeff @ lineo . ca > ,
* Kenneth Albanowski < kjahds @ kjahds . com > ,
* Copyright ( C ) 2000 Lineo , Inc . ( www . lineo . com )
*
* Based on :
*
* linux / arch / m68k / mm / init . c
*
* Copyright ( C ) 1995 Hamish Macdonald
*
* JAN / 1999 - - hacked to support ColdFire ( gerg @ snapgear . com )
* DEC / 2000 - - linux 2.4 support < davidm @ snapgear . com >
*/
# include <linux/signal.h>
# include <linux/sched.h>
# include <linux/kernel.h>
# include <linux/errno.h>
# include <linux/string.h>
# include <linux/types.h>
# include <linux/ptrace.h>
# include <linux/mman.h>
# include <linux/mm.h>
# include <linux/swap.h>
# include <linux/init.h>
# include <linux/highmem.h>
# include <linux/pagemap.h>
# include <linux/bootmem.h>
# include <linux/slab.h>
# include <asm/setup.h>
# include <asm/segment.h>
# include <asm/page.h>
# include <asm/pgtable.h>
# include <asm/system.h>
# include <asm/machdep.h>
# undef DEBUG
extern void die_if_kernel ( char * , struct pt_regs * , long ) ;
extern void free_initmem ( void ) ;
/*
* BAD_PAGE is the page that is used for page faults when linux
* is out - of - memory . Older versions of linux just did a
* do_exit ( ) , but using this instead means there is less risk
* for a process dying in kernel mode , possibly leaving a inode
* unused etc . .
*
* BAD_PAGETABLE is the accompanying page - table : it is initialized
* to point to BAD_PAGE entries .
*
* ZERO_PAGE is a special page that is used for zero - initialized
* data and COW .
*/
static unsigned long empty_bad_page_table ;
static unsigned long empty_bad_page ;
unsigned long empty_zero_page ;
extern unsigned long memory_start ;
extern unsigned long memory_end ;
/*
* paging_init ( ) continues the virtual memory environment setup which
* was begun by the code in arch / head . S .
* The parameters are pointers to where to stick the starting and ending
* addresses of available kernel virtual memory .
*/
2007-10-24 12:03:46 +10:00
void __init paging_init ( void )
2005-04-16 15:20:36 -07:00
{
/*
* Make sure start_mem is page aligned , otherwise bootmem and
* page_alloc get different views of the world .
*/
# ifdef DEBUG
unsigned long start_mem = PAGE_ALIGN ( memory_start ) ;
# endif
unsigned long end_mem = memory_end & PAGE_MASK ;
# ifdef DEBUG
printk ( KERN_DEBUG " start_mem is %#lx \n virtual_end is %#lx \n " ,
start_mem , end_mem ) ;
# endif
/*
* Initialize the bad page table and bad page to point
* to a couple of allocated pages .
*/
empty_bad_page_table = ( unsigned long ) alloc_bootmem_pages ( PAGE_SIZE ) ;
empty_bad_page = ( unsigned long ) alloc_bootmem_pages ( PAGE_SIZE ) ;
empty_zero_page = ( unsigned long ) alloc_bootmem_pages ( PAGE_SIZE ) ;
memset ( ( void * ) empty_zero_page , 0 , PAGE_SIZE ) ;
/*
* Set up SFC / DFC registers ( user data space ) .
*/
set_fs ( USER_DS ) ;
# ifdef DEBUG
printk ( KERN_DEBUG " before free_area_init \n " ) ;
printk ( KERN_DEBUG " free_area_init -> start_mem is %#lx \n virtual_end is %#lx \n " ,
start_mem , end_mem ) ;
# endif
{
2006-09-25 23:31:10 -07:00
unsigned long zones_size [ MAX_NR_ZONES ] = { 0 , } ;
2005-04-16 15:20:36 -07:00
2009-01-28 17:07:19 +10:00
zones_size [ ZONE_DMA ] = ( end_mem - PAGE_OFFSET ) > > PAGE_SHIFT ;
2005-04-16 15:20:36 -07:00
free_area_init ( zones_size ) ;
}
}
2007-10-24 12:03:46 +10:00
void __init mem_init ( void )
2005-04-16 15:20:36 -07:00
{
int codek = 0 , datak = 0 , initk = 0 ;
unsigned long tmp ;
extern char _etext , _stext , _sdata , _ebss , __init_begin , __init_end ;
extern unsigned int _ramend , _rambase ;
unsigned long len = _ramend - _rambase ;
unsigned long start_mem = memory_start ; /* DAVIDM - these must start at end of kernel */
unsigned long end_mem = memory_end ; /* DAVIDM - this must not include kernel stack at top */
2009-05-15 10:59:37 -07:00
pr_debug ( " Mem_init: start=%lx, end=%lx \n " , start_mem , end_mem ) ;
2005-04-16 15:20:36 -07:00
end_mem & = PAGE_MASK ;
high_memory = ( void * ) end_mem ;
start_mem = PAGE_ALIGN ( start_mem ) ;
max_mapnr = num_physpages = ( ( ( unsigned long ) high_memory ) - PAGE_OFFSET ) > > PAGE_SHIFT ;
/* this will put all memory onto the freelists */
totalram_pages = free_all_bootmem ( ) ;
codek = ( & _etext - & _stext ) > > 10 ;
datak = ( & _ebss - & _sdata ) > > 10 ;
initk = ( & __init_begin - & __init_end ) > > 10 ;
tmp = nr_free_pages ( ) < < PAGE_SHIFT ;
2006-06-26 10:33:10 +10:00
printk ( KERN_INFO " Memory available: %luk/%luk RAM, (%dk kernel code, %dk data) \n " ,
2005-04-16 15:20:36 -07:00
tmp > > 10 ,
len > > 10 ,
codek ,
datak
) ;
}
# ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem ( unsigned long start , unsigned long end )
{
int pages = 0 ;
for ( ; start < end ; start + = PAGE_SIZE ) {
ClearPageReserved ( virt_to_page ( start ) ) ;
2006-03-22 00:08:40 -08:00
init_page_count ( virt_to_page ( start ) ) ;
2005-04-16 15:20:36 -07:00
free_page ( start ) ;
totalram_pages + + ;
pages + + ;
}
2009-09-17 11:49:41 -04:00
printk ( KERN_NOTICE " Freeing initrd memory: %dk freed \n " , pages * ( PAGE_SIZE / 1024 ) ) ;
2005-04-16 15:20:36 -07:00
}
# endif
void
free_initmem ( )
{
# ifdef CONFIG_RAMKERNEL
unsigned long addr ;
extern char __init_begin , __init_end ;
/*
* The following code should be cool even if these sections
* are not page aligned .
*/
addr = PAGE_ALIGN ( ( unsigned long ) ( & __init_begin ) ) ;
/* next to check that the page we free is not a partial page */
for ( ; addr + PAGE_SIZE < ( unsigned long ) ( & __init_end ) ; addr + = PAGE_SIZE ) {
ClearPageReserved ( virt_to_page ( addr ) ) ;
2006-03-22 00:08:40 -08:00
init_page_count ( virt_to_page ( addr ) ) ;
2005-04-16 15:20:36 -07:00
free_page ( addr ) ;
totalram_pages + + ;
}
printk ( KERN_NOTICE " Freeing unused kernel memory: %ldk freed (0x%x - 0x%x) \n " ,
( addr - PAGE_ALIGN ( ( long ) & __init_begin ) ) > > 10 ,
( int ) ( PAGE_ALIGN ( ( unsigned long ) ( & __init_begin ) ) ) ,
( int ) ( addr - PAGE_SIZE ) ) ;
# endif
}