Version: v0.0.0-...-c97c800 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Feb 6, 2019 License: BSD-3-Clause Imports: 10 Imported by: 0



package bzImage implements encoding.UnmarshalBinary for bzImage files. The bzImage struct contains all the information about the file and can be used to create a new bzImage.

These are the semi-documented things that define a bzImage Thanks to coreboot for documenting the basic layout.



View Source
const (
	Ram      e820type = 1
	Reserved          = 2
	ACPI              = 3
	NVS               = 4
View Source
const (
	NotSet    boottype = 0
	LoadLin            = 1
	BootSect           = 2
	SysLinux           = 3
	EtherBoot          = 4
	Kernel             = 5
View Source
const (
	RamdiskStartMask = 0x07FF
	Prompt           = 0x8000
	Load             = 0x4000

	CommandLineMagic = 0x7ff
	CommandLineSize  = 256

	DefaultInitrdAddrMax  = 0x37FFFFFF
	DefaultBzimageAddrMax = 0x37FFFFFF

	E820Max = 128
	E820Map = 0x2d0
	E820NR  = 0x1e8
View Source
const (
	EDDMBRSigMax       = 16
	EDDMaxNR           = 6 /* number of edd_info structs starting at EDDBUF  */
	EDDDeviceParamSize = 74
View Source
const (
	EDDExtFixedDiskAccess = 1 << iota


View Source
var (
	LoaderType = map[boottype]string{
		NotSet:    "Not set",
		LoadLin:   "loadlin",
		BootSect:  "bootsector",
		SysLinux:  "syslinux",
		EtherBoot: "etherboot",
		Kernel:    "kernel (kexec)",
	E820 = map[e820type]string{
		Ram:      "Ram",
		Reserved: "Reserved",
		ACPI:     "ACPI",
		NVS:      "NVS",
	HeaderMagic = [4]uint8{'H', 'd', 'r', 'S'}
View Source
var (
	Debug = func(string, ...interface{}) {}


func Equal

func Equal(a, b []byte) error

func MakeLinuxHeader

func MakeLinuxHeader(h *LinuxHeader) ([]byte, error)

MakeLinuxHeader marshals a LinuxHeader into a []byte.


type BzImage

type BzImage struct {
	Header       LinuxHeader
	BootCode     []byte
	HeadCode     []byte
	KernelCode   []byte
	TailCode     []byte
	KernelBase   uintptr
	KernelOffset uintptr
	// contains filtered or unexported fields

func (*BzImage) AddInitRAMFS

func (b *BzImage) AddInitRAMFS(name string) error

func (*BzImage) Diff

func (b *BzImage) Diff(b2 *BzImage) string

Diff is a convenience function that returns a string showing differences between a bzImage and another bzImage

func (*BzImage) ELF

func (b *BzImage) ELF() (*elf.File, error)

Extract extracts the KernelCode as an ELF.

func (*BzImage) InitRAMFS

func (b *BzImage) InitRAMFS() (int, int, error)

InitRAMFS returns a []byte from KernelCode which can be used to save or replace an existing InitRAMFS. The fun part is that there are no symbols; what we do instead is find the programs what are RW and look for the cpio magic in them. If we find it, we see if it can be read as a cpio and, if so, if there is a /dev or /init inside. We repeat until we succeed or there's nothing left.

func (*BzImage) MarshalBinary

func (b *BzImage) MarshalBinary() ([]byte, error)

MarshalBinary implements the encoding.BinaryMarshaler interface.

func (*BzImage) UnmarshalBinary

func (b *BzImage) UnmarshalBinary(d []byte) error

UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. For now, it hardwires the KernelBase to 0x100000. bzImages were created by a process of evilution, and they are wondrous to behold. bzImages are almost impossible to modify. They form a sandwich with the compressed kernel code in the middle. It's actually a BLT: MBR and bootparams first 512 bytes

the MBR includes 0xc0 bytes of boot code which is vestigial.

Then there is "preamble" code which is the kernel decompressor; then the xz compressed kernel; then a library of sorts after the kernel which is called by the early uncompressed kernel code. This is all linked together and forms an essentially indivisible whole -- which we wish to divisible. Hence the groveling around for the xz header that you see here, and hence the checks to ensure that the kernel layout ends up largely the same before and after. That said, if you keep layout unchanged, you can modify the uncompressed kernel. For example, when you first build a kernel, you can: dd if=/dev/urandom of=x bs=1048576 count=8 echo x | cpio -o > x.cpio and use that as an initrd, it's more or less an 8 MiB block you can replace as needed. Just make sure nothing grows. And make sure the initramfs is in the same place. Ah, joy.

type E820Entry

type E820Entry struct {
	Addr    uint64
	Size    uint64
	MemType e820type

type EDDInfo

type EDDInfo struct {
	Device                uint8
	Version               uint8
	InterfaceSupport      uint16
	LegacyMaxCylinder     uint16
	LegacyMaxHead         uint8
	LegacySectorsPerTrace uint8
	EDDDeviceParams       [EDDDeviceParamSize]uint8

type LinuxHeader

type LinuxHeader struct {
	MBRCode         [0xc0]uint8         `offset:"0x000"`
	ExtRamdiskImage uint32              `offset:"0xc0"`
	ExtRamdiskSize  uint32              `offset:"0xc4"`
	ExtCmdlinePtr   uint32              `offset:"0xc8"`
	O               [0x1f1 - 0xcc]uint8 `offset:"0xcc"`
	SetupSects      uint8               `offset:"0x1f1"`
	RootFlags       uint16              `offset:"0x1f2"`
	Syssize         uint32              `offset:"0x1f4"` //(2.04+)
	RamSize         uint16              `offset:"0x1f8"`
	Vidmode         uint16              `offset:"0x1fa"`
	RootDev         uint16              `offset:"0x1fc"`
	Bootsectormagic uint16              `offset:"0x1fe"`
	// 0.00+
	Jump            uint16   `offset:"0x200"`
	HeaderMagic     [4]uint8 `offset:"0x202"`
	Protocolversion uint16   `offset:"0x206"`
	RealModeSwitch  uint32   `offset:"0x208"`
	StartSys        uint16   `offset:"0x20c"`
	Kveraddr        uint16   `offset:"0x20e"`
	TypeOfLoader    uint8    `offset:"0x210"`
	Loadflags       uint8    `offset:"0x211"`
	Setupmovesize   uint16   `offset:"0x212"`
	Code32Start     uint32   `offset:"0x214"`
	RamDiskImage    uint32   `offset:"0x218"`
	RamDiskSize     uint32   `offset:"0x21c"`
	BootSectKludge  [4]uint8 `offset:"0x220"`
	// 2.01+
	Heapendptr    uint16 `offset:"0x224"`
	ExtLoaderVer  uint8  `offset:"0x226"`
	ExtLoaderType uint8  `offset:"0x227"`
	// 2.02+
	Cmdlineptr uint32 `offset:"0x228"`
	// 2.03+
	InitrdAddrMax uint32 `offset:"0x22c"`
	// 2.05+
	Kernelalignment   uint32 `offset:"0x230"`
	RelocatableKernel uint8  `offset:"0x234"`
	MinAlignment      uint8  `offset:"0x235"` //(2.10+)
	XLoadFlags        uint16 `offset:"0x236"`
	// 2.06+
	CmdLineSize uint32 `offset:"0x238"`
	// 2.07+
	HardwareSubArch     uint32 `offset:"0x23c"`
	HardwareSubArchData uint64 `offset:"0x240"`
	// 2.08+
	PayloadOffset uint32 `offset:"0x248"`
	PayloadSize   uint32 `offset:"0x24c"`
	// 2.09+
	SetupData uint64 `offset:"0x250"`
	// 2.10+
	PrefAddress    uint64 `offset:"0x258"`
	InitSize       uint32 `offset:"0x260"`
	HandoverOffset uint32 `offset:"0x264"`

The header of Linux/i386 kernel

func (*LinuxHeader) Diff

func (h *LinuxHeader) Diff(i *LinuxHeader) string

Diff is a convenience function that returns a string showing differences between a header and another header.

func (*LinuxHeader) Show

func (h *LinuxHeader) Show() []string

Show stringifies a LinuxHeader into a []string

func (*LinuxHeader) String

func (h *LinuxHeader) String() string

String stringifies a LinuxHeader into comma-separated parts

type LinuxParams

type LinuxParams struct {
	Origx         uint8  `offset:"0x00"`
	Origy         uint8  `offset:"0x01"`
	ExtMemK       uint16 `offset:"0x02"` //-- EXTMEMK sits here
	OrigVideoPage uint16 `offset:"0x04"`
	OrigVideoMode uint8  `offset:"0x06"`
	OrigVideoCols uint8  `offset:"0x07"`

	OrigVideoeGabx uint16 `offset:"0x0a"`

	OrigVideoLines  uint8  `offset:"0x0e"`
	OrigVideoIsVGA  uint8  `offset:"0x0f"`
	OrigVideoPoints uint16 `offset:"0x10"`

	// VESA graphic mode -- linear frame buffer
	Lfbwidth      uint16 `offset:"0x12"`
	Lfbheight     uint16 `offset:"0x14"`
	Lfbdepth      uint16 `offset:"0x16"`
	Lfbbase       uint32 `offset:"0x18"`
	Lfbsize       uint32 `offset:"0x1c"`
	CLMagic       uint16 `offset:"0x20"` // DON'T USE
	CLOffset      uint16 `offset:"0x22"` // DON'T USE
	Lfblinelength uint16 `offset:"0x24"`
	Redsize       uint8  `offset:"0x26"`
	Redpos        uint8  `offset:"0x27"`
	Greensize     uint8  `offset:"0x28"`
	Greenpos      uint8  `offset:"0x29"`
	Bluesize      uint8  `offset:"0x2a"`
	Bluepos       uint8  `offset:"0x2b"`
	Rsvdsize      uint8  `offset:"0x2c"`
	Rsvdpos       uint8  `offset:"0x2d"`
	Vesapmseg     uint16 `offset:"0x2e"`
	Vesapmoff     uint16 `offset:"0x30"`
	Pages         uint16 `offset:"0x32"`

	//struct apmbiosinfo apmbiosinfo;
	Apmbiosinfo [0x40]uint8 `offset:"0x40"`
	//struct driveinfostruct driveinfo;
	Driveinfo [0x20]uint8 `offset:"0x80"`
	//struct sysdesctable sysdesctable;
	Sysdesctable [0x140]uint8 `offset:"0xa0"`
	Altmemk      uint32       `offset:"0x1e0"`

	E820MapNr uint8 `offset:"0x1e8"`

	MountRootReadonly uint16 `offset:"0x1f2"`

	Ramdiskflags uint16 `offset:"0x1f8"`

	OrigRootDev uint16 `offset:"0x1fc"`

	Auxdeviceinfo uint8 `offset:"0x1ff"`

	Paramblocksignature [4]uint8 `offset:"0x202"`
	Paramblockversion   uint16   `offset:"0x206"`

	LoaderType  uint8 `offset:"0x210"`
	Loaderflags uint8 `offset:"0x211"`

	KernelStart uint32 `offset:"0x214"`
	Initrdstart uint32 `offset:"0x218"`
	Initrdsize  uint32 `offset:"0x21c"`

	CLPtr         uint32 `offset:"0x228"` // USE THIS.
	InitrdAddrMax uint32 `offset:"0x22c"`
	/* 2.04+ */
	KernelAlignment uint32 `offset:"0x230"`

	MinAlignment        uint8  `offset:"0x235"`
	XLoadFlags          uint16 `offset:"0x236"`
	CmdLineSize         uint32 `offset:"0x238"`
	HardwareSubarch     uint32 `offset:"0x23C"`
	HardwareSubarchData uint64 `offset:"0x240"`
	Payload_Ofset       uint32 `offset:"0x248"`
	PayloadLength       uint32 `offset:"0x24C"`
	SetupData           uint64 `offset:"0x250"`
	PrefAddress         uint64 `offset:"0x258"`
	InitSize            uint32 `offset:"0x260"`
	HandoverOffset      uint32 `offset:"0x264"`

	EDDMBRSigBuffer [EDDMBRSigMax]uint32 `offset:"0x290"`
	// e820map is another cockup from the usual suspects.
	// Go rounds the size to something reasonable. Oh well. No checking for you.
	// So the next two offsets are bogus, sorry about that.
	E820Map [E820Max]E820Entry `offset:"0x2d0"`

	EDDBuf [EDDMaxNR]EDDInfo `offset:"0xf00"` // `offset:"0xd00"`
	// contains filtered or unexported fields

Parameters passed to 32-bit part of Linux

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL