您的位置:首页 > 其它

整理一下最近的笔记

2007-07-02 23:59 323 查看
[linux kernel porting]

说实话,内核移植这块确实太深奥了,自己最近在搞移植,所以找了些资料看,很多自己不明白,当时做了笔记,希望以后可以一一搞懂吧;






/**//**********************************************************************************************************


* @Description: linux内核移植相关源代码分析


*


* @Author: liyangth@gmail.com


*


* @Changelog:


* 2007-05-30 LiYang First Version


*


* @FQA:


* [0%]Q1:


**********************************************************************************************************/


Porting Linux




基本原则和方法:


1 理解OS中硬件相关的部分


1.1Linux 硬件相关源码


1.1.1ARM-specific files


|--arch


| |--arm


| | |--kernel //- core kernel code;


| | |--mm //- memory management code;


| | |--lib //- ARM-specific or optimised internal library functions


| | | (backtrace,memcpy, io functions, bit-twiddling etc);


| | |--nwfpe and fastfpe //- two different floating-point


| | | implementations;


| | |--boot //- the directory in which the final compiled


| | | kernel is left and contains stuff for generating


| | | compressed kernels;


| | |--tools //- has scripts for autogenerating files, such


| | | as mach-types (see Registering a Machine ID);


| | |


| | |--def-configs //- contains the default configuration


| | | files for each machine.


| | |


| | |--mach-xxx //具体的体系架构SOC的相关部分


|


|--include


| |--asm-arm


| | |--arch //- the link to the configured machine headers sub-


| | | directory arch-XXX;


| | |--hardware //- headers for ARM-specific companion chips or


| | | devices;


| | |--mach //- generic interface definitions for things used by many


| | | machines (irq, dma, pci) and the machine description macros


| | |--proc //- link to proc-armo or proc-armv appropriate for


| | | configured machine


| | |--proc-armo, and proc-armv - 26 and 32-bit versions of core


| | | processor-related headers.


| | |


| | |--arch-xxx


|


|--drivers






1.1.1.1ARM-specific files in linux/arch/arm




2 理解所要移植的硬件


3 理解移植的关键部分










***************************************************************


注册机器 ID(Register Machine ID)


Name: <name of your architecture>


ArchDir: <name of include/asm-arm/arch-* directory>


Type:<MACH_TYPE_* macro name>


Description: <description of your architecture>

http://www.armlinux.org.uk/developer/machines/.

rmk@arm.linux.org.uk


Add info to linux/arch/arm/tools/mach-types




修改或增加代码


******************************************************************


arch/arm/Makefile


Insert the following to this file (replace XXX with your


machine name):




ifeq ((CONFIG_ARCH_XXX),y)


MACHINE = xxx


endif




[LiY]在make menuconfig时


1.arch/arm/Kconfig


mainmenu "Linux Kernel Configuration"


|--menu "System Type"


| |-config ARCH_S2S65A


| | bool "S2S65A00"




[0%]2.arch/arm/Makefile


textaddr-$(CONFIG_ARCH_S2S65A) := 0xc0008000


machine-$(CONFIG_ARCH_S2S65A) := s2s65a00




[Q1]drivers/下的驱动编译时在Makefile中都是obj-$() :=


在这里machine-$()是什么意思?


[Q2]textaddr是编译S2S65A机器的text section在0xc0008000这个处么?






******************************************************************


arch/arm/boot/Makefile


Here you specify ZTEXTADDR, the start address of the


kernel decompressor.This should have the same value as


the address to which Linux is uploaded in your boot loader.


This is normally 32K (0x8000) above the base of RAM.


The space between the start of RAM and the kernel is used


for page tables.


ifeq ((CONFIG_ARCH_XXX),y)


ZTEXTADDR = 0xXXXX8000


endif




[LiY]


1:ZTEXTADDR-- 内核解压后的起始地址


2:


*****************************************************************


arch/arm/kernel/entry-armv.S


Machine-specific IRQ functions. You provide the assembly


macros disable_fiq, get_irqnr_and_base, and


irq_prio_table here. disable_fiq and irq_prio_table is


usually empty, but get_irqnr_and_base must be


implemented carefully: you should use the zero flag to


indicate the presence of interrupts, and put the correct IRQ


number in irqnr.




[LiY]


[0%]get_irqnr_and_base?


********************************************************************


arch/arm/kernel/debug-armv.S


These are the low-level debug functions, which talk to a


serial port without relying on interrupts or any other kernel


functionality. You'll need to use these functions if it won't


boot. The functions you need to implement are addruart,


senduart and waituart, using ARM assembly. They give


you the address of the debug UART, send a byte to the


debug UART, and wait for the debug UART, respectively.






******************************************************************


arch/arm/mach-XXX/Makefile


You need to add a target for your machine, listing the


object files in this directory.That will be at least the


following:


+O_TARGET := MACHINE.o


+obj-y := arch.o irq.o mm.o






***************************************************************


arch/arm/mach-XXX/arch.c


This should contain the architecture-specific fix ups and IO


initialisations. (The latter used to go in arch/arm/mach-


XXX/mm.c but that file is now deprecated).




static void __init


fixup_XXX(struct machine_desc *desc, struct param_


struct *params,char **cmdline, struct meminfo *mi)




...{


ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);


setup_ramdisk(1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE);


setup_initrd(0xc0800000, X * 1024 * 1024);


}






MACHINE_START(ANAKIN, "XXX")


MAINTAINER("Acunia N.V.")


BOOT_MEM(XXX, YYY, ZZZ)


VIDEO(VVV, WWW)


FIXUP(fixup_XXX)


MAPIO(XXX_map_io)


INITIRQ(genarch_init_irq)


MACHINE_END




[LiY]


@arch/arm/mach-s2s65a00/s2s65a.c


| MACHINE_START(S2S65A, "S2S65A")




/**//* Maintainer: Nobody */


.phys_ram = 0x40000000, //SDRAM(64MB x 2)起始地址;


.phys_io = 0xfff00000, //io起始地址;


.fixup = fixup_s2s65a, //修正,没有实现;


.map_io = s2s65a_map_io, //io和mem地址的初始化;


.init_irq = s2s65a_init_irq, //


.timer = &s2s65a_timer,


MACHINE_END


|






**************************************************************************


arch/arm/mach-XXX/irq.c


You should provide the XXX_init_irq function here. This


sets up the interrupt controller. Interrupt mask and unmask


functions go here too.






@arch/arm/mach-s2s65a00/irq.c


|


|


void __init s2s65a_init_irq(void)




...{


unsigned int i;




for (i = 0; i < NR_IRQS; i++)




...{


set_irq_handler(i, do_level_IRQ);


set_irq_chip(i, &s2s65a_int_chip);


set_irq_flags(i, IRQF_VALID | IRQF_PROBE);




}




/**//*


* Disable interrupts


*/


__raw_writel(0xffffffff, IRQ_ENABLECLR_REG);


__raw_writel(0x3, FIQ_ENABLECLR_REG);




/**//*


* Clear down any pending interrupts


*/




}


|


|




**************************************************************************


arch/arm/mach-XXX/mm.c


This file is now deprecated. Its content (IO initialisation)


has moved into arch/arm/mach-XXX/arch.c






@arch/arm/mach-s2s65a00/mm.c


|1.


|填充struct map_desc类的对象s2s65a_io_desc;


|


|2.实现s2s65a_map_io给s2s65a.c中的MACHINE_START用;


|s2s65a_map_io


| |-iotable_init(s2s65a_io_desc,ARRAY_SIZE(s2s65a_io_desc));




@arch/arm/mm/mm-armv.c


|




|/**//*


* Create the page directory entries and any necessary


* page tables for the mapping specified by `md'. We


* are able to cope here with varying sizes and address


* offsets, and we take full advantage of sections and


* supersections.


*/


static void __init create_mapping(struct map_desc *md)


|




|/**//*


* Create the architecture specific mappings


*/


void __init iotable_init(struct map_desc *io_desc, int nr)




...{


int i;




for (i = 0; i < nr; i++)


create_mapping(io_desc + i);


}


|


|






**************************************************************************


include/asm/arch/dma.h


Defines for DMA channels, and DMA-able areas of memory. For


machines without DMA, you can just declare 0 DMA channels as


follows:


#define MAX_DMA_ADDRESS 0xffffffff


#define MAX_DMA_CHANNELS 0




**************************************************************************


include/asm/arch/hardware.h


In this file, you need to define the memory addresses, IO


addresses, and so on, according to your hardware


specifications (memory map and IO map). The _START


addresses are the physical addresses, the _BASE addresses


are the virtual adresses to which each memory or IO region


will be mapped. Refer to other similar machines for


examples.




[LiY]定义板子上所有资源的地址,根据手册;


[Q1]_BASE address are the virtual address to which each memory or IO region will be mapped.








**************************************************************************


include/asm/arch/io.h


Here you define the macros IO_SPACE_LIMIT (as 0xffffffff),


__io(addr),__arch_getw(addr),__arch_putw(data,addr),


and other related macros, according to your CPU. For CPUs


that already have an implementation (for example Intel®


SA-1110 Processor and Intel® XScale™ Microarchitecture),


you can just copy it across and/or reuse the existing io.h for


that CPU.






**************************************************************************


include/asm/arch/irq.h


Here you need to provide the fixup_irq macro. In almost all


cases, this is just a direct mapping:


#define fixup_irq(i) i




**************************************************************************


include/asm/arch/irqs.h


In this file you will define all your IRQ numbers. For example:


#define IRQ_UART0 0










**************************************************************************


include/asm/arch/keyboard.h


This file is typically here to cheat the VT driver into thinking


that there is a null keyboard. Most ARM devices don't have a


real one. If you do this is where to put the keyboard IO


defines and structs.










**************************************************************************


include/asm/arch/memory.h


Unless you have an exotic memory-map this is platforminvariant


and you can copy this from other implementations.






**************************************************************************


include/asm/arch/param.h


This is included by asm/param.h. Here you can redefine HZ


(default 100),NGROUPS (default -1), and MAXHOSTNAMELEN


(default 64). If you are okay with the above defaults, you


still need to create this file but you can make it an empty file


(like the Anakin port).










[0%]**************************************************************************


include/asm/arch/system.h


This file is included by arch/arm/kernel/process.c.You are


required to define arch_idle() and arch_reset() functions.


arch_idle() is called whenever the machine has no other


process to run - i.e. it's time to sleep. arch_reset() is called


on system reset.The actual implementation of these functions


depends on your specific hardware, and there are some subtleties


associated with arch_idle(). This function will normally


put the hardware of your specific device into a lowpower


mode and then call the generic cpu function cpu_do_idle to do the


same thing for the cpu.






static inline void arch_idle(void)




...{




/**//*


Please check include/asm/proc-fns.h, include/asm/cpu-*.h and


arch/arm/mm/proc-*.S. In particular, cpu_do_idle is * a macro expanding


into cpu_XXX_do_idle, where XXX is the CPU configuration, e.g.


arm920, sa110, xs80200, etc.


*/


cpu_do_idle(IDLE_WAIT_SLOW);


}






static inline void arch_reset(char mode)




...{




switch (mode) ...{


case 's':




/**//* Software reset (jump to address 0) */


cpu_reset(0);


break;


case 'h':




/**//* TODO: hardware reset */


}


}




[0%]**************************************************************************


include/asm/arch/time.h


Here you have to supply your timer interrupt handler and related


functions. See the template below:




/**//* XXX_gettimeoffset is not mandatory.*/


static unsigned long XXX_gettimeoffset(void)




...{




/**//* Return number of microseconds since last interrupt


*/


}




static void XXX_timer_interrupt(int irq, void *dev_id,


struct


pt_regs *regs)




...{/**//* Add hardware specific stuffs, if applicable */


do_timer(regs);


do_profile (regs);


}




extern inline void setup_timer(void)




...{


gettimeoffset = XXX_gettimeoffset;


timer_irq.handler = XXX_timer_interrupt;


setup_arm_irq(IRQ_XXX, &timer_irq);




/**//* Other hardware specific setups */


}






**************************************************************************


include/asm/arch/timex.h


This file is included by include/asm/timex.h, which is in turn


included by include/linux/timex.h. Basically you need to


define your clock rate here. For example, for Anakin it is 1/8ms:


#define CLOCK_TICK_RATE 1000 / 8






**************************************************************************


include/asm/arch/uncompress.h


This file is included by arch/arm/boot/compressed/misc.c


(which, among other things, outputs the Uncompressing


Linux message). You are required to provide two functions,


arch_decomp_setup to setup the UART, and puts for outputting


the decompression message to the UART:


static void_puts(char char *s)




/**//*


* Hardware-specific routine to put a string to the debug


* UART, converting " " to " " on the way.


*/


static inline void arch_decomp_setup(void)




/**//* Hardware-specific routine to put a string to setup the


* UART mentioned above.


*/




/**//* Watchdog is not used for most ARM Linux implementations


*/


#define arch_decomp_wdog()






**************************************************************************


include/asm/arch/vmalloc.h


This file is largely invariant across platforms, so you can just


copy it from other ARM architectures without worrying too


much.
















***********************Reference*****************


The ARM Linux Project –

http://www.arm.linux.org.uk/

Linux Console Project –

http://sourceforge.net/projects/linuxconsole/

Linux Framebuffer Driver Writing HOWTO –

http://www.linux-fbdev.org/HOWTO/


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: