There are a number of ways to do it, although it is not clear to me which one you're looking for exactly.
First off, as you mentioned, you can request a resolution in your Multiboot flags. This is hardcoded in the binary, therefore not really good in terms of letting the user choose a resolution.
As you rightfully state, you can set (read: request) a resolution using a GRUB variable: it is called 'gfxpayload'. For me, this overrides my Multiboot2-header resolution. Typically, I use it as:
Code:
menuentry "MyOS" {
multiboot2 /path/to/my/kernel
set gfxpayload=1920x1080x32
boot
}
You can create multiple entries using different resolutions, letting the user choose one of the predefined options in GRUB. To clean things up, use a submenu for that.
Here's how I do it.
If you want ultimate flexibility, you can let the user input the values. Use GRUB's
read command for this. After that, you can construct the resolution and set gfxpayload to that value.
I haven't done this, but IIRC it looks something like this:
Code:
menuentry "custom" {
echo "width:"
read __width
echo "height:"
read __height
<your commands>
set gfxpayload=${__width}x${__height}x32
boot
}