⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 head.s

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 S
📖 第 1 页 / 共 5 页
字号:
/* -*- mode: asm -*-**** head.S -- This file contains the initial boot code for the**	     Linux/68k kernel.**** Copyright 1993 by Hamish Macdonald**** 68040 fixes by Michael Rausch** 68060 fixes by Roman Hodek** MMU cleanup by Randy Thelen** Final MMU cleanup by Roman Zippel**** Atari support by Andreas Schwab, using ideas of Robert de Vries** and Bjoern Brauel** VME Support by Richard Hirst**** 94/11/14 Andreas Schwab: put kernel at PAGESIZE** 94/11/18 Andreas Schwab: remove identity mapping of STRAM for Atari** ++ Bjoern & Roman: ATARI-68040 support for the Medusa** 95/11/18 Richard Hirst: Added MVME166 support** 96/04/26 Guenther Kelleter: fixed identity mapping for Falcon with** 			      Magnum- and FX-alternate ram** 98/04/25 Phil Blundell: added HP300 support** 1998/08/30 David Kilzer: Added support for fbcon_font_desc structures**            for linux-2.1.115** 9/02/11  Richard Zidlicky: added Q40 support (initial vesion 99/01/01) **** 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.***//* * Linux startup code. * * At this point, the boot loader has: * Disabled interrupts * Disabled caches * Put us in supervisor state. * * The kernel setup code takes the following steps: * .  Raise interrupt level * .  Set up initial kernel memory mapping. *    .  This sets up a mapping of the 4M of memory the kernel is located in. *    .  It also does a mapping of any initial machine specific areas. * .  Enable the MMU * .  Enable cache memories * .  Jump to kernel startup * * Much of the file restructuring was to accomplish: * 1) Remove register dependency through-out the file. * 2) Increase use of subroutines to perform functions * 3) Increase readability of the code * * Of course, readability is a subjective issue, so it will never be * argued that that goal was accomplished.  It was merely a goal. * A key way to help make code more readable is to give good * documentation.  So, the first thing you will find is exaustive * write-ups on the structure of the file, and the features of the * functional subroutines. * * General Structure: * ------------------ *	Without a doubt the single largest chunk of head.S is spent * mapping the kernel and I/O physical space into the logical range * for the kernel. *	There are new subroutines and data structures to make MMU * support cleaner and easier to understand. * 	First, you will find a routine call "mmu_map" which maps * a logical to a physical region for some length given a cache * type on behalf of the caller.  This routine makes writing the * actual per-machine specific code very simple. *	A central part of the code, but not a subroutine in itself, * is the mmu_init code which is broken down into mapping the kernel * (the same for all machines) and mapping machine-specific I/O * regions. *	Also, there will be a description of engaging the MMU and * caches. *	You will notice that there is a chunk of code which * can emit the entire MMU mapping of the machine.  This is present * only in debug modes and can be very helpful. *	Further, there is a new console driver in head.S that is * also only engaged in debug mode.  Currently, it's only supported * on the Macintosh class of machines.  However, it is hoped that * others will plug-in support for specific machines. * * ###################################################################### * * mmu_map * ------- *	mmu_map was written for two key reasons.  First, it was clear * that it was very difficult to read the previous code for mapping * regions of memory.  Second, the Macintosh required such extensive * memory allocations that it didn't make sense to propogate the * existing code any further. *	mmu_map requires some parameters: * *	mmu_map (logical, physical, length, cache_type) * *	While this essentially describes the function in the abstract, you'll * find more indepth description of other parameters at the implementation site. *  * mmu_get_root_table_entry * ------------------------ * mmu_get_ptr_table_entry * ----------------------- * mmu_get_page_table_entry * ------------------------ *  *	These routines are used by other mmu routines to get a pointer into * a table, if necessary a new table is allocated. These routines are working * basically like pmd_alloc() and pte_alloc() in <asm/pgtable.h>. The root * table needs of course only to be allocated once in mmu_get_root_table_entry, * so that here also some mmu specific initialization is done. The second page * at the start of the kernel (the first page is unmapped later) is used for * the kernel_pg_dir. It must be at a position known at link time (as it's used * to initialize the init task struct) and since it needs special cache * settings, it's the easiest to use this page, the rest of the page is used * for further pointer tables. * mmu_get_page_table_entry allocates always a whole page for page tables, this * means 1024 pages and so 4MB of memory can be mapped. It doesn't make sense * to manage page tables in smaller pieces as nearly all mappings have that * size. * * ###################################################################### * * * ###################################################################### * * mmu_engage * ---------- *	Thanks to a small helping routine enabling the mmu got quiet simple * and there is only one way left. mmu_engage makes a complete a new mapping * that only includes the absolute necessary to be able to jump to the final * postion and to restore the original mapping. * As this code doesn't need a transparent translation register anymore this * means all registers are free to be used by machines that needs them for * other purposes. * * ###################################################################### * * mmu_print * --------- *	This algorithm will print out the page tables of the system as * appropriate for an 030 or an 040.  This is useful for debugging purposes * and as such is enclosed in #ifdef MMU_PRINT/#endif clauses. * * ###################################################################### * * console_init * ------------ *	The console is also able to be turned off.  The console in head.S * is specifically for debugging and can be very useful.  It is surrounded by * #ifdef CONSOLE/#endif clauses so it doesn't have to ship in known-good * kernels.  It's basic algorithm is to determine the size of the screen * (in height/width and bit depth) and then use that information for * displaying an 8x8 font or an 8x16 (widthxheight).  I prefer the 8x8 for * debugging so I can see more good data.  But it was trivial to add support * for both fonts, so I included it. *	Also, the algorithm for plotting pixels is abstracted so that in * theory other platforms could add support for different kinds of frame * buffers.  This could be very useful. * * console_put_penguin * ------------------- *	An important part of any Linux bring up is the penguin and there's * nothing like getting the Penguin on the screen!  This algorithm will work * on any machine for which there is a console_plot_pixel. * * console_scroll * -------------- *	My hope is that the scroll algorithm does the right thing on the * various platforms, but it wouldn't be hard to add the test conditions * and new code if it doesn't. * * console_putc * ------------- * * ###################################################################### * *	Register usage has greatly simplified within head.S. Every subroutine * saves and restores all registers that it modifies (except it returns a * value in there of course). So the only register that needs to be initialized * is the stack pointer. * All other init code and data is now placed in the init section, so it will * be automatically freed at the end of the kernel initialization. * * ###################################################################### * * options * ------- *	There are many options availble in a build of this file.  I've * taken the time to describe them here to save you the time of searching * for them and trying to understand what they mean. * * CONFIG_xxx:	These are the obvious machine configuration defines created * during configuration.  These are defined in include/linux/autoconf.h. * * CONSOLE:	There is support for head.S console in this file.  This * console can talk to a Mac frame buffer, but could easily be extrapolated * to extend it to support other platforms. * * TEST_MMU:	This is a test harness for running on any given machine but * getting an MMU dump for another class of machine.  The classes of machines * that can be tested are any of the makes (Atari, Amiga, Mac, VME, etc.) * and any of the models (030, 040, 060, etc.). * *	NOTE:	TEST_MMU is NOT permanent!  It is scheduled to be removed *		When head.S boots on Atari, Amiga, Macintosh, and VME *		machines.  At that point the underlying logic will be *		believed to be solid enough to be trusted, and TEST_MMU *		can be dropped.  Do note that that will clean up the *		head.S code significantly as large blocks of #if/#else *		clauses can be removed. * * MMU_NOCACHE_KERNEL:	On the Macintosh platform there was an inquiry into * determing why devices don't appear to work.  A test case was to remove * the cacheability of the kernel bits. * * MMU_PRINT:	There is a routine built into head.S that can display the * MMU data structures.  It outputs its result through the serial_putc * interface.  So where ever that winds up driving data, that's where the * mmu struct will appear.  On the Macintosh that's typically the console. * * SERIAL_DEBUG:	There are a series of putc() macro statements * scattered through out the code to give progress of status to the * person sitting at the console.  This constant determines whether those * are used. * * DEBUG:	This is the standard DEBUG flag that can be set for building *		the kernel.  It has the effect adding additional tests into *		the code. * * FONT_6x11: * FONT_8x8: * FONT_8x16: *		In theory these could be determined at run time or handed *		over by the booter.  But, let's be real, it's a fine hard *		coded value.  (But, you will notice the code is run-time *		flexible!)  A pointer to the font's struct fbcon_font_desc *		is kept locally in Lconsole_font.  It is used to determine *		font size information dynamically. * * Atari constants: * USE_PRINTER:	Use the printer port for serial debug. * USE_SCC_B:	Use the SCC port A (Serial2) for serial debug. * USE_SCC_A:	Use the SCC port B (Modem2) for serial debug. * USE_MFP:	Use the ST-MFP port (Modem1) for serial debug. * * Macintosh constants: * MAC_SERIAL_DEBUG:	Turns on serial debug output for the Macintosh. * MAC_USE_SCC_A:	Use the SCC port A (modem) for serial debug. * MAC_USE_SCC_B:	Use the SCC port B (printer) for serial debug (default). */#include <linux/config.h>#include <linux/linkage.h>#include <linux/init.h>#include <asm/bootinfo.h>#include <asm/setup.h>#include <asm/entry.h>#include <asm/pgtable.h>#include <asm/page.h>#include "m68k_defs.h"#ifdef CONFIG_MAC#include <asm/machw.h>/* * Macintosh console support */#define CONSOLE/* * Macintosh serial debug support; outputs boot info to the printer *   and/or modem serial ports */#undef MAC_SERIAL_DEBUG/* * Macintosh serial debug port selection; define one or both; *   requires MAC_SERIAL_DEBUG to be defined */#define MAC_USE_SCC_A		/* Macintosh modem serial port */#define MAC_USE_SCC_B		/* Macintosh printer serial port */#endif	/* CONFIG_MAC */#undef MMU_PRINT#undef MMU_NOCACHE_KERNEL#define SERIAL_DEBUG#undef DEBUG/* * For the head.S console, there are three supported fonts, 6x11, 8x16 and 8x8. * The 8x8 font is harder to read but fits more on the screen. */#define FONT_8x8 	/* default *//* #define FONT_8x16 */	/* 2nd choice *//* #define FONT_6x11 */	/* 3rd choice */.globl SYMBOL_NAME(kernel_pg_dir).globl SYMBOL_NAME(availmem).globl SYMBOL_NAME(m68k_pgtable_cachemode).globl SYMBOL_NAME(m68k_supervisor_cachemode)#ifdef CONFIG_MVME16x.globl SYMBOL_NAME(mvme_bdid)#endif#ifdef CONFIG_Q40.globl SYMBOL_NAME(q40_mem_cptr)	#endif		CPUTYPE_040	= 1	/* indicates an 040 */CPUTYPE_060	= 2	/* indicates an 060 */CPUTYPE_0460	= 3	/* if either above are set, this is set */CPUTYPE_020	= 4	/* indicates an 020 *//* Translation control register */TC_ENABLE = 0x8000TC_PAGE8K = 0x4000TC_PAGE4K = 0x0000/* Transparent translation registers */TTR_ENABLE	= 0x8000	/* enable transparent translation */TTR_ANYMODE	= 0x4000	/* user and kernel mode access */TTR_KERNELMODE	= 0x2000	/* only kernel mode access */TTR_USERMODE	= 0x0000	/* only user mode access */TTR_CI		= 0x0400	/* inhibit cache */TTR_RW		= 0x0200	/* read/write mode */TTR_RWM		= 0x0100	/* read/write mask */TTR_FCB2	= 0x0040	/* function code base bit 2 */TTR_FCB1	= 0x0020	/* function code base bit 1 */TTR_FCB0	= 0x0010	/* function code base bit 0 */TTR_FCM2	= 0x0004	/* function code mask bit 2 */TTR_FCM1	= 0x0002	/* function code mask bit 1 */TTR_FCM0	= 0x0001	/* function code mask bit 0 *//* Cache Control registers */CC6_ENABLE_D	= 0x80000000	/* enable data cache (680[46]0) */CC6_FREEZE_D	= 0x40000000	/* freeze data cache (68060) */CC6_ENABLE_SB	= 0x20000000	/* enable store buffer (68060) */CC6_PUSH_DPI	= 0x10000000	/* disable CPUSH invalidation (68060) */CC6_HALF_D	= 0x08000000	/* half-cache mode for data cache (68060) */CC6_ENABLE_B	= 0x00800000	/* enable branch cache (68060) */CC6_CLRA_B	= 0x00400000	/* clear all entries in branch cache (68060) */CC6_CLRU_B	= 0x00200000	/* clear user entries in branch cache (68060) */CC6_ENABLE_I	= 0x00008000	/* enable instruction cache (680[46]0) */CC6_FREEZE_I	= 0x00004000	/* freeze instruction cache (68060) */CC6_HALF_I	= 0x00002000	/* half-cache mode for instruction cache (68060) */CC3_ALLOC_WRITE	= 0x00002000	/* write allocate mode(68030) */CC3_ENABLE_DB	= 0x00001000	/* enable data burst (68030) */CC3_CLR_D	= 0x00000800	/* clear data cache (68030) */CC3_CLRE_D	= 0x00000400	/* clear entry in data cache (68030) */CC3_FREEZE_D	= 0x00000200	/* freeze data cache (68030) */CC3_ENABLE_D	= 0x00000100	/* enable data cache (68030) */CC3_ENABLE_IB	= 0x00000010	/* enable instruction burst (68030) */CC3_CLR_I	= 0x00000008	/* clear instruction cache (68030) */CC3_CLRE_I	= 0x00000004	/* clear entry in instruction cache (68030) */CC3_FREEZE_I	= 0x00000002	/* freeze instruction cache (68030) */CC3_ENABLE_I	= 0x00000001	/* enable instruction cache (68030) *//* Miscellaneous definitions */PAGESIZE	= 4096PAGESHIFT	= 12ROOT_TABLE_SIZE	= 128PTR_TABLE_SIZE	= 128PAGE_TABLE_SIZE	= 64ROOT_INDEX_SHIFT = 25PTR_INDEX_SHIFT  = 18PAGE_INDEX_SHIFT = 12#ifdef DEBUG/* When debugging use readable names for labels */#ifdef __STDC__#define L(name) .head.S.##name#else#define L(name) .head.S./**/name#endif#else#ifdef __STDC__#define L(name) .L##name#else#define L(name) .L/**/name#endif#endif/* The __INITDATA stuff is a no-op when ftrace or kgdb are turned on */#ifndef __INITDATA#define __INITDATA	.data#define __FINIT		.previous#endif/* Several macros to make the writing of subroutines easier: * - func_start marks the beginning of the routine which setups the frame *   register and saves the registers, it also defines another macro *   to automatically restore the registers again. * - func_return marks the end of the routine and simply calls the prepared *   macro to restore registers and jump back to the caller. * - func_define generates another macro to automatically put arguments *   onto the stack call the subroutine and cleanup the stack again. *//* Within subroutines these macros can be used to access the arguments * on the stack. With STACK some allocated memory on the stack can be * accessed and ARG0 points to the return address (used by mmu_engage). */#define	STACK	%a6@(stackstart)#define ARG0	%a6@(4)#define ARG1	%a6@(8)#define ARG2	%a6@(12)#define ARG3	%a6@(16)#define ARG4	%a6@(20).macro	func_start	name,saveregs,stack=0L(\name):	linkw	%a6,#-\stack	moveml	\saveregs,%sp@-.set	stackstart,-\stack	.macro	func_return_\name	moveml	%sp@+,\saveregs	unlk	%a6	rts.endm.endm.macro	func_return	name	func_return_\name.endm.macro	func_call	name	jbsr	L(\name).endm.macro	move_stack	nr,arg1,arg2,arg3,arg4.if	\nr	move_stack	"(\nr-1)",\arg2,\arg3,\arg4	movel	\arg1,%sp@-.endif.endm.macro	func_define	name,nr=0.macro	\name	arg1,arg2,arg3,arg4	move_stack	\nr,\arg1,\arg2,\arg3,\arg4	func_call	\name.if	\nr	lea	%sp@(\nr*4),%sp.endif.endm.endmfunc_define	mmu_map,4func_define	mmu_map_tt,4func_define	mmu_fixup_page_mmu_cache,1func_define	mmu_temp_map,2func_define	mmu_engagefunc_define	mmu_get_root_table_entry,1func_define	mmu_get_ptr_table_entry,2func_define	mmu_get_page_table_entry,2func_define	mmu_printfunc_define	get_new_page#ifdef CONFIG_HP300func_define	set_leds#endif.macro	mmu_map_eq	arg1,arg2,arg3	mmu_map	\arg1,\arg1,\arg2,\arg3.endm.macro	get_bi_record	record	pea	\record	func_call	get_bi_record	addql	#4,%sp.endmfunc_define	serial_putc,1func_define	console_putc,1.macro	putc	ch#if defined(CONSOLE) || defined(SERIAL_DEBUG)	pea	\ch#endif#ifdef CONSOLE	func_call	console_putc#endif#ifdef SERIAL_DEBUG	func_call	serial_putc#endif#if defined(CONSOLE) || defined(SERIAL_DEBUG)	addql	#4,%sp#endif.endm.macro	dputc	ch#ifdef DEBUG	putc	\ch#endif.endmfunc_define	putn,1.macro	dputn	nr#ifdef DEBUG	putn	\nr#endif.endm.macro	puts		string#if defined(CONSOLE) || defined(SERIAL_DEBUG)	__INITDATA.Lstr\@:	.string	"\string"	__FINIT	pea	%pc@(.Lstr\@)	func_call	puts	addql	#4,%sp#endif.endm.macro	dputs	string#ifdef DEBUG	puts	"\string"#endif.endm#define is_not_amiga(lab) cmpl &MACH_AMIGA,%pc@(m68k_machtype); jne lab#define is_not_atari(lab) cmpl &MACH_ATARI,%pc@(m68k_machtype); jne lab#define is_not_mac(lab) cmpl &MACH_MAC,%pc@(m68k_machtype); jne lab#define is_not_mvme147(lab) cmpl &MACH_MVME147,%pc@(m68k_machtype); jne lab#define is_not_mvme16x(lab) cmpl &MACH_MVME16x,%pc@(m68k_machtype); jne lab#define is_not_bvme6000(lab) cmpl &MACH_BVME6000,%pc@(m68k_machtype); jne lab#define is_mvme147(lab) cmpl &MACH_MVME147,%pc@(m68k_machtype); jeq lab#define is_mvme16x(lab) cmpl &MACH_MVME16x,%pc@(m68k_machtype); jeq lab#define is_bvme6000(lab) cmpl &MACH_BVME6000,%pc@(m68k_machtype); jeq lab#define is_not_hp300(lab) cmpl &MACH_HP300,%pc@(m68k_machtype); jne lab#define is_not_apollo(lab) cmpl &MACH_APOLLO,%pc@(m68k_machtype); jne lab#define is_not_q40(lab) cmpl &MACH_Q40,%pc@(m68k_machtype); jne lab#define is_not_sun3x(lab) cmpl &MACH_SUN3X,%pc@(m68k_machtype); jne lab

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -