Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.16-rc4 306 lines 12 kB view raw
1 2 Adding a new board to LinuxSH 3 ================================ 4 5 Paul Mundt <lethal@linux-sh.org> 6 7This document attempts to outline what steps are necessary to add support 8for new boards to the LinuxSH port under the new 2.5 and 2.6 kernels. This 9also attempts to outline some of the noticeable changes between the 2.4 10and the 2.5/2.6 SH backend. 11 121. New Directory Structure 13========================== 14 15The first thing to note is the new directory structure. Under 2.4, most 16of the board-specific code (with the exception of stboards) ended up 17in arch/sh/kernel/ directly, with board-specific headers ending up in 18include/asm-sh/. For the new kernel, things are broken out by board type, 19companion chip type, and CPU type. Looking at a tree view of this directory 20heirarchy looks like the following: 21 22Board-specific code: 23 24. 25|-- arch 26| `-- sh 27| `-- boards 28| |-- adx 29| | `-- board-specific files 30| |-- bigsur 31| | `-- board-specific files 32| | 33| ... more boards here ... 34| 35`-- include 36 `-- asm-sh 37 |-- adx 38 | `-- board-specific headers 39 |-- bigsur 40 | `-- board-specific headers 41 | 42 .. more boards here ... 43 44It should also be noted that each board is required to have some certain 45headers. At the time of this writing, io.h is the only thing that needs 46to be provided for each board, and can generally just reference generic 47functions (with the exception of isa_port2addr). 48 49Next, for companion chips: 50. 51`-- arch 52 `-- sh 53 `-- cchips 54 `-- hd6446x 55 |-- hd64461 56 | `-- cchip-specific files 57 `-- hd64465 58 `-- cchip-specific files 59 60... and so on. Headers for the companion chips are treated the same way as 61board-specific headers. Thus, include/asm-sh/hd64461 is home to all of the 62hd64461-specific headers. 63 64Finally, CPU family support is also abstracted: 65. 66|-- arch 67| `-- sh 68| |-- kernel 69| | `-- cpu 70| | |-- sh2 71| | | `-- SH-2 generic files 72| | |-- sh3 73| | | `-- SH-3 generic files 74| | `-- sh4 75| | `-- SH-4 generic files 76| `-- mm 77| `-- This is also broken out per CPU family, so each family can 78| have their own set of cache/tlb functions. 79| 80`-- include 81 `-- asm-sh 82 |-- cpu-sh2 83 | `-- SH-2 specific headers 84 |-- cpu-sh3 85 | `-- SH-3 specific headers 86 `-- cpu-sh4 87 `-- SH-4 specific headers 88 89It should be noted that CPU subtypes are _not_ abstracted. Thus, these still 90need to be dealt with by the CPU family specific code. 91 922. Adding a New Board 93===================== 94 95The first thing to determine is whether the board you are adding will be 96isolated, or whether it will be part of a family of boards that can mostly 97share the same board-specific code with minor differences. 98 99In the first case, this is just a matter of making a directory for your 100board in arch/sh/boards/ and adding rules to hook your board in with the 101build system (more on this in the next section). However, for board families 102it makes more sense to have a common top-level arch/sh/boards/ directory 103and then populate that with sub-directories for each member of the family. 104Both the Solution Engine and the hp6xx boards are an example of this. 105 106After you have setup your new arch/sh/boards/ directory, remember that you 107also must add a directory in include/asm-sh for headers localized to this 108board. In order to interoperate seamlessly with the build system, it's best 109to have this directory the same as the arch/sh/boards/ directory name, 110though if your board is again part of a family, the build system has ways 111of dealing with this, and you can feel free to name the directory after 112the family member itself. 113 114There are a few things that each board is required to have, both in the 115arch/sh/boards and the include/asm-sh/ heirarchy. In order to better 116explain this, we use some examples for adding an imaginary board. For 117setup code, we're required at the very least to provide definitions for 118get_system_type() and platform_setup(). For our imaginary board, this 119might look something like: 120 121/* 122 * arch/sh/boards/vapor/setup.c - Setup code for imaginary board 123 */ 124#include <linux/init.h> 125 126const char *get_system_type(void) 127{ 128 return "FooTech Vaporboard"; 129} 130 131int __init platform_setup(void) 132{ 133 /* 134 * If our hardware actually existed, we would do real 135 * setup here. Though it's also sane to leave this empty 136 * if there's no real init work that has to be done for 137 * this board. 138 */ 139 140 /* 141 * Presume all FooTech boards have the same broken timer, 142 * and also presume that we've defined foo_timer_init to 143 * do something useful. 144 */ 145 board_time_init = foo_timer_init; 146 147 /* Start-up imaginary PCI ... */ 148 149 /* And whatever else ... */ 150 151 return 0; 152} 153 154Our new imaginary board will also have to tie into the machvec in order for it 155to be of any use. Currently the machvec is slowly on its way out, but is still 156required for the time being. As such, let us take a look at what needs to be 157done for the machvec assignment. 158 159machvec functions fall into a number of categories: 160 161 - I/O functions to IO memory (inb etc) and PCI/main memory (readb etc). 162 - I/O remapping functions (ioremap etc) 163 - some initialisation functions 164 - a 'heartbeat' function 165 - some miscellaneous flags 166 167The tree can be built in two ways: 168 - as a fully generic build. All drivers are linked in, and all functions 169 go through the machvec 170 - as a machine specific build. In this case only the required drivers 171 will be linked in, and some macros may be redefined to not go through 172 the machvec where performance is important (in particular IO functions). 173 174There are three ways in which IO can be performed: 175 - none at all. This is really only useful for the 'unknown' machine type, 176 which us designed to run on a machine about which we know nothing, and 177 so all all IO instructions do nothing. 178 - fully custom. In this case all IO functions go to a machine specific 179 set of functions which can do what they like 180 - a generic set of functions. These will cope with most situations, 181 and rely on a single function, mv_port2addr, which is called through the 182 machine vector, and converts an IO address into a memory address, which 183 can be read from/written to directly. 184 185Thus adding a new machine involves the following steps (I will assume I am 186adding a machine called vapor): 187 188 - add a new file include/asm-sh/vapor/io.h which contains prototypes for 189 any machine specific IO functions prefixed with the machine name, for 190 example vapor_inb. These will be needed when filling out the machine 191 vector. 192 193 This is the minimum that is required, however there are ample 194 opportunities to optimise this. In particular, by making the prototypes 195 inline function definitions, it is possible to inline the function when 196 building machine specific versions. Note that the machine vector 197 functions will still be needed, so that a module built for a generic 198 setup can be loaded. 199 200 - add a new file arch/sh/boards/vapor/mach.c. This contains the definition 201 of the machine vector. When building the machine specific version, this 202 will be the real machine vector (via an alias), while in the generic 203 version is used to initialise the machine vector, and then freed, by 204 making it initdata. This should be defined as: 205 206 struct sh_machine_vector mv_vapor __initmv = { 207 .mv_name = "vapor", 208 } 209 ALIAS_MV(vapor) 210 211 - finally add a file arch/sh/boards/vapor/io.c, which contains 212 definitions of the machine specific io functions. 213 214A note about initialisation functions. Three initialisation functions are 215provided in the machine vector: 216 - mv_arch_init - called very early on from setup_arch 217 - mv_init_irq - called from init_IRQ, after the generic SH interrupt 218 initialisation 219 - mv_init_pci - currently not used 220 221Any other remaining functions which need to be called at start up can be 222added to the list using the __initcalls macro (or module_init if the code 223can be built as a module). Many generic drivers probe to see if the device 224they are targeting is present, however this may not always be appropriate, 225so a flag can be added to the machine vector which will be set on those 226machines which have the hardware in question, reducing the probe to a 227single conditional. 228 2293. Hooking into the Build System 230================================ 231 232Now that we have the corresponding directories setup, and all of the 233board-specific code is in place, it's time to look at how to get the 234whole mess to fit into the build system. 235 236Large portions of the build system are now entirely dynamic, and merely 237require the proper entry here and there in order to get things done. 238 239The first thing to do is to add an entry to arch/sh/Kconfig, under the 240"System type" menu: 241 242config SH_VAPOR 243 bool "Vapor" 244 help 245 select Vapor if configuring for a FooTech Vaporboard. 246 247next, this has to be added into arch/sh/Makefile. All boards require a 248machdir-y entry in order to be built. This entry needs to be the name of 249the board directory as it appears in arch/sh/boards, even if it is in a 250sub-directory (in which case, all parent directories below arch/sh/boards/ 251need to be listed). For our new board, this entry can look like: 252 253machdir-$(CONFIG_SH_VAPOR) += vapor 254 255provided that we've placed everything in the arch/sh/boards/vapor/ directory. 256 257Next, the build system assumes that your include/asm-sh directory will also 258be named the same. If this is not the case (as is the case with multiple 259boards belonging to a common family), then the directory name needs to be 260implicitly appended to incdir-y. The existing code manages this for the 261Solution Engine and hp6xx boards, so see these for an example. 262 263Once that is taken care of, it's time to add an entry for the mach type. 264This is done by adding an entry to the end of the arch/sh/tools/mach-types 265list. The method for doing this is self explanatory, and so we won't waste 266space restating it here. After this is done, you will be able to use 267implicit checks for your board if you need this somewhere throughout the 268common code, such as: 269 270 /* Make sure we're on the FooTech Vaporboard */ 271 if (!mach_is_vapor()) 272 return -ENODEV; 273 274also note that the mach_is_boardname() check will be implicitly forced to 275lowercase, regardless of the fact that the mach-types entries are all 276uppercase. You can read the script if you really care, but it's pretty ugly, 277so you probably don't want to do that. 278 279Now all that's left to do is providing a defconfig for your new board. This 280way, other people who end up with this board can simply use this config 281for reference instead of trying to guess what settings are supposed to be 282used on it. 283 284Also, as soon as you have copied over a sample .config for your new board 285(assume arch/sh/configs/vapor_defconfig), you can also use this directly as a 286build target, and it will be implicitly listed as such in the help text. 287 288Looking at the 'make help' output, you should now see something like: 289 290Architecture specific targets (sh): 291 zImage - Compressed kernel image (arch/sh/boot/zImage) 292 adx_defconfig - Build for adx 293 cqreek_defconfig - Build for cqreek 294 dreamcast_defconfig - Build for dreamcast 295... 296 vapor_defconfig - Build for vapor 297 298which then allows you to do: 299 300$ make ARCH=sh CROSS_COMPILE=sh4-linux- vapor_defconfig vmlinux 301 302which will in turn copy the defconfig for this board, run it through 303oldconfig (prompting you for any new options since the time of creation), 304and start you on your way to having a functional kernel for your new 305board. 306