diff -aurN milo-2.2-18-patched/boot.c milo-2.2-18/boot.c --- milo-2.2-18-patched/boot.c 2000-06-29 06:12:40.000000000 +0900 +++ milo-2.2-18/boot.c 2024-03-07 14:40:36.000000000 +0900 @@ -93,6 +93,8 @@ } *chunks; int nchunks; +long bss_size = 0; + /* * Counting stuff. */ @@ -303,7 +305,7 @@ { struct elfhdr *elf; struct elf_phdr *phdr; - int i; + int i, j; elf = (struct elfhdr *) header; @@ -332,8 +334,7 @@ } phdr = (struct elf_phdr *) (header + elf->e_phoff); - nchunks = elf->e_phnum; - chunks = malloc(sizeof(struct segment) * nchunks); + chunks = malloc(sizeof(struct segment) * elf->e_phnum); if (!chunks) { printk("No memory for segments\n"); @@ -344,12 +345,28 @@ kernel_at = phdr[0].p_vaddr; /* assume they are sorted */ kernel_filesize = 0; - for (i = 0; i < nchunks; i++) { - chunks[i].addr = phdr[i].p_vaddr; - chunks[i].offset = phdr[i].p_offset; - chunks[i].size = phdr[i].p_filesz; + for (i = j = 0; i < elf->e_phnum; i++) { + if (phdr[i].p_type != PT_LOAD) + continue; + + chunks[j].addr = phdr[i].p_vaddr; + chunks[j].offset = phdr[i].p_offset; + chunks[j].size = phdr[i].p_filesz; kernel_filesize += phdr[i].p_filesz; + + if (phdr[i].p_memsz > phdr[i].p_filesz) { + if (bss_size > 0) { + printk("Can't load kernel.\n" + " Multiple BSS segments" + " (PHDR %d)", i); + return -1; + } + bss_size = phdr[i].p_memsz - phdr[i].p_filesz; + } + + j++; } + nchunks = j; kernel_memsize = phdr[nchunks - 1].p_vaddr - kernel_at + phdr[nchunks - 1].p_memsz; @@ -420,10 +437,9 @@ #ifdef DEBUG_BOOT printk("...clearing bss memory between 0x%p and 0x%p\n", (char *) kernel_at + kernel_filesize, - (char *) kernel_at + kernel_memsize); + (char *) kernel_at + kernel_filesize + bss_size); #endif - memset((char *) kernel_at + kernel_filesize, 0, - kernel_memsize - kernel_filesize); + memset((char *) kernel_at + kernel_filesize, 0, bss_size); #ifdef DEBUG_BOOT printk("... done.\n"); #endif