Difference between revisions of "HowTo Build Your Own Custom Kernel"
(unpacking, patching, and configuring kernel sources) |
(→Links: correct link to "Buffalo ARM9 Kernel Port", which is in the same wiki section) |
||
(20 intermediate revisions by 2 users not shown) | |||
Line 3: | Line 3: | ||
There are two ways to build a custom kernel for the LinkStation/Kurobox. If you have access to an i686 host running some flavor of Linux, you can '''cross-compile''' a kernel for ARM9 on an i686 host. Alternatively, if your NAS has enough RAM, you could compile the kernel on the NAS itself, using the system's native '''gcc'''. Both ways of these approaches to building a custom kernel are described in the instructions that follow. | There are two ways to build a custom kernel for the LinkStation/Kurobox. If you have access to an i686 host running some flavor of Linux, you can '''cross-compile''' a kernel for ARM9 on an i686 host. Alternatively, if your NAS has enough RAM, you could compile the kernel on the NAS itself, using the system's native '''gcc'''. Both ways of these approaches to building a custom kernel are described in the instructions that follow. | ||
− | == Cross-compiling a | + | == Cross-compiling a Kernel == |
=== Download All the Required Tarballs === | === Download All the Required Tarballs === | ||
Line 83: | Line 83: | ||
cd /usr/src | cd /usr/src | ||
tar -xvjf /wherever/i/downloaded/linux-2.6.22_lsp.3.0.5.tar.bz2 | tar -xvjf /wherever/i/downloaded/linux-2.6.22_lsp.3.0.5.tar.bz2 | ||
− | ln -s linux-2.6.22_lsp.3.0.5 | + | ln -s linux-2.6.22_lsp.3.0.5 linux |
− | (That '''ln -s''' is | + | (That '''ln -s''' is optional, of course, and just for convenience.) |
− | Now that you've unpacked the source, a small change needs to be made to the main Makefile. Since the Makefile was written for cross-compilation, you need to comment out some lines and uncomment others | + | Now that you've unpacked the source, a small change needs to be made to the main '''Makefile'''. Since the Makefile was written for cross-compilation, you need to comment out some lines and uncomment others: |
#ARCH ?= $(SUBARCH) | #ARCH ?= $(SUBARCH) | ||
CROSS_COMPILE ?= | CROSS_COMPILE ?= | ||
Line 95: | Line 95: | ||
//#if 0 | //#if 0 | ||
#ifdef CONFIG_BUFFALO_LINKSTATION_LSGL | #ifdef CONFIG_BUFFALO_LINKSTATION_LSGL | ||
− | (Why did they put ''# | + | (Why did they put ''#if 0'' in there? Who knows? Just comment it out.) |
+ | |||
+ | You also have to swap two pairs of lines in '''block/ll_rw_blk.c''', so that it ends up looking like this: | ||
+ | |||
+ | <pre> | ||
+ | if (!uptodate) { | ||
+ | if (blk_fs_request(req) && !(req->cmd_flags & REQ_QUIET)) | ||
+ | printk("end_request: I/O error, dev %s, sector %llu\n", | ||
+ | req->rq_disk ? req->rq_disk->disk_name : "?", | ||
+ | (unsigned long long)req->sector); | ||
+ | if(req->rq_disk){ | ||
+ | #ifdef CONFIG_BUFFALO_ERRCNT | ||
+ | if(atomic_inc_return(&req->rq_disk->nr_errs) < 0) | ||
+ | atomic_set(&req->rq_disk->nr_errs, INT_MAX); | ||
+ | #endif /* CONFIG_BUFFALO_ERRCNT */ | ||
+ | #ifdef CONFIG_BUFFALO_PLATFORM | ||
+ | // end_request: I/O error, dev sda, sector 16 | ||
+ | { | ||
+ | //char str[32]; | ||
+ | //sprintf(str,"%02x:%02x",req->rq_disk->major,req->rq_disk->minors); | ||
+ | kernevnt_IOErr(req->rq_disk->disk_name /*str*/, (rq_data_dir(req)==WRITE)? "WRITE":"READ", req->sector, ++req->rq_disk->io_errors); | ||
+ | } | ||
+ | #endif | ||
+ | } | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | ''(Why does Buffalo publish incomplete, broken, code? I don't know. They're technically required by the GPL to publish source for their modifications, yet the code released clearly isn't the complete code they used to build their kernels. Is this a violation of the GPL? I'll give you a chance to compile their code, and let you decide for yourself...)'' | ||
+ | |||
+ | === Peek at the LspReadme.txt === | ||
+ | |||
+ | In the top level directory of the kernel source, there should be a file '''LspReadme.txt'''. This file contains all sorts of great information about the Buffalo kernel. You may want to look through it before you configure your kernel. | ||
=== Configuring the Kernel === | === Configuring the Kernel === | ||
− | Next, you'll want to pre-configure the kernel with the | + | Next, you'll want to pre-configure the kernel with the default .config for your NAS. Assuming you have an LS-GL or LS-CL, which are based on the mv88f5182 chip: |
cd /usr/src/linux | cd /usr/src/linux | ||
make mv88f5182_defconfig | make mv88f5182_defconfig | ||
That will copy the default Buffalo config file (arch/arm/configs/mv88f5182_defconfig) to '''.config'''. | That will copy the default Buffalo config file (arch/arm/configs/mv88f5182_defconfig) to '''.config'''. | ||
− | Now, | + | Now, you have to configure the kernel. |
make menuconfig | make menuconfig | ||
− | For some reason, the default config has CONFIG_BLK_DEV_INITRD and CONFIG_BLK_DEV_RAM disabled, and CONFIG_SYSFS_DEPRECATED and CONFIG_LEGACY_PTYS enabled. So, poke around for those options and change them. | + | For some reason, the default .config has CONFIG_BLK_DEV_INITRD and CONFIG_BLK_DEV_RAM disabled, and CONFIG_SYSFS_DEPRECATED and CONFIG_LEGACY_PTYS enabled. So, poke around for those options and change them. When you're done, somewhere in your .config file, you should have each of these lines: |
CONFIG_BLK_DEV_INITRD=y | CONFIG_BLK_DEV_INITRD=y | ||
CONFIG_BLK_DEV_RAM=y | CONFIG_BLK_DEV_RAM=y | ||
# CONFIG_SYSFS_DEPRECATED is not set | # CONFIG_SYSFS_DEPRECATED is not set | ||
# CONFIG_LEGACY_PTYS is not set | # CONFIG_LEGACY_PTYS is not set | ||
+ | The default .config also comes with a large number of Buffalo configuration variables unset. The kernel will probably compile if you use these settings: | ||
+ | CONFIG_BUFFALO_PLATFORM=y | ||
+ | CONFIG_BUFFALO_SOFT_BOARDID=y | ||
+ | CONFIG_USE_RS5C372=y | ||
+ | CONFIG_BUFFALO_USE_INTERRUPT_DRIVER=y | ||
+ | CONFIG_BUFFALO_USE_GPIO_DRIVER=y | ||
+ | CONFIG_BUFFALO_SUPPORT_BOARD_INFO=y | ||
+ | (In fact, using those was the only way I could get the kernel to compile. Finding this combination took some trial and error, because the Buffalo Kconfig files don't contain proper dependency information for these config variables.) | ||
+ | |||
+ | The default .config also has an incorrect value for CONFIG_MV_ETH_NAME. CONFIG_MV_ETH_NAME should be set as follows: | ||
+ | CONFIG_MV_ETH_NAME="eth" | ||
+ | The default value for this variable ("egiga") makes the first ethernet device on the LS appear as '''egiga0'''. Since most alternative distributions and initrds assume that the first ethernet device is '''eth0''', your NAS probably won't be accessible from the network unless you change this to '''eth''' (note: that's '''eth''', without no '''0'''). | ||
+ | |||
You may also want to set a "local version" for your kernel: | You may also want to set a "local version" for your kernel: | ||
CONFIG_LOCALVERSION="my_cool_custom_kernel_2009-08-13" | CONFIG_LOCALVERSION="my_cool_custom_kernel_2009-08-13" | ||
Line 116: | Line 160: | ||
=== Compiling the Kernel and Modules === | === Compiling the Kernel and Modules === | ||
− | Now, | + | Now, compile the kernel: |
make uImage | make uImage | ||
− | + | And, if you configured any code to load as modules, build the modules: | |
make modules | make modules | ||
+ | make modules_install | ||
+ | The kernel should now be ready at '''arch/arm/boot/uImage''', and the modules should be under '''binaries/lib/modules'''. As always, make sure to keep backup copies of your existing kernel and modules before you replace them with new ones. | ||
+ | |||
+ | These instructions for native compilation of a custom kernel have been tested and verified to work with | ||
+ | the '''linux-2.6.22_lsp.3.0.5.tar.bz2''' Buffalo sources on a [[:Category:LS-CL|LS-CL]] running [[GenLink for ARM9|GenLink]]. The resulting kernel compiles, boots, and runs quite nicely on the box. These instructions should work equally well for the | ||
+ | |||
+ | == Links == | ||
+ | [[Buffalo ARM9 Kernel Port]] | ||
+ | |||
+ | [[:Category:LSPro|LS Pro]] and [[:Category:LSLive|LS Live]]. | ||
[[Category:Development]] | [[Category:Development]] |
Latest revision as of 18:51, 5 April 2010
Contents
Two Ways to Compile a Kernel
There are two ways to build a custom kernel for the LinkStation/Kurobox. If you have access to an i686 host running some flavor of Linux, you can cross-compile a kernel for ARM9 on an i686 host. Alternatively, if your NAS has enough RAM, you could compile the kernel on the NAS itself, using the system's native gcc. Both ways of these approaches to building a custom kernel are described in the instructions that follow.
Cross-compiling a Kernel
Download All the Required Tarballs
To use the cross toolchain to compile a kernel for ARM9, you'll need access to an i686 host running some flavor of Linux. First, download the cross toolchain (arm-2005q3-2-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2), mkimage, and the source archive (linux-2.6.12_lsp.1.7.8.tgz):
$ cd /some_directory $ wget -H -c http://downloads.nas-central.org/LSPro_ARM9/DevelopmentTools/CrossToolchains/CodeSourcery/arm-2005q3-2-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 $ wget -H -c http://downloads.nas-central.org/LSPro_ARM9/DevelopmentTools/CrossToolchains/mkimage $ wget -H -c http://downloads.nas-central.org/LSPro_ARM9/GPL/gpl_ls-gl/linux-2.6.12_lsp.1.7.8.tgz
If the files were not at the locations indicated above, fear not! Just look in every directory on the server (like I did).
Prepare the Environment
Then, install (i.e., untar) the toolchain and mkimage:
$ cd /some_path $ tar -xjf /some_directory/arm-2005q3-2-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 $ cd bin $ export PATH=`pwd`:$PATH $ cp -p /some_directory/mkimage . $ chmod a+rx mkimage
Strictly speaking mkimage should not go into /some_path/bin. But, hey...
Now untar the source of the kernel in some directory:
$ cd /some_directory $ tar -xzf linux-2.6.12_lsp.1.7.8.tgz $ cd linux-2.6.12_lsp.1.7.8
Ready, Get Set, Build!
In some_directory you can find the configs Buffalo used to build the kernels shipped with their various firmwares:
$ ls buffalo/
and choose one to use as a template for yours.
$ cp buffalo/buffalo_lsgl_arm_110.config .config
Then you can modify the configuration as you want:
$ make menuconfig
and start up the build!
$ make uImage
If you selected some features to be built as modules, they need to be prepared too.
$ make modules
The kernel and modules will be ready at arch/arm/boot/uImage.
Enjoy!
Compiling a Native Kernel
Software and Source Code Requirements
If the distribution you have installed on your NAS has gcc, and enough RAM to compile a kernel, you should be able to build a custom kernel directly on the box itself. To do this, you will need gcc, a utility called mkimage, and the Buffalo kernel sources for your device. Those using GenLink will already have sys-devel/gcc on their system. mkimage is part of the dev-embedded/u-boot-tools package:
emerge --getbinpkg --usepkg dev-embedded/u-boot-tools
If you're running a different distribution, you should use the commands appropriate to your distribution to install gcc and u-boot-tools.
In case you're wondering, mkimage is a utility used to create kernel and/or initrd images for use with u-boot. u-boot is the standard bootloader used on the LS. The mkimage utility is run by the Makefile during the kernel build process, and is needed to package the kernel so it can later be loaded by u-boot.
The Buffalo kernel sources for your NAS should be available on the Buffalo Source Code Download page. Just look for the model device that you have, follow the link for the firmware version you want, look for a package name starting with "linux-", and download it.
For example, if you have a LS-CL, you would surf to this page and download linux-2.6.22_lsp.3.0.5.tar.bz2.
Of course, that's only an example. Download the source package that matches your device.
Unpack and Fix Sources
Once you have the kernel sources, you should unpack them somewhere convenient. For the sake of example, we'll use /usr/src/linux.
cd /usr/src tar -xvjf /wherever/i/downloaded/linux-2.6.22_lsp.3.0.5.tar.bz2 ln -s linux-2.6.22_lsp.3.0.5 linux
(That ln -s is optional, of course, and just for convenience.)
Now that you've unpacked the source, a small change needs to be made to the main Makefile. Since the Makefile was written for cross-compilation, you need to comment out some lines and uncomment others:
#ARCH ?= $(SUBARCH) CROSS_COMPILE ?= ARCH ?= arm #CROSS_COMPILE=arm-none-linux-gnueabi-
There's also a small bug in arch/arm/mach-feroceon/Board/boardEnv/mv88F5182BoardEnv.c that you'll want to fix:
//#if 0 #ifdef CONFIG_BUFFALO_LINKSTATION_LSGL
(Why did they put #if 0 in there? Who knows? Just comment it out.)
You also have to swap two pairs of lines in block/ll_rw_blk.c, so that it ends up looking like this:
if (!uptodate) { if (blk_fs_request(req) && !(req->cmd_flags & REQ_QUIET)) printk("end_request: I/O error, dev %s, sector %llu\n", req->rq_disk ? req->rq_disk->disk_name : "?", (unsigned long long)req->sector); if(req->rq_disk){ #ifdef CONFIG_BUFFALO_ERRCNT if(atomic_inc_return(&req->rq_disk->nr_errs) < 0) atomic_set(&req->rq_disk->nr_errs, INT_MAX); #endif /* CONFIG_BUFFALO_ERRCNT */ #ifdef CONFIG_BUFFALO_PLATFORM // end_request: I/O error, dev sda, sector 16 { //char str[32]; //sprintf(str,"%02x:%02x",req->rq_disk->major,req->rq_disk->minors); kernevnt_IOErr(req->rq_disk->disk_name /*str*/, (rq_data_dir(req)==WRITE)? "WRITE":"READ", req->sector, ++req->rq_disk->io_errors); } #endif } }
(Why does Buffalo publish incomplete, broken, code? I don't know. They're technically required by the GPL to publish source for their modifications, yet the code released clearly isn't the complete code they used to build their kernels. Is this a violation of the GPL? I'll give you a chance to compile their code, and let you decide for yourself...)
Peek at the LspReadme.txt
In the top level directory of the kernel source, there should be a file LspReadme.txt. This file contains all sorts of great information about the Buffalo kernel. You may want to look through it before you configure your kernel.
Configuring the Kernel
Next, you'll want to pre-configure the kernel with the default .config for your NAS. Assuming you have an LS-GL or LS-CL, which are based on the mv88f5182 chip:
cd /usr/src/linux make mv88f5182_defconfig
That will copy the default Buffalo config file (arch/arm/configs/mv88f5182_defconfig) to .config.
Now, you have to configure the kernel.
make menuconfig
For some reason, the default .config has CONFIG_BLK_DEV_INITRD and CONFIG_BLK_DEV_RAM disabled, and CONFIG_SYSFS_DEPRECATED and CONFIG_LEGACY_PTYS enabled. So, poke around for those options and change them. When you're done, somewhere in your .config file, you should have each of these lines:
CONFIG_BLK_DEV_INITRD=y CONFIG_BLK_DEV_RAM=y # CONFIG_SYSFS_DEPRECATED is not set # CONFIG_LEGACY_PTYS is not set
The default .config also comes with a large number of Buffalo configuration variables unset. The kernel will probably compile if you use these settings:
CONFIG_BUFFALO_PLATFORM=y CONFIG_BUFFALO_SOFT_BOARDID=y CONFIG_USE_RS5C372=y CONFIG_BUFFALO_USE_INTERRUPT_DRIVER=y CONFIG_BUFFALO_USE_GPIO_DRIVER=y CONFIG_BUFFALO_SUPPORT_BOARD_INFO=y
(In fact, using those was the only way I could get the kernel to compile. Finding this combination took some trial and error, because the Buffalo Kconfig files don't contain proper dependency information for these config variables.)
The default .config also has an incorrect value for CONFIG_MV_ETH_NAME. CONFIG_MV_ETH_NAME should be set as follows:
CONFIG_MV_ETH_NAME="eth"
The default value for this variable ("egiga") makes the first ethernet device on the LS appear as egiga0. Since most alternative distributions and initrds assume that the first ethernet device is eth0, your NAS probably won't be accessible from the network unless you change this to eth (note: that's eth, without no 0).
You may also want to set a "local version" for your kernel:
CONFIG_LOCALVERSION="my_cool_custom_kernel_2009-08-13"
Compiling the Kernel and Modules
Now, compile the kernel:
make uImage
And, if you configured any code to load as modules, build the modules:
make modules make modules_install
The kernel should now be ready at arch/arm/boot/uImage, and the modules should be under binaries/lib/modules. As always, make sure to keep backup copies of your existing kernel and modules before you replace them with new ones.
These instructions for native compilation of a custom kernel have been tested and verified to work with the linux-2.6.22_lsp.3.0.5.tar.bz2 Buffalo sources on a LS-CL running GenLink. The resulting kernel compiles, boots, and runs quite nicely on the box. These instructions should work equally well for the