mtd

package
v0.11.0 Latest Latest
Warning

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

Go to latest
Published: Feb 2, 2023 License: BSD-3-Clause Imports: 2 Imported by: 0

Documentation

Overview

Chips are made by vendors, and an individual vendor is defined by a 1 to 8 byte vendor id stored in the chip. An instance of a type of chip, with, e.g., a particular size, is defined by a 1 to 3 or so byte device id stored in the chip. The vendor, device id pair can be used to find both unique properties of a chip (e.g. size) and the common properties of a chip (e.g. erase value, voltages, erase blocks. etc.) It is not at all unusual to know a vendor but not a device id. Hence we need to be able to get a vendor given a vendor id, and then a chip given a chip id. It's ok, however, to know the vendor and fail to know the chip.

Sadly, device ids are not unique; they are reused per vendor. And, as mentioned, both vendor and device id are variable length. In a not uncommon failure of vision, they started out as 1 byte each, grew to 2, then 3 in some cases, 7 in other. Good times. Life would be easier if everybody just made these things strings in the beginning.

An ID identifies a vendor, but not the same vendor over time. Vendor names for a given ID change over time, due to buyouts, bankruptcies, and the occasional near depression. For example, what was AMD is now Spansion. This name changing complicates the picture a bit, so we maintain a list of vendor names for a given part, with the first name in the list being the current name. This will allow us to accomodate scripts that might have the wrong vendor name. As time goes by, and bankruptcies accumulate, this first name can change.

Hence, it is useful to have 3 bits of knowledge o list of vendor names given a vendor id o list of chips and their unique properties given a device id o list of common properties which can be referenced from a chip

We wish to embed this code in FLASH so if needed we can burn a chip from FLASH-embedded u-root.

This code uses strings, not integers, since device and vendor IDs are now variable length, depending on year of manufacture. Further, it is just nicer to work with strings.

In most cases, we will walk these tables once, so we design for exhaustive search. The tables are short and are traversed in microseconds, you only do it once, and it's important to keep data as compact as possible.

A note on flashing. Writing is not zero cost: each erase/write cycle reduces chip lifetime. Data in the chip need not be erased to be written: 0xee can be changed to 0xcc without an erase cycle in many parts. Code can make a guess a guess at an optimal erase/write pattern based on the size of the regions to be written, the content of regions, and the size of the blocks available. Getting this calculation right has proven to be tricky, as it has to balance time costs of writing, expected costs of too many erase cycles, and several other factors I can not recall just now. Watch this space.

TODO: figure out some minimum set of config options for Linux, with the proviso that this will be very kernel version dependent.

Index

Constants

This section is empty.

Variables

View Source
var DevName = "/dev/mtd0"

DevName is the default name for the MTD device.

Functions

func Supported

func Supported(c Chip) bool

Supported returns true if a chip is supported by this package.

Types

type Chip

type Chip interface {
	// Name returns the chip name
	Name() ChipName
	// ID returns the chip ID
	ID() ChipID
	// Size returns the chip size.
	Size() ChipSize
	// Synonyms returns all the alternate names for a chip
	Synonyms() []ChipName
	// String returns as much information as one can stand about a chip.
	String() string
}

Chip defines operations on Chips.

func ChipFromVIDDID

func ChipFromVIDDID(vid VendorID, did ChipID) (Chip, error)

ChipFromVIDDID will return a Chip struct, given a Vendor and Device ID.

type ChipDevice

type ChipDevice struct {
	// contains filtered or unexported fields
}

ChipDevice has information about a chip, include Vendor, Device, sizes, and so on; and a reference to common properties. As in Vendors, there are several names for a chip.

func (*ChipDevice) ID

func (c *ChipDevice) ID() ChipID

ID returns the ChipID.

func (*ChipDevice) Name

func (c *ChipDevice) Name() ChipName

Name returns the canonical chip name.

func (*ChipDevice) Size

func (c *ChipDevice) Size() ChipSize

Size returns a ChipSize in bytes.

func (*ChipDevice) String

func (c *ChipDevice) String() string

String is a stringer for a ChipDevice.

func (*ChipDevice) Synonyms

func (c *ChipDevice) Synonyms() []ChipName

Synonyms returns all synonyms for a chip.

type ChipID

type ChipID uint64

ChipID is the integer associated with a ChipName It began as 8 bits, and never stopped growing.

type ChipName

type ChipName string

ChipName is the device name

type ChipSize

type ChipSize uint

ChipSize is the size in bytes of the chip.

type Dev

type Dev struct {
	*os.File
	// contains filtered or unexported fields
}

Dev contains information about ongoing MTD status and operation.

func (*Dev) Close

func (m *Dev) Close() error

Close implements io.Close

func (*Dev) Name added in v0.9.0

func (m *Dev) Name() string

DevName returns the name of the flash device.

func (*Dev) QueueWriteAt added in v0.9.0

func (m *Dev) QueueWriteAt(b []byte, off int64) (int, error)

QueueWrite adds a []byte to the pending write queue.

func (*Dev) ReadAt

func (m *Dev) ReadAt(b []byte, off int64) (int, error)

ReadAt implements io.ReadAT

func (*Dev) SyncWrite

func (m *Dev) SyncWrite() error

SyncWrite syncs a pending queue of writes to a device.

type Flasher

type Flasher interface {
	// ReadAt implements io.ReadAt for a flash device.
	ReadAt([]byte, int64) (int, error)
	// QueueWrite queues a sequence of writes into a flash device.
	QueueWriteAt([]byte, int64) (int, error)
	// SyncWrite assembles the queued writes and figures out a reasonable
	// plan for actually writing the part.
	SyncWrite() error
	// Close implements io.Close for a flash device.
	Close() error
	// Name returns the name of the flash device
	Name() string
}

Flasher defines the interface to flash drivers.

Many devices must have lazy writes; SyncWrite should always be called after a sequence of QueueWrite commands. Close should return an error if there are queued write commands. To erase a device, one calls chip Blank(), QueueWrite(), and SyncWrite(). The operators are deined for the Flasher, not the Chipper, since flashing can involve driver-level operations such as unlocking protection bits on a bridge that are more than just a chip operation.

func NewDev

func NewDev(n string) (Flasher, error)

NewDev creates a Dev, returning Flasher or error.

type Vendor

type Vendor interface {
	// Chip returns a Chip, given a DeviceID
	Chip(ChipID) (Chip, error)
	// ID Returns the VendorID
	ID() VendorID
	// Name() returns the canonical name
	Name() VendorName
	// Synonyms returns all the names
	Synonyms() []VendorName
}

Vendor defines operations on vendor data.

func VendorFromID

func VendorFromID(v VendorID) (Vendor, error)

VendorFromID returns a Vendor or error given a VendorID.

func VendorFromName

func VendorFromName(v VendorName) (Vendor, error)

VendorFromName returns a Vendor or error given a VendorName.

type VendorID

type VendorID uint64

VendorID is the integer associated with a VendorName It began as 8 bits, and never stopped growing.

type VendorName

type VendorName string

VendorName is the manufacturers name

Jump to

Keyboard shortcuts

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