Difference between revisions of "User talk:MrNuke"

From coreboot
Jump to: navigation, search
(Entry format)
(Testing ARM coreboot under qemu-system-arm)
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
== Ideas for generic handling of devices ==
+
== Sections deserving their own page ==
 +
* [[User_talk:MrNuke/Block_Device_API | IDEAPAGE: Generic handling of storage devices]]
 +
* [[User_talk:MrNuke/CBFS_Ideas | IDEAPAGE: CBFS partitioning support]]
  
IMPORTANT! Feel free to edit this page to share your thoughts and ideas. This is the official MMC open brainstorming page.
+
== Testing ARM coreboot under qemu-system-arm ==
  
=== Proposal 1: Unified API ===
+
Launch qemu with '''-serial stdio''' and pass kernel the '''console=tty''' option. (UNTESTED).
Chan is an IO channel.  
 
  
This struct is used in Inferno and has been for a long time; so it works.
+
Run qemu-arm:
It's also in the opcodes somewhat like what we did for EMMC on ARM.
+
  '''$ qemu-system-arm -M vexpress-a9 -m 1024M -serial stdio -kernel build/coreboot.rom'''
 
 
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 ====
 
 
 
# 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) ?
 
# How do we connect the dots, such that most of the details can be handled transparently ?
 
# 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) ?
 
# 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
 
# 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
 
 
 
{| 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"| "ORBC"
 
! colspan="4"| version
 
! colspan="4"| romsize
 
! colspan="4"| bootblocksize
 
 
 
|-
 
| 0x10
 
! colspan="4"| align
 
! colspan="4"| offset
 
! colspan="4"| arch
 
! colspan="4"| padding
 
 
 
|-
 
|}
 
 
 
The meaning of each member is as follows:
 
 
 
* '''magic''' is a 32 bit number that identifies the ROM as a CBFS type.  The magic number is 0x4F524243, which is 'ORBC' in ASCII.
 
* '''version''' is a version number for CBFS header. cbfs_header structure may be different if version is not matched.
 
* '''romsize''' is the size of the ROM in bytes.  Coreboot will subtract 'size' from 0xFFFFFFFF to locate the beginning of the ROM in memory.
 
* '''bootblocksize''' is the size of bootblock reserved in firmware image.
 
* '''align''' is the number of bytes that each component is aligned to within the ROM.  This is used to make sure that each component is aligned correctly with regards to the erase block sizes on the ROM - allowing one to replace a component at runtime without disturbing the others.
 
* '''offset''' is the offset of the the first CBFS component (from the start of the ROM).  This is to allow for arbitrary space to be left at the beginning of the ROM for things like embedded controller firmware.
 
* '''architecture''' describes which architecture (x86, arm, ...) this CBFS is created for.
 
 
 
 
 
* '''PROPOSED:''' Change '''padding''' to an offset pointing to partition table; all '1's means no partition table is available
 
** The offset shall have the same meaning as all other offsets (from the start of ROM).
 
** (PatrickG) 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).
 
*** (mrnuke) Partition name in partition would violate the out-of-band metadata requirement. (adurbin can explain this better)
 
*** (mrnuke) Also, partition entries can be made fixed size by using Proposal 2 (similar to FMAP).
 
 
 
==== Proposal 1: Variable name length partition table ====
 
 
 
All values are big endian
 
 
 
===== 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"| region_name
 
 
 
|-
 
| 0x10
 
! colspan="16"| 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 =====
 
 
 
{| 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
 
 
 
|-
 
| 0x10
 
! colspan="16"| CBPT1
 
 
 
|-
 
| 0x_0
 
! colspan="16"| CBPT2
 
 
 
|-
 
| 0x_0
 
! colspan="16"| CBPT3
 
 
 
|-
 
| 0x_0
 
! 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 =====
 
 
 
{| 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"| 0x00070000
 
! colspan="4"| 0x00010000
 
! colspan="1"| c
 
! colspan="1"| o
 
! colspan="1"| r
 
! colspan="1"| e
 
 
 
|-
 
| 0x10
 
! colspan="1"| b
 
! colspan="1"| o
 
! colspan="1"| o
 
! colspan="1"| t
 
! colspan="1"| \0
 
! colspan="11"| 0xff
 
 
 
|-
 
| 0x20
 
! colspan="4"| "CBPT"
 
! colspan="4"| 0x00040000
 
! colspan="4"| 0x00020000
 
! colspan="1"| t
 
! colspan="1"| h
 
! colspan="1"| i
 
! colspan="1"| s
 
 
 
|-
 
| 0x30
 
! colspan="1"| _
 
! colspan="1"| p
 
! colspan="1"| a
 
! colspan="1"| r
 
! colspan="1"| t
 
! colspan="1"| i
 
! colspan="1"| t
 
! colspan="1"| i
 
! colspan="1"| o
 
! colspan="1"| n
 
! colspan="1"| _
 
! colspan="1"| h
 
! colspan="1"| a
 
! colspan="1"| s
 
! colspan="1"| _
 
! colspan="1"| a
 
 
 
|-
 
| 0x40
 
! colspan="1"| _
 
! colspan="1"| l
 
! colspan="1"| u
 
! colspan="1"| d
 
! colspan="1"| i
 
! colspan="1"| c
 
! colspan="1"| r
 
! colspan="1"| o
 
! colspan="1"| u
 
! colspan="1"| s
 
! colspan="1"| l
 
! colspan="1"| y
 
! colspan="1"| _
 
! colspan="1"| l
 
! colspan="1"| o
 
! colspan="1"| n
 
 
 
|-
 
| 0x50
 
! colspan="1"| g
 
! colspan="1"| .
 
! colspan="1"| n
 
! colspan="1"| a
 
! colspan="1"| m
 
! colspan="1"| e
 
! colspan="1"| \0
 
! colspan="9"| 0xff
 
 
 
|-
 
| 0x60
 
! colspan="4"| "CBPT"
 
! colspan="4"| 0x00060000
 
! colspan="4"| 0x00010000
 
! colspan="1"| m
 
! colspan="1"| r
 
! colspan="1"| c
 
! colspan="1"| .
 
 
 
|-
 
| 0x70
 
! colspan="1"| c
 
! colspan="1"| a
 
! colspan="1"| c
 
! colspan="1"| h
 
! colspan="1"| e
 
! colspan="1"| \0
 
! colspan="10"| 0xff
 
 
 
|-
 
| 0x80
 
! colspan="4"| 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 partition table ====
 
 
 
===== 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
 
 
 
|-
 
|}
 
 
 
Each entry shall be aligned to 16-bytes. This allows for easy identification of entries with '''hexdump -C'''. Non-aligned entries shall be considered invalid.
 
 
 
Partitions cannot overlap.
 
 
 
Partitions must be entirely contained within the ROM. This is handled by having the partition offest counted from the start of ROM. Other than that, partition_offset + partition_size <= size_of_rom.
 
 
 
Partition table shall be considered immutable (i.e. constant, readonly, and not user-replaceable). The only exception is in cbfstool, which shall allow manipulation of partitions.
 
 
 
The meaning of each member is as follows:
 
 
 
* '''"CBPT"''' is a 32 bit number that identifies the entry as a CBFS partition entry.  The is 'CBPT' in ASCII.
 
* '''offset''' is the offset (from the start of the ROM) to the start of the partition.
 
* '''size''' is the size of the partition in bytes.
 
* '''flags''' is yet undefined.
 
** FMAP defines the following three flags
 
*** STATIC: area's contents will not change
 
*** COMPRESSED: area holds potentially compressed data
 
*** RO: area is considered read-only
 
** STATIC and RO flags seem to be redundant
 
** FMAP flags seems to be of limited use
 
 
 
* '''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"
 
! 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"| 0x00070000
 
! colspan="4"| 0x00010000
 
! colspan="4"| 0x00000000
 
 
 
|-
 
| 0x10
 
! colspan="1"| c
 
! colspan="1"| o
 
! colspan="1"| r
 
! colspan="1"| e
 
! colspan="1"| b
 
! colspan="1"| o
 
! colspan="1"| o
 
! colspan="1"| t
 
! colspan="1"| \0
 
! colspan="7"| 0xff
 
 
 
|-
 
| 0x20
 
! colspan="16"| 0xff
 
 
 
|-
 
| 0x30
 
! colspan="4"| "CBPT"
 
! colspan="4"| 0x00040000
 
! colspan="4"| 0x00020000
 
! colspan="4"| 0x00000000
 
 
 
|-
 
| 0x40
 
! colspan="1"| t
 
! colspan="1"| h
 
! colspan="1"| i
 
! colspan="1"| s
 
! colspan="1"| _
 
! colspan="1"| p
 
! colspan="1"| a
 
! colspan="1"| r
 
! colspan="1"| t
 
! colspan="1"| i
 
! colspan="1"| t
 
! colspan="1"| i
 
! colspan="1"| o
 
! colspan="1"| n
 
! colspan="1"| _
 
! colspan="1"| h
 
 
 
|-
 
| 0x50
 
! colspan="1"| a
 
! colspan="1"| s
 
! colspan="1"| _
 
! colspan="1"| a
 
! colspan="1"| _
 
! colspan="1"| l
 
! colspan="1"| u
 
! colspan="1"| d
 
! colspan="1"| i
 
! colspan="1"| c
 
! colspan="1"| r
 
! colspan="1"| o
 
! colspan="1"| u
 
! colspan="1"| s
 
! colspan="1"| l
 
! colspan="1"| \0
 
 
 
|-
 
| 0x60
 
! colspan="4"| "CBPT"
 
! colspan="4"| 0x00060000
 
! colspan="4"| 0x00010000
 
! colspan="4"| 0x00000000
 
 
 
|-
 
| 0x70
 
! colspan="1"| m
 
! colspan="1"| r
 
! colspan="1"| c
 
! colspan="1"| .
 
! colspan="1"| c
 
! colspan="1"| a
 
! colspan="1"| c
 
! colspan="1"| h
 
! colspan="1"| e
 
! colspan="1"| \0
 
! colspan="6"| 0xff
 
 
 
|-
 
| 0x80
 
! colspan="16"| 0xffffffff
 
 
 
|-
 
| 0x90
 
! colspan="4"| 0xffffffff
 
 
 
|-
 
|}
 
 
 
* "coreboot": 0x00070000 + 0x00010000
 
* "this_partition_has_a_ludicrousl" 0x00040000 + 0x00020000
 
* "mrc.cache": 0x00070000 + 0x00010000
 

Latest revision as of 19:55, 6 February 2014

Sections deserving their own page

Testing ARM coreboot under qemu-system-arm

Launch qemu with -serial stdio and pass kernel the console=tty option. (UNTESTED).

Run qemu-arm:

$ qemu-system-arm -M vexpress-a9 -m 1024M -serial stdio -kernel build/coreboot.rom