//.........这里部分代码省略.........
MiDeletePte (PointerPte,
Va,
FALSE,
Process,
NULL,
NULL,
OldIrql);
UNLOCK_PFN (OldIrql);
Process->NumberOfPrivatePages += 1;
MI_WRITE_INVALID_PTE (PointerPte, MmDecommittedPte);
}
else {
//
// PTE is valid, process later when PFN lock is held.
//
if (count == MM_VALID_PTE_SIZE) {
MiProcessValidPteList (&ValidPteList[0], count);
count = 0;
}
ValidPteList[count] = PointerPte;
count += 1;
//
// Remove address from working set list.
//
WorkingSetIndex = Pfn1->u1.WsIndex;
ASSERT (PAGE_ALIGN(MmWsle[WorkingSetIndex].u1.Long) ==
Va);
//
// Check to see if this entry is locked in the
// working set or locked in memory.
//
Locked = MmWsle[WorkingSetIndex].u1.e1;
MiRemoveWsle (WorkingSetIndex, MmWorkingSetList);
//
// Add this entry to the list of free working set
// entries and adjust the working set count.
//
MiReleaseWsle (WorkingSetIndex, &Process->Vm);
if ((Locked.LockedInWs == 1) || (Locked.LockedInMemory == 1)) {
//
// This entry is locked.
//
MmWorkingSetList->FirstDynamic -= 1;
if (WorkingSetIndex != MmWorkingSetList->FirstDynamic) {
Entry = MmWorkingSetList->FirstDynamic;
ASSERT (MmWsle[Entry].u1.e1.Valid);
MiSwapWslEntries (Entry,
WorkingSetIndex,
&Process->Vm,
void *mmorecore(struct mdesc *mdp, ssize_t size)
{
ssize_t test = 0;
void *result; // please keep it uninitialized to track issues
off_t foffset; /* File offset at which new mapping will start */
size_t mapbytes; /* Number of bytes to map */
void *moveto; /* Address where we wish to move "break value" to */
void *mapto; /* Address we actually mapped to */
char buf = 0; /* Single byte to write to extend mapped file */
// fprintf(stderr,"increase %p by %u\n",mdp,size);
if (pagesize == 0)
pagesize = getpagesize();
if (size == 0) {
/* Just return the current "break" value. */
result = mdp->breakval;
} else if (size < 0) {
/* We are deallocating memory. If the amount requested would cause
us to try to deallocate back past the base of the mmap'd region
then die verbosely. Otherwise, deallocate the memory and return
the old break value. */
if (((char *) mdp->breakval) + size >= (char *) mdp->base) {
result = (void *) mdp->breakval;
mdp->breakval = (char *) mdp->breakval + size;
moveto = PAGE_ALIGN(mdp->breakval);
munmap(moveto,
(size_t) (((char *) mdp->top) - ((char *) moveto)) - 1);
mdp->top = moveto;
} else {
fprintf(stderr,"Internal error: mmap was asked to deallocate more memory than it previously allocated. Bailling out now!\n");
abort();
}
} else {
/* We are allocating memory. Make sure we have an open file
descriptor if not working with anonymous memory. */
if (!(mdp->flags & MMALLOC_ANONYMOUS) && mdp->fd < 0) {
fprintf(stderr,"Internal error: mmap file descriptor <0 (%d), without MMALLOC_ANONYMOUS being in the flags.\n",mdp->fd);
abort();
} else if ((char *) mdp->breakval + size > (char *) mdp->top) {
/* The request would move us past the end of the currently
mapped memory, so map in enough more memory to satisfy
the request. This means we also have to grow the mapped-to
file by an appropriate amount, since mmap cannot be used
to extend a file. */
moveto = PAGE_ALIGN((char *) mdp->breakval + size);
mapbytes = (char *) moveto - (char *) mdp->top;
foffset = (char *) mdp->top - (char *) mdp->base;
if (mdp->fd > 0) {
/* FIXME: Test results of lseek() */
lseek(mdp->fd, foffset + mapbytes - 1, SEEK_SET);
test = write(mdp->fd, &buf, 1);
if (test == -1) {
fprintf(stderr,"Internal error: write to mmap'ed fd failed! error: %s", strerror(errno));
abort();
}
}
/* Let's call mmap. Note that it is possible that mdp->top
is 0. In this case mmap will choose the address for us */
mapto = mmap(mdp->top, mapbytes, PROT_READ | PROT_WRITE,
MAP_PRIVATE_OR_SHARED(mdp) | MAP_IS_ANONYMOUS(mdp) |
MAP_FIXED, MAP_ANON_OR_FD(mdp), foffset);
if (mapto == (void *) -1/* That's MAP_FAILED */) {
char buff[1024];
fprintf(stderr,"Internal error: mmap returned MAP_FAILED! error: %s\n",strerror(errno));
sprintf(buff,"cat /proc/%d/maps",getpid());
int status = system(buff);
if (status == -1 || !(WIFEXITED(status) && WEXITSTATUS(status) == 0))
fprintf(stderr, "Something went wrong when trying to %s\n", buff);
sleep(1);
abort();
}
if (mdp->top == 0)
mdp->base = mdp->breakval = mapto;
mdp->top = PAGE_ALIGN((char *) mdp->breakval + size);
result = (void *) mdp->breakval;
mdp->breakval = (char *) mdp->breakval + size;
} else {
result = (void *) mdp->breakval;
mdp->breakval = (char *) mdp->breakval + size;
}
}
return (result);
}
unsigned long
load_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
bd_t *bp)
{
#ifdef INTERACTIVE_CONSOLE
int timer = 0;
char ch;
#endif
char *cp;
int zimage_size;
unsigned long initrd_size;
/* First, capture the embedded board information. Then
* initialize the serial console port.
*/
embed_config(&bp);
com_port = serial_init(0, bp);
/* copy board data */
if (bp)
memcpy(hold_residual,bp,sizeof(bd_t));
/* Set end of memory available to us. It is always the highest
* memory address provided by the board information.
*/
end_avail = (char *)(bp->bi_memsize);
puts("\nloaded at: "); puthex(load_addr);
puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
if ( (unsigned long)load_addr != (unsigned long)&start ) {
puts("relocated to: "); puthex((unsigned long)&start);
puts(" ");
puthex((unsigned long)((unsigned long)&start + (4*num_words)));
puts("\n");
}
if ( bp ) {
puts("board data at: "); puthex((unsigned long)bp);
puts(" ");
puthex((unsigned long)((unsigned long)bp + sizeof(bd_t)));
puts("\nrelocated to: ");
puthex((unsigned long)hold_residual);
puts(" ");
puthex((unsigned long)((unsigned long)hold_residual + sizeof(bd_t)));
puts("\n");
}
/*
* We link ourself to an arbitrary low address. When we run, we
* relocate outself to that address. __image_being points to
* the part of the image where the zImage is. -- Tom
*/
zimage_start = (char *)(unsigned long)(&__image_begin);
zimage_size = (unsigned long)(&__image_end) -
(unsigned long)(&__image_begin);
initrd_size = (unsigned long)(&__ramdisk_end) -
(unsigned long)(&__ramdisk_begin);
/*
* The zImage and initrd will be between start and _end, so they've
* already been moved once. We're good to go now. -- Tom
*/
puts("zimage at: "); puthex((unsigned long)zimage_start);
puts(" "); puthex((unsigned long)(zimage_size+zimage_start));
puts("\n");
if ( initrd_size ) {
puts("initrd at: ");
puthex((unsigned long)(&__ramdisk_begin));
puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n");
}
/*
* setup avail_ram - this is the first part of ram usable
* by the uncompress code. Anything after this program in RAM
* is now fair game. -- Tom
*/
avail_ram = (char *)PAGE_ALIGN((unsigned long)_end);
puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" ");
puthex((unsigned long)end_avail); puts("\n");
puts("\nLinux/PPC load: ");
cp = cmd_line;
/* This is where we try and pick the right command line for booting.
* If we were given one at compile time, use it. It Is Right.
* If we weren't, see if we have a ramdisk. If so, thats root.
* When in doubt, give them the netroot (root=/dev/nfs rw) -- Tom
*/
#ifdef CONFIG_CMDLINE_BOOL
memcpy (cmd_line, compiled_string, sizeof(compiled_string));
#else
if ( initrd_size )
memcpy (cmd_line, ramroot_string, sizeof(ramroot_string));
else
memcpy (cmd_line, netroot_string, sizeof(netroot_string));
#endif
while ( *cp )
putc(*cp++);
#ifdef INTERACTIVE_CONSOLE
//.........这里部分代码省略.........
/*
* paging_init() continues the virtual memory environment setup which
* was begun by the code in arch/head.S.
*/
void __init paging_init(void)
{
unsigned long zones_size[MAX_NR_ZONES] = { 0, };
unsigned long min_addr, max_addr;
unsigned long addr, size, end;
int i;
#ifdef DEBUG
printk ("start of paging_init (%p, %lx)\n", kernel_pg_dir, availmem);
#endif
/* Fix the cache mode in the page descriptors for the 680[46]0. */
if (CPU_IS_040_OR_060) {
int i;
#ifndef mm_cachebits
mm_cachebits = _PAGE_CACHE040;
#endif
for (i = 0; i < 16; i++)
pgprot_val(protection_map[i]) |= _PAGE_CACHE040;
}
min_addr = m68k_memory[0].addr;
max_addr = min_addr + m68k_memory[0].size;
for (i = 1; i < m68k_num_memory;) {
if (m68k_memory[i].addr < min_addr) {
printk("Ignoring memory chunk at 0x%lx:0x%lx before the first chunk\n",
m68k_memory[i].addr, m68k_memory[i].size);
printk("Fix your bootloader or use a memfile to make use of this area!\n");
m68k_num_memory--;
memmove(m68k_memory + i, m68k_memory + i + 1,
(m68k_num_memory - i) * sizeof(struct mem_info));
continue;
}
addr = m68k_memory[i].addr + m68k_memory[i].size;
if (addr > max_addr)
max_addr = addr;
i++;
}
m68k_memoffset = min_addr - PAGE_OFFSET;
m68k_virt_to_node_shift = fls(max_addr - min_addr - 1) - 6;
module_fixup(NULL, __start_fixup, __stop_fixup);
flush_icache();
high_memory = phys_to_virt(max_addr);
min_low_pfn = availmem >> PAGE_SHIFT;
max_low_pfn = max_addr >> PAGE_SHIFT;
for (i = 0; i < m68k_num_memory; i++) {
addr = m68k_memory[i].addr;
end = addr + m68k_memory[i].size;
m68k_setup_node(i);
availmem = PAGE_ALIGN(availmem);
availmem += init_bootmem_node(NODE_DATA(i),
availmem >> PAGE_SHIFT,
addr >> PAGE_SHIFT,
end >> PAGE_SHIFT);
}
/*
* Map the physical memory available into the kernel virtual
* address space. First initialize the bootmem allocator with
* the memory we already mapped, so map_node() has something
* to allocate.
*/
addr = m68k_memory[0].addr;
size = m68k_memory[0].size;
free_bootmem_node(NODE_DATA(0), availmem, min(INIT_MAPPED_SIZE, size) - (availmem - addr));
map_node(0);
if (size > INIT_MAPPED_SIZE)
free_bootmem_node(NODE_DATA(0), addr + INIT_MAPPED_SIZE, size - INIT_MAPPED_SIZE);
for (i = 1; i < m68k_num_memory; i++)
map_node(i);
flush_tlb_all();
/*
* initialize the bad page table and bad page to point
* to a couple of allocated pages
*/
empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
memset(empty_zero_page, 0, PAGE_SIZE);
/*
* Set up SFC/DFC registers
*/
set_fs(KERNEL_DS);
#ifdef DEBUG
printk ("before free_area_init\n");
#endif
for (i = 0; i < m68k_num_memory; i++) {
zones_size[ZONE_DMA] = m68k_memory[i].size >> PAGE_SHIFT;
free_area_init_node(i, pg_data_map + i, zones_size,
//.........这里部分代码省略.........
static int busname_peek_message(BusName *n) {
struct kdbus_cmd_recv cmd_recv = {
.size = sizeof(cmd_recv),
.flags = KDBUS_RECV_PEEK,
};
struct kdbus_cmd_free cmd_free = {
.size = sizeof(cmd_free),
};
const char *comm = NULL;
struct kdbus_item *d;
struct kdbus_msg *k;
size_t start, ps, sz, delta;
void *p = NULL;
pid_t pid = 0;
int r;
/* Generate a friendly debug log message about which process
* caused triggering of this bus name. This simply peeks the
* metadata of the first queued message and logs it. */
assert(n);
/* Let's shortcut things a bit, if debug logging is turned off
* anyway. */
if (log_get_max_level() < LOG_DEBUG)
return 0;
r = ioctl(n->starter_fd, KDBUS_CMD_RECV, &cmd_recv);
if (r < 0) {
if (errno == EINTR || errno == EAGAIN)
return 0;
return log_unit_error_errno(UNIT(n), errno, "Failed to query activation message: %m");
}
/* We map as late as possible, and unmap imemdiately after
* use. On 32bit address space is scarce and we want to be
* able to handle a lot of activator connections at the same
* time, and hence shouldn't keep the mmap()s around for
* longer than necessary. */
ps = page_size();
start = (cmd_recv.msg.offset / ps) * ps;
delta = cmd_recv.msg.offset - start;
sz = PAGE_ALIGN(delta + cmd_recv.msg.msg_size);
p = mmap(NULL, sz, PROT_READ, MAP_SHARED, n->starter_fd, start);
if (p == MAP_FAILED) {
r = log_unit_error_errno(UNIT(n), errno, "Failed to map activation message: %m");
goto finish;
}
k = (struct kdbus_msg *) ((uint8_t *) p + delta);
KDBUS_ITEM_FOREACH(d, k, items) {
switch (d->type) {
case KDBUS_ITEM_PIDS:
pid = d->pids.pid;
break;
case KDBUS_ITEM_PID_COMM:
comm = d->str;
break;
}
}
if (pid > 0)
log_unit_debug(UNIT(n), "Activation triggered by process " PID_FMT " (%s)", pid, strna(comm));
r = 0;
finish:
if (p)
(void) munmap(p, sz);
cmd_free.offset = cmd_recv.msg.offset;
if (ioctl(n->starter_fd, KDBUS_CMD_FREE, &cmd_free) < 0)
log_unit_warning(UNIT(n), "Failed to free peeked message, ignoring: %m");
return r;
}
static int busname_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
BusName *n = userdata;
assert(n);
assert(fd >= 0);
if (n->state != BUSNAME_LISTENING)
return 0;
log_unit_debug(UNIT(n), "Activation request");
if (revents != EPOLLIN) {
log_unit_error(UNIT(n), "Got unexpected poll event (0x%x) on starter fd.", revents);
goto fail;
}
busname_peek_message(n);
//.........这里部分代码省略.........
请发表评论