[coreboot] I'm not able to extract the VGA BIOS from phoenix BIOS

Peter Stuge peter at stuge.se
Fri Apr 30 01:56:57 CEST 2010


Joop Boonen wrote:
> > If it has a ROM on it you should be able to read it out. (Note that
> > the address reported by lspci may actually not be correct, I don't
> > know why, but you may need to read the expansion rom BAR directly
> > to get the correct address: (I thought this is what lspci does, but no)
> >
> > setpci -s 1:6 30.l
> >
> > Then mmap /dev/mem (see flashrom physmap.c for an example) and read
> > out the block. I hacked up something to do this a few weeks ago, let
> > me know if you want it.
> 
> Can I please have the hacked code, than I can test it.

As was already pointed out, since you have the option ROM for the
graphics card in your regular BIOS image, you don't need to do this
anymore, but here's the tool anyway: http://stuge.se/physrd.c


//Peter
-------------- next part --------------
/* compile: gcc -o physrd physrd.c
 * run: ./physrd 0xphysical_address 0xsize output.bin
 */
/*
 * This program is based on physmap.c in the flashrom project.
 *
 * Copyright (C) 2009, 2010 Peter Stuge <peter at stuge.se>
 * Copyright (C) 2009 coresystems GmbH
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 */

#define printf_debug printf

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#ifdef __DARWIN__
#include <DirectIO/darwinio.h>

#define MEM_DEV "DirectIO"

void *sys_physmap(unsigned long phys_addr, size_t len)
{
	return map_physical(phys_addr, len);
}

void physunmap(void *virt_addr, size_t len)
{
	unmap_physical(virt_addr, len);
}

#else
#include <sys/mman.h>

#if defined (__sun) && (defined(__i386) || defined(__amd64))
#  define MEM_DEV "/dev/xsvc"
#else
#  define MEM_DEV "/dev/mem"
#endif

static int fd_mem = -1;

void *sys_physmap(unsigned long phys_addr, size_t len)
{
	void *virt_addr;

	if (-1 == fd_mem) {
		/* Open the memory device UNCACHED. Important for MMIO. */
		if (-1 == (fd_mem = open(MEM_DEV, O_RDWR | O_SYNC))) {
			perror("Critical error: open(" MEM_DEV ")");
			return NULL;
		}
	}

	virt_addr = mmap(0, len, PROT_WRITE | PROT_READ, MAP_SHARED,
			 fd_mem, (off_t)phys_addr);
	return MAP_FAILED == virt_addr ? NULL : virt_addr;
}

void physunmap(void *virt_addr, size_t len)
{
	if (len == 0) {
		printf("Not unmapping zero size at %p\n", virt_addr);
		return;
	}
		
	munmap(virt_addr, len);
}
#endif

void *physmap(const char *descr, unsigned long phys_addr, size_t len)
{
	void *virt_addr;

	if (len == 0) {
		printf_debug("Not mapping %s, zero size at 0x%08lx.\n",
			     descr, phys_addr);
		return NULL;
	}
		
	if ((getpagesize() - 1) & len) {
		fprintf(stderr, "Mapping %s at 0x%08lx, unaligned size 0x%lx.\n",
			descr, phys_addr, (unsigned long)len);
	}

	if ((getpagesize() - 1) & phys_addr) {
		fprintf(stderr, "Mapping %s, 0x%lx bytes at unaligned 0x%08lx.\n",
			descr, (unsigned long)len, phys_addr);
	}

	virt_addr = sys_physmap(phys_addr, len);

	if (NULL == virt_addr) {
		if (NULL == descr)
			descr = "memory";
		fprintf(stderr, "Error accessing %s, 0x%lx bytes at 0x%08lx\n", descr, (unsigned long)len, phys_addr);
		perror(MEM_DEV " mmap failed");
		if (EINVAL == errno) {
			fprintf(stderr, "In Linux this error can be caused by the CONFIG_NONPROMISC_DEVMEM (<2.6.27),\n");
			fprintf(stderr, "CONFIG_STRICT_DEVMEM (>=2.6.27) and CONFIG_X86_PAT kernel options.\n");
			fprintf(stderr, "Please check if either is enabled in your kernel before reporting a failure.\n");
			fprintf(stderr, "You can override CONFIG_X86_PAT at boot with the nopat kernel parameter but\n");
			fprintf(stderr, "disabling the other option unfortunately requires a kernel recompile. Sorry!\n");
		}
	}

	return virt_addr;
}

int main(int argc,char *argv[]) {
  void *mem;
  unsigned long addr,len;
  FILE *f;
  if(4!=argc) {
    fprintf(stderr,"syntax: ./physrd physical_address size output.bin\n");
    return 1;
  }
  addr=strtoul(argv[1],NULL,0);
  len=strtoul(argv[2],NULL,0);
  if(NULL==(mem=physmap("memory",addr,len)))
    return 1;
  if(NULL==(f=fopen(argv[3],"wb"))) {
    perror("fopen");
    return 1;
  }
  fwrite(mem,1,len,f);
  physunmap(mem,len);
  fclose(f);
  return 0; 
}


More information about the coreboot mailing list