User talk:MrNuke: Difference between revisions

From coreboot
Jump to navigation Jump to search
Line 124: Line 124:
** alternatively: limit number of partitions to something reasonable, move names into partitions (so partition entries are fixed size) and append the partition table to the master header. Existence proven by master_header's version field (cbfs_core ignores it right now, which is good).
** alternatively: limit number of partitions to something reasonable, move names into partitions (so partition entries are fixed size) and append the partition table to the master header. Existence proven by master_header's version field (cbfs_core ignores it right now, which is good).


==== Proposed partition entry ====
==== Proposed partition entry formate ====


All values are big endian
All values are big endian


===== Variable name length =====
===== Proposal 1: Variable name length =====
 
====== Entry format ======


{| class="wikitable"
{| class="wikitable"
Line 167: Line 169:
* Subsequent entries shall be placed at the closest 16-byte aligned offset
* Subsequent entries shall be placed at the closest 16-byte aligned offset


===== Fixed name length + partition flags =====
====== Proposed partition table ======
 
{| class="wikitable"
! style="width: 3em;" | Offset
! style="width: 3em;" | 0
! style="width: 3em;" | 1
! style="width: 3em;" | 2
! style="width: 3em;" | 3
! style="width: 3em;" | 4
! style="width: 3em;" | 5
! style="width: 3em;" | 6
! style="width: 3em;" | 7
! style="width: 3em;" | 8
! style="width: 3em;" | 9
! style="width: 3em;" | A
! style="width: 3em;" | B
! style="width: 3em;" | C
! style="width: 3em;" | D
! style="width: 3em;" | E
! style="width: 3em;" | F
 
|-
| 0x00
! colspan="4"| "CBPT"
! colspan="4"| offset
! colspan="4"| size
! colspan="4"| flags
 
|-
| 0x10
! colspan="16"| region_name
 
|-
| 0x20
! colspan="16"| region_name
 
|-
|}
 
* '''region_name''' shall be null-terminated.
** It is always 32-bytes, but can be null-terminated earlier
** Unused bytes will be all '1's
* This structure is marginally easier to parse as opposed to variable length
 
==== Questions ====
 
* Should region_name be fixed to 32-bytes, like in FMAP?
* Should we include a field for partition flags?
** What are the use-cases
** Would this really be useful?
** Would this '''actually''' get used in the wild?
* Should we just use the FMAP format?
 
==== Proposed partition table ====
 
===== Varlen name header =====


{| class="wikitable"
{| class="wikitable"
Line 264: Line 211:
* Generally, CBPT1 will point to the same region as the master header, but this is not required. The idea is that old payloads will still be able to read CBFS by using the region pointed to by the master header. Whether this region is the same as CBPT1 or not is not guaranteed. This is to not impose a specific order on the partition entries.
* Generally, CBPT1 will point to the same region as the master header, but this is not required. The idea is that old payloads will still be able to read CBFS by using the region pointed to by the master header. Whether this region is the same as CBPT1 or not is not guaranteed. This is to not impose a specific order on the partition entries.


===== Fixlen name header =====
====== Example partition table ======
 
{| class="wikitable"
! style="width: 3em;" | Offset
! style="width: 3em;" | 0
! style="width: 3em;" | 1
! style="width: 3em;" | 2
! style="width: 3em;" | 3
! style="width: 3em;" | 4
! style="width: 3em;" | 5
! style="width: 3em;" | 6
! style="width: 3em;" | 7
! style="width: 3em;" | 8
! style="width: 3em;" | 9
! style="width: 3em;" | A
! style="width: 3em;" | B
! style="width: 3em;" | C
! style="width: 3em;" | D
! style="width: 3em;" | E
! style="width: 3em;" | F
 
|-
| 0x00
! colspan="16"| CBPT1
 
|-
| 0x30
! colspan="16"| CBPT2
 
|-
| 0x60
! colspan="16"| CBPT3
 
|-
| 0x90
! colspan="4"| terminator all '1's
 
|-
|}
 
* Generally, CBPT1 will point to the same region as the master header, but this is not required. The idea is that old payloads will still be able to read CBFS by using the region pointed to by the master header. Whether this region is the same as CBPT1 or not is not guaranteed. This is to not impose a specific order on the partition entries.
 
===== Example partition table =====
 
====== With variable name length ======


{| class="wikitable"
{| class="wikitable"
Line 438: Line 341:
* "mrc.cache": 0x00070000 + 0x00010000
* "mrc.cache": 0x00070000 + 0x00010000


====== With fixed name length and flags ======
===== Questions =====
 
* Should region_name be fixed to 32-bytes, like in FMAP?
* Should we include a field for partition flags?
** What are the use-cases
** Would this really be useful?
** Would this '''actually''' get used in the wild?
* Should we just use the FMAP format?
 
===== Proposal 2: Fixed name length =====
 
====== Entry format ======
 
{| class="wikitable"
! style="width: 3em;" | Offset
! style="width: 3em;" | 0
! style="width: 3em;" | 1
! style="width: 3em;" | 2
! style="width: 3em;" | 3
! style="width: 3em;" | 4
! style="width: 3em;" | 5
! style="width: 3em;" | 6
! style="width: 3em;" | 7
! style="width: 3em;" | 8
! style="width: 3em;" | 9
! style="width: 3em;" | A
! style="width: 3em;" | B
! style="width: 3em;" | C
! style="width: 3em;" | D
! style="width: 3em;" | E
! style="width: 3em;" | F
 
|-
| 0x00
! colspan="4"| "CBPT"
! colspan="4"| offset
! colspan="4"| size
! colspan="4"| flags
 
|-
| 0x10
! colspan="16"| region_name
 
|-
| 0x20
! colspan="16"| region_name
 
|-
|}
 
* '''region_name''' shall be null-terminated.
** It is always 32-bytes, but can be null-terminated earlier
** Unused bytes will be all '1's
* This structure is marginally easier to parse as opposed to variable length
 
====== Table format ======
 
{| class="wikitable"
! style="width: 3em;" | Offset
! style="width: 3em;" | 0
! style="width: 3em;" | 1
! style="width: 3em;" | 2
! style="width: 3em;" | 3
! style="width: 3em;" | 4
! style="width: 3em;" | 5
! style="width: 3em;" | 6
! style="width: 3em;" | 7
! style="width: 3em;" | 8
! style="width: 3em;" | 9
! style="width: 3em;" | A
! style="width: 3em;" | B
! style="width: 3em;" | C
! style="width: 3em;" | D
! style="width: 3em;" | E
! style="width: 3em;" | F
 
|-
| 0x00
! colspan="16"| CBPT1
 
|-
| 0x30
! colspan="16"| CBPT2
 
|-
| 0x60
! colspan="16"| CBPT3
 
|-
| 0x90
! colspan="4"| terminator all '1's
 
|-
|}
 
* Generally, CBPT1 will point to the same region as the master header, but this is not required. The idea is that old payloads will still be able to read CBFS by using the region pointed to by the master header. Whether this region is the same as CBPT1 or not is not guaranteed. This is to not impose a specific order on the partition entries.
 
====== Example table ======


{| class="wikitable"
{| class="wikitable"

Revision as of 17:56, 22 January 2014

Ideas for generic handling of devices

IMPORTANT! Feel free to edit this page to share your thoughts and ideas. This is the official MMC open brainstorming page.

Proposal 1: Unified API

Chan is an IO channel.

This struct is used in Inferno and has been for a long time; so it works. It's also in the opcodes somewhat like what we did for EMMC on ARM.

struct Dev
{
	char*	name;
	void	(*reset)(void);
	void	(*init)(void);
	void	(*shutdown)(void);
	Chan*	(*attach)(char*); /* tell the device you want to use it */
	Walkqid*	(*walk)(Chan*, Chan*, char**, int); /* walk to a name in the device's managed name space; return a handle */
	int	(*stat)(Chan*, uchar*, int); // status info
	Chan*	(*open)(Chan*, int); /* get access to a resource in the device name space */
	void	(*close)(Chan*); /* tell it you are done with whatever it is. */
	long	(*read)(Chan*, void*, long, vlong);
	long	(*write)(Chan*, void*, long, vlong);
	void	(*power)(int);	/* power mgt: power(1) ? on, power (0) ? off */
};

Questions

  1. Do we want to expose or hide the block nature of some devces (i.e. force reading multiples of blocksize, or allow reading any number of bytes, with no alignment requirement) ?
  2. How do we connect the dots, such that most of the details can be handled transparently ?
  3. How simple or complex do we want the API to be such that it can work in any stage (including bootblock, assuming some SRAM and a stack are available) ?
  4. Can we integrate this into libpayload such that the same sources can be used for both coreboot and libpayload ?
    • think "Device specfic storage drivers -> [*] Allwinner A10 MMC driver" in libpayload config
  5. More questions coming soon (TM)

Extending CBFS to support partitioning

Reasoning

  • To separate write-protected (RO) and writeable (RW) regions of flash chip
  • To incorporate relevant FMAP features directly into CBFS
  • To be able to better handle the requirements of ChromeOS

Tentative terminology

  • Partition
    • A region indexed by CBFS
  • File
    • Same meaning as before. A CBFS file that resides entirely within the boundaries of one partition.

Design constraints

  • Backwards compatibility
    • New CBFS structure should be backwards compatible with old structure
    • Old payloads should still be able to access old features of CBFS

Tentative API

  • cbfs_get_file(const char *name) <- Get file in main partition, also backwards compatible
  • cbfs_get_partition(const char *name) <- Get location of partition other than main (or even main)
  • cbfs_get_partition_file(cbfs_part_t partition, const char *name) <- Get file in given partition

Hypothetical examples

Partition in read-write portion of flash

Here, we assume that "rw1" is not in a write-protected area of flash.

void *rw1 = cbfs_get_partition("rw1");
file *romstage cbfs_get_partition_file(rw1, "fallback/romstage);
load_and_run_stage(romstage);

MRC cache

void *mrc_cache = cbfs_get_partition("mrc.cache");
/* Access raw partition, there is no file in this partition */
mrc_cache_check(mrc_cache);
mrc_cache_write(mrc_cache, data);

Technical stuff

Current CBFS master header

All values are big endian

Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00 "ORBC" version romsize bootblocksize
0x10 align offset arch padding
  • PROPOSED: Change padding to a signed offset pointing to partition table; all '1's means no partition table is available
    • The offset shall be from the start of "ORBC" signature.
    • alternatively: limit number of partitions to something reasonable, move names into partitions (so partition entries are fixed size) and append the partition table to the master header. Existence proven by master_header's version field (cbfs_core ignores it right now, which is good).

Proposed partition entry formate

All values are big endian

Proposal 1: Variable name length
Entry format
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00 "CBPT" offset size region_name
0x10 region_name ...
  • region_name shall be null-terminated.
  • Each partition entry shall be 16 byte aligned.
  • Subsequent entries shall be placed at the closest 16-byte aligned offset
Proposed partition table
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x10 CBPT1
0x_0 CBPT2
0x_0 CBPT3
0x_0 terminator all '1's
  • Generally, CBPT1 will point to the same region as the master header, but this is not required. The idea is that old payloads will still be able to read CBFS by using the region pointed to by the master header. Whether this region is the same as CBPT1 or not is not guaranteed. This is to not impose a specific order on the partition entries.
Example partition table
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00 "CBPT" 0x00070000 0x00010000 c o r e
0x10 b o o t \0 0xff
0x20 "CBPT" 0x00040000 0x00020000 t h i s
0x30 _ p a r t i t i o n _ h a s _ a
0x40 _ l u d i c r o u s l y _ l o n
0x50 g . n a m e \0 0xff
0x60 "CBPT" 0x00060000 0x00010000 m r c .
0x70 c a c h e \0 0xff
0x80 0xffffffff
  • "coreboot": 0x00070000 + 0x00010000
  • "this_partition_has_a_ludicrously_long.name" 0x00040000 + 0x00020000
  • "mrc.cache": 0x00070000 + 0x00010000
Questions
  • Should region_name be fixed to 32-bytes, like in FMAP?
  • Should we include a field for partition flags?
    • What are the use-cases
    • Would this really be useful?
    • Would this actually get used in the wild?
  • Should we just use the FMAP format?
Proposal 2: Fixed name length
Entry format
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00 "CBPT" offset size flags
0x10 region_name
0x20 region_name
  • region_name shall be null-terminated.
    • It is always 32-bytes, but can be null-terminated earlier
    • Unused bytes will be all '1's
  • This structure is marginally easier to parse as opposed to variable length
Table format
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00 CBPT1
0x30 CBPT2
0x60 CBPT3
0x90 terminator all '1's
  • Generally, CBPT1 will point to the same region as the master header, but this is not required. The idea is that old payloads will still be able to read CBFS by using the region pointed to by the master header. Whether this region is the same as CBPT1 or not is not guaranteed. This is to not impose a specific order on the partition entries.
Example table
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00 "CBPT" 0x00070000 0x00010000 0x00000000
0x10 c o r e b o o t \0 0xff
0x20 0xff
0x30 "CBPT" 0x00040000 0x00020000 0x00000000
0x40 t h i s _ p a r t i t i o n _ h
0x50 a s _ a _ l u d i c r o u s l \0
0x60 "CBPT" 0x00060000 0x00010000 0x00000000
0x70 m r c . c a c h e \0 0xff
0x80 0xffffffff
0x90 0xffffffff
  • "coreboot": 0x00070000 + 0x00010000
  • "this_partition_has_a_ludicrousl" 0x00040000 + 0x00020000
  • "mrc.cache": 0x00070000 + 0x00010000