/*
 *  linux/init/main.c
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file README.legal in the main directory of this archive
 * for more details.
 */

/*
 * 680x0/Amiga support by Hamish Macdonald
 */

#include <stdarg.h>

#if 0
#include <linux/mktime.h>
#endif
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/ptrace.h>
#include <linux/tty.h>
#include <linux/head.h>
#include <linux/unistd.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/fs.h>

#include <machine/ktypes.h>
#include <machine/sys_info.h>

#include <asm/system.h>
#include <asm/segment.h>

extern ulong * prof_buffer;
extern ulong prof_len;
extern void start(void);
extern int etext;
extern char *linux_banner;

extern void vec_init(void);
extern void init_INTS(void);
extern void sched_init(void);
extern ulong chr_dev_init(ulong,ulong);
extern ulong blk_dev_init(ulong,ulong);
extern void rd_load (void);

int root_mountflags = 0;

struct sys_info sys_info = {0,};

/*
 * These three variables describe the "init" program text, data and bss
 * as included in the kernel data segment.
 */
extern unsigned char initdata[];
extern ulong initsize;
extern ulong initbss;

/*
 * This is the kernel start function.
 * The parameters come from mm_init, which sets up
 * the memory management environment.
 */

void start_kernel (ulong memory_start, ulong memory_end)
{
#ifdef DEBUG
    printk ("made it to start_kernel (%#lx, %#lx)\n",
	    memory_start, memory_end);
#endif

    vec_init();
    init_INTS();
    sched_init();

#ifdef PROFILE_SHIFT
    prof_buffer = (ulong *) memory_start;
    prof_len = (ulong)&etext - (ulong)start;
    prof_len >>= PROFILE_SHIFT;
    memory_start += prof_len * sizeof(ulong);
#endif

    memory_start = chr_dev_init(memory_start,memory_end);
    memory_start = blk_dev_init(memory_start,memory_end);

    memory_start = inode_init(memory_start,memory_end);

    /*
     * tell the memory manager the bounds of memory available for
     * paging, after all other fixed memory has been allocated
     */
    mem_init(memory_start,memory_end);

    buffer_init();
#if 0
    time_init();
    floppy_init();
    sock_init();
#endif

    if (!sys_fork())
    {
	/* mount the root filesystem */
	mount_root ();

	/* output the banner */
	printk (linux_banner);

	/* setup the mm parameters */
	current->brk = initsize + initbss;
	current->end_data = 0;
	current->end_code = 0;	   /* no write protect */
	current->start_stack = TASK_SIZE;

	/* copy the init program to user space */
	memcpy_tofs( (void *)0, initdata, initsize);

	move_to_user_mode();
    }

    /*
     * task[0] is meant to be used as an "idle" task: it may not sleep, but
     * it might do some general things like count free pages or it could be
     * used to implement a reasonable LRU algorithm for the paging routines:
     * anything that can be useful, but shouldn't take time from the real
     * processes.
     *
     * Right now task[0] just does an infinite idle loop.
     */
    for(;;)
	schedule();
}
