// this func calculate the number of frames // require for the ram and then acc to that // create no. of frames which will be required for it // and also mark the space which is preoccupied // by the kernel void init_mm(u32int ram_sz_bytes) { // create a bitmap for the record // which blocks is allocated // and which isn't initFrames(ram_sz_bytes); // right now bit is full of zero // means nothing is allocated yet // so we have place one to show that // kernel is here you can't allocate // here allocate_kernel(); }
/** * Load an x86 Linux kernel. * * @param loader Loader internal data. */ __noreturn void linux_arch_load(linux_loader_t *loader) { linux_params_t *params; size_t cmdline_size, setup_size, load_size; char *cmdline; void *virt; phys_ptr_t phys, initrd_max; list_t memory_map; status_t ret; static_assert(sizeof(linux_params_t) == PAGE_SIZE); static_assert(offsetof(linux_params_t, hdr) == LINUX_HEADER_OFFSET); // Allocate memory for the parameters data (the "zero page"). params = memory_alloc(sizeof(linux_params_t), 0, 0x10000, 0x90000, MEMORY_TYPE_RECLAIMABLE, 0, NULL); memset(params, 0, sizeof(*params)); // Read in the kernel header. ret = fs_read(loader->kernel, ¶ms->hdr, sizeof(params->hdr), offsetof(linux_params_t, hdr)); if (ret != STATUS_SUCCESS) boot_error("Error reading kernel header: %pS", ret); // Start populating required fields in the header. Don't set heap_end_ptr or // the CAN_USE_HEAP flag, as these appear to only be required by the 16-bit // entry point which we do not use. params->hdr.type_of_loader = 0xff; // Calculate the maximum command line size. cmdline_size = (params->hdr.version >= 0x0206) ? params->hdr.cmdline_size : 255; if (strlen(loader->cmdline) > cmdline_size) boot_error("Kernel command line is too long"); // Allocate memory for command line. cmdline_size = round_up(cmdline_size + 1, PAGE_SIZE); cmdline = memory_alloc(cmdline_size, 0, 0x10000, 0x90000, MEMORY_TYPE_RECLAIMABLE, 0, NULL); strncpy(cmdline, loader->cmdline, cmdline_size); cmdline[cmdline_size] = 0; params->hdr.cmd_line_ptr = (uint32_t)((ptr_t)cmdline); // Determine the setup code size. if (params->hdr.setup_sects) setup_size = (params->hdr.setup_sects + 1) * 512; else setup_size = 5 * 512; // Load size is total file size minus setup size. load_size = loader->kernel->size - setup_size; // Allocate memory for the kernel image. virt = allocate_kernel(params, load_size, &phys); if (!virt) boot_error("Insufficient memory available for kernel image"); params->hdr.code32_start = phys + params->hdr.code32_start - LINUX_BZIMAGE_ADDR; // Read in the kernel image. ret = fs_read(loader->kernel, virt, load_size, setup_size); if (ret != STATUS_SUCCESS) boot_error("Error reading kernel image: %pS", ret); // Load in the initrd(s). if (loader->initrd_size) { initrd_max = (params->hdr.version >= 0x0203) ? params->hdr.initrd_addr_max : 0x37ffffff; // It is recommended that the initrd be loaded as high as possible. virt = memory_alloc( round_up(loader->initrd_size, PAGE_SIZE), 0, 0x100000, initrd_max + 1, MEMORY_TYPE_MODULES, MEMORY_ALLOC_HIGH, &phys); dprintf( "linux: loading initrd to 0x%" PRIxPHYS " (size: 0x%zx, max: 0x%" PRIxPHYS ")\n", phys, loader->initrd_size, initrd_max); linux_initrd_load(loader, virt); params->hdr.ramdisk_image = phys; params->hdr.ramdisk_size = loader->initrd_size; } // Set the video mode. linux_video_set(loader); // Perform pre-boot tasks. loader_preboot(); // Get the final memory map and print it out for informational purposes. // Note that the memory_finalize() is necessary on EFI in order to free up // any internal allocations in the EFI memory map so that they will be free // to the kernel. dprintf("linux: final physical memory map:\n"); memory_finalize(&memory_map); memory_map_dump(&memory_map); // Get platform code to do any setup it needs and enter the kernel. // For BIOS, this will obtain information usually obtained by the real-mode // bootstrap when using the 16-bit boot protocol, then jump to the 32-bit // entry point. For EFI, this will enter the kernel using the handover // protocol. linux_platform_load(loader, params); }