CISO file format
I have analyzed the CISO format by studying the source code of uLoader. Here I will explain the results and hope that anyone can confirm them.
Data Structure
Each CISO file has a header with 32 KiB (32768 bytes). The first 4 bytes are the magic "CISO". The next 4 bytes are a 4 byte integer stored in little endian (intel format but not network byte order).
The MAP
The map uses the rest of the head (32760 bytes). Each byte represents a ISO block with given block size. A '1' means that the block is stored in the file, a '0' means that it is not stored (and is logical filled with zeros).
If reading from a CISO it is good to transform the map into a other map:
CODE typedef u16 CISO_Map_t;
const CISO_Map_t CISO_UNUSED_BLOCK = (CISO_Map_t)~0;
CISO_Head_t * head = ...
CISO_Map_t ciso_map[CISO_MAP_SIZE];
CISO_Map_t count = 0;
int idx;
for ( idx = 0; idx < CISO_MAP_SIZE; idx++ )
ciso_map[idx] = head->map[idx] ? count++ : CISO_UNUSED_BLOCK;
Reading a byte from the CISO file looks like this:
Good block_size
It seems that block_size must be a multiple of WII_SECTOR_SIZE (= 32 KiB = 32768).
To store a complete Wii disc with 4 699 979 776 bytes the block size must be at least 5*32=160 KiB and for double layer 320 KiB.
When extracting a disc from WBFS the uLoader software uses the WBFS sector size (multiple of 2 MiB) as CISO block size. The 'isotociso' tool (part of uLoader source) uses a fixed block size of 4 MiB. These block sizes are much larger and the ciso files grow a litle bit.
My Questions:
wwt + wit
I have implemented CISO support into my WWT tools.
If writing the block size is at least 1 MiB, but the maximum used block number never exceeds 8192.
If reading a CISO plausibility checks are done to verify a valid CISO:
I have analyzed the CISO format by studying the source code of uLoader. Here I will explain the results and hope that anyone can confirm them.
Data Structure
Code:
enum // some constants
{
CISO_HEAD_SIZE = 0x8000, // total header size
CISO_MAP_SIZE = CISO_HEAD_SIZE - 8, // map size
CISO_MIN_BLOCK_SIZE = WII_SECTOR_SIZE, // minimal allowed block size
};
typedef struct CISO_Head_t
{
u8 magic[4]; // "CISO"
u32 block_size; // stored as litte endian (not network byte order)
u8 map[CISO_MAP_SIZE]; // 0=unused, 1=used, others=invalid
} __attribute__ ((packed)) CISO_Head_t;
Each CISO file has a header with 32 KiB (32768 bytes). The first 4 bytes are the magic "CISO". The next 4 bytes are a 4 byte integer stored in little endian (intel format but not network byte order).
The MAP
The map uses the rest of the head (32760 bytes). Each byte represents a ISO block with given block size. A '1' means that the block is stored in the file, a '0' means that it is not stored (and is logical filled with zeros).
If reading from a CISO it is good to transform the map into a other map:
CODE typedef u16 CISO_Map_t;
const CISO_Map_t CISO_UNUSED_BLOCK = (CISO_Map_t)~0;
CISO_Head_t * head = ...
CISO_Map_t ciso_map[CISO_MAP_SIZE];
CISO_Map_t count = 0;
int idx;
for ( idx = 0; idx < CISO_MAP_SIZE; idx++ )
ciso_map[idx] = head->map[idx] ? count++ : CISO_UNUSED_BLOCK;
Reading a byte from the CISO file looks like this:
Code:
u8 ReadByteCISO ( ... file, CISO_Map_t * ciso_map, u32 block_size, off_t iso_off )
{
const u32 block = iso_off/block_size;
if ( block >= CISO_MAP_SIZE || ciso_map[block] == CISO_UNUSED_BLOCK )
return 0;
// calcualte the base address
u32 file_off = ciso_map[block] * (u64)block_size + CISO_UNUSED_BLOCK;
// add the offset inside the block
file_off += iso_off - block * (u64)block_size;
return ReadByte(file,file_off);
}
Good block_size
It seems that block_size must be a multiple of WII_SECTOR_SIZE (= 32 KiB = 32768).
To store a complete Wii disc with 4 699 979 776 bytes the block size must be at least 5*32=160 KiB and for double layer 320 KiB.
When extracting a disc from WBFS the uLoader software uses the WBFS sector size (multiple of 2 MiB) as CISO block size. The 'isotociso' tool (part of uLoader source) uses a fixed block size of 4 MiB. These block sizes are much larger and the ciso files grow a litle bit.
My Questions:
- Is the block size always a multiple of 32768 (32 KiB)?
- Must the block size be a power 2?
- Is there a importand minimal CISO block size?
- Does a USB loader need a max block limitation to limit the size of the internal mapping table?
wwt + wit
I have implemented CISO support into my WWT tools.
If writing the block size is at least 1 MiB, but the maximum used block number never exceeds 8192.
If reading a CISO plausibility checks are done to verify a valid CISO:
- The magic must be "CISO".
- The block size must be a multiple of 32 KiB.
- No other values than 0 and 1 are allowed for the map.
- The filesize must be correspondent to the number of used blocks.
- Are other values than 0 and 1 allowed for the map?