# Building a custom kernel on a different machine



## bhanafee (Sep 30, 2010)

I'm trying to build and install a custom kernel for a machine with _very_ limited resources (a Soekris net4501). It has no floppy, cdrom, HDD, keyboard, mouse, or VGA. It does have serial, ethernet, the capability to boot using PXE, and a compact flash that acts like an IDE drive. I'm switching it from OpenBSD to FreeBSD because I need to add firewire support, but I'm new to FreeBSD so this is my first time building a custom kernel.

Using the instructions here  along with a FreeBSD installation created using VMWare on a Mac, I have been able to compile a bootloader and use it to install a GENERIC 8.1 kernel onto the target machine from an nfs mount of an exploded disk 1 ISO image. The GENERIC kernel mostly works on the target device, but it still needs a couple drivers and I'd also like to recover some memory by removing unneeded drivers for hardware that isn't ever going to be on this box. Between section 8.6 of the handbook, assorted man pages, dmesg, devinfo and pciconf on the GENERIC install, I think I've got a pretty good inventory of what to keep.

Since the target device has such limited resources, I need to build the kernel on the virtual FreeBSD image then move the binary files. After a few tries, the "make buildkernel _[CONFIG]_" step completes with no errors, but all the instructions for building a custom kernel seem to end with "make installkernel _[CONFIG]_" and a reboot. Since the "make buildkernel" is not on the target machine, I need to perform the kernel installation manually.

What do I need to move besides /boot/kernel/kernel? Anything?


----------



## phoenix (Sep 30, 2010)

`# make KERNCONF=nameofkernel KODIR=/some/other/path installkernel`

The KODIR is the important part.  That will install the kernel to /some/other/path instead of to /boot/kernel.  That way, you don't interfere with your running system.

*kernel* and *acpi.ko* are all you *need* for a 32-bit x86 install, if you've compiled all the needed drivers into the kernel.  If you load anything from /boot/loader.conf, then you obviously also need the corresponding .ko file.

As an example, I always use the following process when testing new kernels:

```
# cd /usr/src
# make buildworld
# make KERNCONF=mykernelconfig buildkernel
# make KERNCONF=mykernelconfig KODIR=/boot/kernel.new installkernel
# nextboot -k kernel.new
# shutdown -r now
```
That way, only the next boot uses /boot/kernel.new/*.  If anything goes wrong, a simple reboot will switch everything back to using /boot/kernel/*.  If everything goes well, then a couple simple mv commands will replace the old kernel with the new kernel.

No muss, no fuss, and no "oh crap, I've just installkernel'd twice meaning my old kernel is no longer kernel.old" moments.


----------



## SIFE (Oct 3, 2010)

I think Mr bhanafee wont wants some optimizations to his kernel config[ ], well there are some threads content some configurations for kernel you can read it to see what you can remove in your kernel[ ].

here Here is are some options you can remove from your kernel[ ]:

1) remove debugging option 
2) if you don't use IPv6 or SCTP protocol remove it[ ].
3) remove old compatibility for FreeBSD binary and keep only COMPAT_FREEBSD7
4) KDTRACE for kernel debugging proposes you can remove it[ ].
5) if you don't have rai controller or floppy drives
6) remove SCSI controllers
7) remove all RAID controllers if you don't have it or need it[ ].
8) remove agp support
9) remove serial and parallel port support if you don't use them[ ].
10) put only support for your network card in kernel
11) remove ISA ethernet NICs and wireless support if you don't use it
12) remove some converting devices such as gif[ ], faith[ ].
13) keep only USB support for mass storage[ ], the rest for usb wireless and NICs, printer, usb serial[ ], keyboard and mouse[ ].
14) you can also remove FireWire support 

compile Compile only what you need modules by list theme in /etc/make.conf like this[ ]:


```
MODULES_OVERRIDE=[I]list of modules[/I]
```
here Here is my kernel config and make.conf[ ]:


```
cpu		HAMMER
ident		STABLE
options 	SCHED_ULE		# ULE scheduler
options 	PREEMPTION		# Enable kernel thread preemption
options 	INET			# InterNETworking
options 	FFS			# Berkeley Fast Filesystem
options 	SOFTUPDATES		# Enable FFS soft updates support
options 	UFS_ACL			# Support for access control lists
options 	UFS_DIRHASH		# Improve performance on big directories
options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
options 	MD_ROOT			# MD is a potential root device
options 	NFSCLIENT		# Network Filesystem Client
options 	NFSSERVER		# Network Filesystem Server
options 	NFSLOCKD		# Network Lock Manager
options 	NFS_ROOT		# NFS usable as /, requires NFSCLIENT
options 	MSDOSFS			# MSDOS Filesystem
options 	CD9660			# ISO 9660 Filesystem
options 	PROCFS			# Process filesystem (requires PSEUDOFS)
options 	PSEUDOFS		# Pseudo-filesystem framework
options 	GEOM_PART_GPT		# GUID Partition Tables.
options 	GEOM_LABEL		# Provides labelization
options 	COMPAT_43TTY		# BSD 4.3 TTY compat (sgtty)
options 	COMPAT_FREEBSD32	# Compatible with i386 binaries
options 	COMPAT_FREEBSD7		# Compatible with FreeBSD7
options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
options 	KTRACE			# ktrace(1) support
options 	STACK			# stack(9) support
options 	SYSVSHM			# SYSV-style shared memory
options 	SYSVMSG			# SYSV-style message queues
options 	SYSVSEM			# SYSV-style semaphores
options 	P1003_1B_SEMAPHORES	# POSIX-style semaphores
options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options 	PRINTF_BUFR_SIZE=128	# Prevent printf output being interspersed.
options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
options 	HWPMC_HOOKS		# Necessary kernel hooks for hwpmc(4)
options 	AUDIT			# Security event auditing
options 	MAC			# TrustedBSD MAC Framework
options 	FLOWTABLE		# per-cpu routing cache
options 	INCLUDE_CONFIG_FILE     # Include this file in kernel
options 	SMP			# Symmetric MultiProcessor Kernel
device		cpufreq
device		acpi
device		pci
device		ata
device		atadisk		# ATA disk drives
device		atapicd		# ATAPI CDROM drives
options 	ATA_STATIC_ID	# Static device numbering
					# output.  Adds ~128k to driver.
					# output.  Adds ~215k to driver.
device		scbus		# SCSI bus (required for SCSI)
device		ch		# SCSI media changers
device		da		# Direct Access (disks)
device		sa		# Sequential Access (tape etc)
device		cd		# CD
device		pass		# Passthrough device (direct SCSI access)
device		ses		# SCSI Environmental Services (and SAF-TE)
device		atkbdc		# AT keyboard controller
device		atkbd		# AT keyboard
device		psm		# PS/2 mouse
device		kbdmux		# keyboard multiplexer
device		vga		# VGA video card driver
device		splash		# Splash screen and screen saver support
device		sc
device		cbb		# cardbus (yenta) bridge
device		pccard		# PC Card (16-bit) bus
device		cardbus		# CardBus (32-bit) bus
device		miibus		# MII bus support
device		re		# RealTek 8139C+/8169/8169S/8110S
device		loop		# Network loopback
device		random		# Entropy device
device		ether		# Ethernet support
device		tun		# Packet tunnel.
device		pty		# BSD-style compatibility pseudo ttys
device		md		# Memory "disks"
device		bpf		# Berkeley packet filter
options 	USB_DEBUG	# enable debug msgs
device		uhci		# UHCI PCI->USB interface
device		ohci		# OHCI PCI->USB interface
device		ehci		# EHCI PCI->USB interface (USB 2.0)
device		usb		# USB Bus (required)
device		uhid		# "Human Interface Devices"
device		umass		# Disks/Mass storage - Requires scbus and da
device		firewire	# FireWire bus code
device    pf
device    pflog
device    pfsync
options NETGRAPH
options NETGRAPH_ETHER
options NETGRAPH_PPPOE
options NETGRAPH_SOCKET
```

make.conf[ ]:


```
CFLAGS= -pipe
COPTFLAGS= -pipe
MODULES_OVERRIDE=sound/sound sound/driver/hda opensolaris zfs linux linprocfs \
drm/drm drm/radeon ata/atapicam
OVERRIDE_LINUX_BASE_PORT=f10
OVERRIDE_LINUX_NOBASE_PORTS=f10
MASTER_SITE_BACKUP?= \
		ftp://ftp.sunet.se/pub/os/FreeBSD/ports/distfiles/${DIST_SUBDIR/} \
		ftp://ftp.de.freebsd.org/pub/FreeBSD/ports/distfiles/${DIST_SUBDIR/} \
     		ftp://ftp.freebsd.org/pub/FreeBSD/ports/distfiles/${DIST_SUBDIR/}
#MASTER_SITE_OVERRIDE?=${MASTER_SITE_BACKUP}
# speed up download of ports
FETCH_CMD=axel
FETCH_BEFORE_ARGS= -n 4 -a
DISABLE_SIZE=YES
# added by use.perl 2010-09-15 03:24:00
PERL_VERSION=5.12.1
```


----------



## richardpl (Oct 3, 2010)

My kernel:

```
cpu I686_CPU
ident kernel
option SCHED_ULE
option PREEMPTION
option INET
option MD_ROOT
option _KPOSIX_PRIORITY_SCHEDULING
option PRINTF_BUFR_SIZE=128
option KBD_INSTALL_CDEV
option SMP
device apic
device atkbd
device atkbdc
device pci
device psm
device vga
device sc
device pmtimer
device loop
device ether
device bpf
nodevice io
nodevice mem
```

src.conf:

```
.if !defined(CC) || ${CC} == "cc"
CC=clang
.endif
.if !defined(CXX) || ${CXX} == "c++"
CXX=clang++
.endif
NDEBUG=
NO_WERROR=
WERROR=
MALLOC_PRODUCTION=
WITHOUT_ACCT=1
WITHOUT_ACPI=1
WITHOUT_AMD=1
WITHOUT_ATM=1
WITHOUT_AUDIT=1
WITHOUT_AUTHPF=1
WITHOUT_BIND=1
WITHOUT_BSNMP=1
WITHOUT_CALENDAR=1
WITHOUT_CDDL=1
WITHOUT_CTM=1
WITHOUT_CVS=1
WITHOUT_DICT=1
WITHOUT_EXAMPLES=1
WITHOUT_FLOPPY=1
WITHOUT_FREEBSD_UPDATE=1
WITHOUT_GAMES=1
WITHOUT_GROFF=1
WITHOUT_HTML=1
WITHOUT_INET6=1
WITHOUT_INFO=1
WITHOUT_IPFILTER=1
WITHOUT_IPFW=1
WITHOUT_IPX=1
WITHOUT_JAIL=1
WITHOUT_LOCALES=1
WITHOUT_LOCATE=1
WITHOUT_LPR=1
WITHOUT_MAIL=1
WITHOUT_MAILWRAPPER=1
WITHOUT_MAN=1
WITHOUT_NCP=1
WITHOUT_NIS=1
WITHOUT_NLS=1
WITHOUT_NLS_CATALOGS=1
WITHOUT_NS_CACHING=1
WITHOUT_NTP=1
WITHOUT_PPP=1
WITHOUT_PROFILE=1
WITHOUT_QUOTAS=1
WITHOUT_RCMDS=1
WITHOUT_RCS=1
WITHOUT_ROUTED=1
WITHOUT_SENDMAIL=1
WITHOUT_SHAREDOCS=1
WITHOUT_SYSCONS=1
WITHOUT_SYSINSTALL=1
WITHOUT_TEXTPROC=1
WITHOUT_ZONEINFO=1
WITHOUT_ZFS=1
```

loader.conf:

```
io_load="YES"
mem_load="YES"
ata_load="YES"
drm_load="YES"
i915_load="YES"
wlan_load="YES"
wlan_wep_load="YES"
atapci_load="YES"
atapicd_load="YES"
atapicam_load="YES"
cam_load="YES"
acpi_load="YES"
acpi_dsdt_load="NO"
acpi_dsdt_name="/boot/dsdt.aml"
autoboot_delay="0"
beastie_disable="YES"
hint.acpi_throttle.0.disabled=1
hint.apic.0.clock=0
hint.atrtc.0.clock=0
hint.attimer.0.clock=0
hint.hpet.0.legacy_route=1
hint.pcm.0.eq=1
hint.pt4cc.0.disabled=1
hw.pci.do_power_nodriver=3
hw.acpi.power_button_state=NONE
hw.acpi.sleep_button_state=NONE
hw.acpi.lid_switch_state=NONE
hw.acpi.standby_state=NONE
hw.acpi.suspend_state=NONE
kern.timecounter.hardware=HPET
kern.cam.boot_delay=15000
kern.hz=100
random_load="YES"
sound_load="YES"
snd_hda_load="YES"
ufs_load="YES"
usb_load="YES"
ohci_load="YES"
uhci_load="YES"
ukbd_load="YES"
ehci_load="YES"
umass_load="YES"
vm.pmap.pg_ps_enabled=0
```

running CURRENT, and /boot/kernel is only 34MB.
With MODULES_OVERRIDE you can make /boot/kernel even smaller....


----------



## SirDice (Oct 3, 2010)

bhanafee said:
			
		

> Since the target device has such limited resources, I need to build the kernel on the virtual FreeBSD image then move the binary files. After a few tries, the "make buildkernel _[CONFIG]_" step completes with no errors, but all the instructions for building a custom kernel seem to end with "make installkernel _[CONFIG]_" and a reboot. Since the "make buildkernel" is not on the target machine, I need to perform the kernel installation manually.



Here's how I do it. If everything is already running freebsd FreeBSD and you have network access:


```
# mount build.machine:/usr/src /usr/src
# mount build.machine:/usr/obj /usr/obj
# cd /usr/src
# make installkernel KERNCONF=MYKERNEL
# make installworld
```

If you make sure the local /etc/make.conf (set KERNCONF) and /etc/src.conf are set up properly it'll only install those parts.


----------



## Beastie (Oct 3, 2010)

SIFE said:
			
		

> 3) remove old compatibilite for FreeBSD binary and keep only COMPAT_FREEBSD7


What for? It is always better to keep software up to date (i.e. build the latest version on the current release). Even binary blobs are available for 8.x. Or not?



			
				SIFE said:
			
		

> 8) remove agp support


Unless you have a 10+ year old machine 



			
				SIFE said:
			
		

> compile only what you need modules by list theme in /etc/make.conf like this :
> 
> ```
> MODULES_OVERRIDE=[I]list of modules[/I]
> ```


Or *makeoptions MODULES_OVERRIDE="list of modules"* within the kernel configuration file itself.


----------

