Skip to content

multiboot2: Allow to get Custom Tags #118

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

Merged
merged 6 commits into from
Mar 17, 2023
Merged

Conversation

phip1611
Copy link
Member

@phip1611 phip1611 commented Nov 27, 2022

This is my first draft to implement #116, i.e., to parse custom Multiboot2 tags.

This PR allows getting custom tags from the Multiboot2 boot information.

The PR should be reviewed commit by commit. May I ask @IsaacWoods for feedback and @blitz for your opinion about the new API?

TL;DR usage:

    #[repr(C, align(8))]
    struct CustomTag {
        // new type from the lib: has repr(u32)
        tag: SpecifiedOrCustomTagTypeSerialized,
        size: u32,
        // begin of inline string
        name: u8,
    }

    let tag = multiboot2_boot_information
        // this function is now public!
        .get_tag(0x1337)
        .unwrap()
        // type definition from end user. must be Sized!
        .cast_tag::<CustomTag>();
    let name = &tag.name as *const u8 as *const c_char;
    let str = unsafe { CStr::from_ptr(name).to_str().unwrap() };
    assert_eq!(str, "name");

Of course, using custom tags, brings all the pain of doing raw pointer magic to the library users.

@phip1611 phip1611 self-assigned this Nov 27, 2022
@phip1611 phip1611 linked an issue Nov 27, 2022 that may be closed by this pull request
@phip1611 phip1611 force-pushed the custom-tags branch 6 times, most recently from 35e2e43 to 60201ba Compare November 27, 2022 15:40
Copy link
Member

@IsaacWoods IsaacWoods left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Some comments about a potential ergonomics improvement, and also some names.

///
/// A `SpecifiedOrCustomTagType` can be constructed from [`SpecifiedOrCustomTagTypeSerialized`].
#[derive(Copy, Clone, Eq, Ord, PartialOrd, PartialEq, Hash)]
pub enum SpecifiedOrCustomTagType {
Copy link
Member

@IsaacWoods IsaacWoods Nov 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and SpecifiedOrCustomTagTypeSerialized are quite long names. If you're alright with the breaking change, I think this being TagType and the current type being renamed to StandardTagType could work? Not sure what a better word for the Serialized bit would be but it also doesn't quite fit.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have an idea how I can simplify everything and have cleaner names. Let's see how it works out in the end.

Copy link

@blitz blitz Nov 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cleaner (shorter) names would really help. I can't help but gloss over the name after the third word. ;)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worst offender: SpecifiedOrCustomTagTypeSerialized :-D

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope you like the new API more. Now there is only TagType and TagTypeId.

@blitz
Copy link

blitz commented Nov 29, 2022

Thanks for working on this!

Regarding the naming:

  • "specified" could be "Standard"
  • "custom" could be "NonStandard" or "VendorSpecific"

@blitz
Copy link

blitz commented Nov 29, 2022

Regarding the API, for your example of a tag that contains a string it could look like this instead:

#[repr(C, align(8))]
struct CustomTag {
  name: [u8], // flexible array
}

impl Tag for CustomTag {
  pub const ID: u32 = 0x1337;
}

For the user the pointer handling then completely disappears. It would also take care of having to handle tag IDs manually. The only downside is that CustomTag can only be constructed with unsafe, but this would be hidden in the library.

As a user I would then like to do use something like find_tag::<CustomTag>() -> Option<CustomTag>.

@phip1611
Copy link
Member Author

phip1611 commented Nov 29, 2022

Regarding the API, for your example of a tag that contains a string it could look like this instead:

#[repr(C, align(8))]
struct CustomTag {
  name: [u8], // flexible array
}

impl Tag for CustomTag {
  pub const ID: u32 = 0x1337;
}

Impossible, as this is not Sized. I didn't find a way to enable the compilation ?Sized structs. https://doc.rust-lang.org/error_codes/E0607.html?highlight=fat%20pointer#

@blitz

I think, ?Sized structs are incompatible on the ABI level.

@blitz
Copy link

blitz commented Nov 30, 2022

Impossible, as this is not Sized. I didn't find a way to enable the compilation ?Sized structs. https://doc.rust-lang.org/error_codes/E0607.html?highlight=fat%20pointer#

You may have to cast through a slice to get the required size information.

I think, ?Sized structs are incompatible on the ABI level.

Are you sure? The way I understand it is that references to the ?Sized struct become fat pointers (pointers + size) and the struct itself looks like in C. This would be ok. I've verified this using objdump and it looks good.

@phip1611 phip1611 force-pushed the custom-tags branch 15 times, most recently from e2dd398 to 86aad17 Compare December 25, 2022 14:40
@phip1611 phip1611 force-pushed the custom-tags branch 2 times, most recently from c2a0931 to cb1bb2c Compare December 25, 2022 14:49
@phip1611
Copy link
Member Author

As a user I would then like to do use something like find_tag::<CustomTag>() -> Option<CustomTag>.

It feels unnecessarily overengineered to me. I'd stick with mbi.get_tag(CustomTag::ID) as it also aligns with the existing code base.

@phip1611
Copy link
Member Author

If no further comments are made, I'm going to merge this in 7 days.

@phip1611 phip1611 force-pushed the custom-tags branch 2 times, most recently from 3bd61a9 to 76a8e8a Compare March 5, 2023 22:21
@phip1611 phip1611 changed the base branch from main to multiboot2-v15-dev March 17, 2023 16:43
@phip1611 phip1611 force-pushed the multiboot2-v15-dev branch 6 times, most recently from 0c76d94 to e687d17 Compare March 17, 2023 17:49
@phip1611 phip1611 force-pushed the custom-tags branch 3 times, most recently from 29d5e9d to a2af96c Compare March 17, 2023 18:05
@phip1611 phip1611 force-pushed the multiboot2-v15-dev branch from e687d17 to b09c7df Compare March 17, 2023 18:06
@phip1611 phip1611 merged commit 4b35d58 into multiboot2-v15-dev Mar 17, 2023
@phip1611 phip1611 deleted the custom-tags branch March 17, 2023 18:12
@phip1611 phip1611 mentioned this pull request Mar 27, 2023
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

Successfully merging this pull request may close these issues.

Evaluate Interface for Custom Tags
3 participants