Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Almost-in-place decompression of kernel #985

Closed
wkozaczuk opened this issue Jun 29, 2018 · 0 comments
Closed

Almost-in-place decompression of kernel #985

wkozaczuk opened this issue Jun 29, 2018 · 0 comments

Comments

@wkozaczuk
Copy link
Collaborator

Currently OSv compressed kernel is loaded in real-mode at the address of 0x1800000 (24MB) and then decompressed at 0x200000 (2MB). Compressed size (now) is roughly 6.6MB and decompressed around 10.5MB. This makes 31MB (24MB + 6.5) the smallest amount of memory OSv needs to starts. It also makes RAMFS images take roughly 2-3 times as much memory as image size.

Kernel is compressed with fastlz algorithm which does not support decompression in place. Instead I am proposing a solution offering "almost-in-place" decompression. In essence it relies on segmenting uncompressed kernel into chunks and compressing each chunk independently and concatenating into single file. The compressed chunked kernel would need to be loaded at the offset based on both compressed and uncompressed kernel size and the decompressed chunk by chunk.

More precisely it would work like follows assuming the chunk size is 1MB and uncompressed kernel size (UKS) is 10.5MB:

  1. Split uncompressed kernel into 10 chunks each 1MB long and last chunk 0.
  2. Compress each chunk independently; if compressed chunk size is bigger than original one use the uncompressed chunk.
  3. Concatenate all compressed chunks from above into single file and save the offsets of each compressed chunk.
  4. Assuming we want the uncompressed kernel start at 1MB calculate the offset where the compressed kernel needs to be loaded as follows: 1MB + UKS + 1MB - CKS (compressed kernel size); the second 1M is simply equal to chunk size and is meant to prevent overwriting uncompressed kernel as it is being uncompressed. Save the uncompressed kernel offset (somehow) in the real loader code (part of build process).
  5. In real mode load kernel into the offset determined by the previous step.
  6. In protected mode (uncompress_loader) decompress chunks one by one starting with first one like so:
    1st chunk gets uncompressed at 1MB.
    2nd chunk get uncompressed at 2MB.
    ... and so on.

Alternatively we could use reversed version of this scheme where the compressed kernel would be loaded at 1MB and then decompressed starting with the last chunk.

For more details look at https://groups.google.com/forum/#!topic/osv-dev/_IZukq_mQrI

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant