H. Peter Anvin
2013-Jul-26 16:49 UTC
[syslinux] [syslinux:firmware] load_linux: dynamically calculate the cmdline region
On 07/26/2013 01:27 AM, syslinux-bot for Matt Fleming wrote:> diff --git a/com32/lib/syslinux/load_linux.c b/com32/lib/syslinux/load_linux.c > index 851d467..37c8df0 100644 > --- a/com32/lib/syslinux/load_linux.c > +++ b/com32/lib/syslinux/load_linux.c > @@ -125,10 +125,29 @@ static int map_initramfs(struct syslinux_movelist **fraglist, > } > > static size_t calc_cmdline_offset(struct linux_header *hdr, > - size_t cmdline_size) > + size_t cmdline_size, addr_t base, > + addr_t start) > { > - if (hdr->version < 0x0202 || !(hdr->loadflags & 0x01)) > + if (hdr->version < 0x0202 || !(hdr->loadflags & 0x01)) { > + struct syslinux_memmap *mmap; > + > + mmap = syslinux_memory_map(); > + if (mmap && !syslinux_memmap_highest(mmap, SMT_FREE, &start, > + cmdline_size, 0xa0000, 16)) { > + syslinux_free_memmap(mmap); > + return start - base; > + } > + > + if (mmap && !syslinux_memmap_highest(mmap, SMT_TERMINAL, &start, > + cmdline_size, 0xa0000, 16)) { > + syslinux_free_memmap(mmap); > + return start - base; > + } > +Hmm... this might constrain the heap excessively if the SMT_TERMINAL cutoff is at the wrong place (because there will be just enough SMT_FREE to fit.) I'm wondering if we shouldn't use the highest of these two regions. Now, for old kernels, there is an additional constraint, which is that the cmdline needs to be part of the same segment as the real mode code, so the above is incorrect for the case of 2.00 or 2.01 kernels loaded high, when the real mode code is loaded low... if we get an address above real_mode_base + 64K those kernels will fail. 2.02+ kernels do not have that limitation. -hpa
Matt Fleming
2013-Jul-29 13:28 UTC
[syslinux] [syslinux:firmware] load_linux: dynamically calculate the cmdline region
On Fri, 26 Jul, at 09:49:28AM, H. Peter Anvin wrote:> Hmm... this might constrain the heap excessively if the SMT_TERMINAL > cutoff is at the wrong place (because there will be just enough SMT_FREE > to fit.) I'm wondering if we shouldn't use the highest of these two > regions.Could you give an example memory map where this would be a problem? I not sure I understand what you mean. Perhaps something like, start end type ----------------------------- 0x090000 0x090400 SMT_FREE 0x090400 0x09f000 SMT_TERMINAL ? In which case, irrespective of their type, you're suggesting we just want the highest usable address from these two regions?> Now, for old kernels, there is an additional constraint, which is that > the cmdline needs to be part of the same segment as the real mode code, > so the above is incorrect for the case of 2.00 or 2.01 kernels loaded > high, when the real mode code is loaded low... if we get an address > above real_mode_base + 64K those kernels will fail. 2.02+ kernels do > not have that limitation.I don't understand the implications of loading the kernel high and real mode code low, what does the location of the kernel have to do with the cmdline? Allocating the cmdline within the same segment as the real mode code makes sense though. -- Matt Fleming, Intel Open Source Technology Center
H. Peter Anvin
2013-Jul-29 13:49 UTC
[syslinux] [syslinux:firmware] load_linux: dynamically calculate the cmdline region
On 07/29/2013 06:28 AM, Matt Fleming wrote:> On Fri, 26 Jul, at 09:49:28AM, H. Peter Anvin wrote: >> Hmm... this might constrain the heap excessively if the SMT_TERMINAL >> cutoff is at the wrong place (because there will be just enough SMT_FREE >> to fit.) I'm wondering if we shouldn't use the highest of these two >> regions. > > Could you give an example memory map where this would be a problem? I > not sure I understand what you mean. Perhaps something like, > > start end type > ----------------------------- > 0x090000 0x090400 SMT_FREE > 0x090400 0x09f000 SMT_TERMINAL >More like the cutoff at, say, 0x094000, and the size of the> > In which case, irrespective of their type, you're suggesting we just > want the highest usable address from these two regions? > >> Now, for old kernels, there is an additional constraint, which is that >> the cmdline needs to be part of the same segment as the real mode code, >> so the above is incorrect for the case of 2.00 or 2.01 kernels loaded >> high, when the real mode code is loaded low... if we get an address >> above real_mode_base + 64K those kernels will fail. 2.02+ kernels do >> not have that limitation. > > I don't understand the implications of loading the kernel high and real > mode code low, what does the location of the kernel have to do with the > cmdline? Allocating the cmdline within the same segment as the real mode > code makes sense though.If the kernel is loaded low, the real mode code has to be at 0x90000 by protocol. If the kernel is loaded high, for kernel >= 2.00 the real mode code can be anywhere... but the cmdline needs to lie inside the real-mode segment (in particular in the range covered by setup_move_size). However, these kernels, at least for actual Liux, would then still move stuff up to the 0x90000 segment... in large measure defeating the point of loading low. It does it pretty late, though, so one can argue that some amount of overwrite is probably okay. Probably. -hpa
H. Peter Anvin
2013-Jul-29 13:54 UTC
[syslinux] [syslinux:firmware] load_linux: dynamically calculate the cmdline region
On 07/29/2013 06:28 AM, Matt Fleming wrote:> > Could you give an example memory map where this would be a problem? I > not sure I understand what you mean. Perhaps something like, > > start end type > ----------------------------- > 0x090000 0x090400 SMT_FREE > 0x090400 0x09f000 SMT_TERMINAL >Omitted the example: let's say the cutoff is 0x94000, and the size of the real-mode portion is 15K. Not much of a heap/stack left. Assuming we can reclaim SMT_TERMINAL seems pretty sane if we are forced to load the real mode chunk high. -hpa