在看 代码时发现,如果设置了MAP_FIXED标志,函数就做一些极其简单的检查,然后就把你指定的addr返回给你,代表你查找的空闲的线性区找到了。
unsigned long 1371 get_unmapped_area_prot(struct file *file, unsigned long addr, unsigned long len, /* */ 1372 unsigned long pgoff, unsigned long flags, int exec) 1373 { 1374 unsigned long ret; 1375 1376 if (!(flags & MAP_FIXED)) { 1377 unsigned long (*get_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); 1378 1379 if (exec && current->mm->get_unmapped_exec_area) 1380 get_area = current->mm->get_unmapped_exec_area; 1381 else 1382 get_area = current->mm->get_unmapped_area; 1383 1384 if (file && file->f_op && file->f_op->get_unmapped_area) 1385 get_area = file->f_op->get_unmapped_area; 1386 addr = get_area(file, addr, len, pgoff, flags); 1387 if (IS_ERR_VALUE(addr)) 1388 return addr; 1389 } 1390 1391 if (addr > TASK_SIZE - len) 1392 return -ENOMEM; 1393 if (addr & ~PAGE_MASK) 1394 return -EINVAL; 1395 if (file && is_file_hugepages(file)) { 1396 /* 1397 * Check if the given range is hugepage aligned, and 1398 * can be made suitable for hugepages. 1399 */ 1400 ret = prepare_hugepage_range(addr, len, pgoff); 1401 } else { 1402 /* 1403 * Ensure that a normal request is not falling in a 1404 * reserved hugepage range. For some archs like IA-64, 1405 * there is a separate region for hugepages. 1406 */ 1407 ret = is_hugepage_only_range(current->mm, addr, len); 1408 } 1409 if (ret) 1410 return -EINVAL; 1411 return addr; 1412 }着重看一下后半部分if(0).... 1)首先检查addr+len是否超过了用户空间 2)所请求的地址是否是页对齐的 由于我们先不考虑文件映射 所以后面的暂时忽略 到这里你可能会想,如果你指定的地址开始的线性区真好被映射了怎么办呢?那不是应该返回NULL吗? 然而,事实是MAP_FIXED标志的一个特性是: 如果你指定的地址和已有的线性区重叠,那么就抛弃已有的线性区映射。cool,but dangerous..... MAP_FIXED Do not select a different address than the one specified. If the memory region specified by start and len overlaps pages of any existing mapping(s), then the overlapped part of the existing mapping(s) will be discarded. If the specified address cannot be used, mmap() will fail. If MAP_FIXED is specified, start must be a multiple of the page size. Use of this option is discouraged. from: http://blog.chinaunix.net/uid-25538637-id-195878.html