I don't think it matters whether it's implemented by the hypervisor or the unikernel since it's all open source. But for compatibility with existing hypervisors/clouds one could imagine a boot loader that loads the main unikernel at a random address, sets up page tables with NX, and then makes a one-way transition to ring 3 so that the page tables cannot be modified.
> one could imagine a boot loader that loads the main unikernel at a random address, sets up page tables with NX, and then makes a one-way transition to ring 3
True - I suppose I'm trying to hold onto the "kernel:hypervisor :: process:unikernel" analogy here for no good reason. Following it suggested that it might be the hypervisor's responsibility.