--- /dev/null
+ org 0x0
+[bits 16]
+entry:
+; mov al, 0x01 ; Say where we are.
+; out 0x80, al
+ mov ax, 0xA800
+ mov ds, ax ; Take us out of flat unreal mode, and
+ mov es, ax ; put us in true real mode.
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+ jmp 0xA800:entry2 ; Long jump to a correct cs.
+entry2:
+; mov al, 0x02
+; out 0x80, al
+ lgdt [gdtr] ; Set up a new GDT.
+ mov eax, 0x1
+ mov cr0, eax ; ... and enter pmode!
+ mov al, 0x03 ; Say we got here.
+ out 0x80, al
+ jmp long 0x10:(continue+0xA8000) ; Now longjmp into the new code.
+[bits 32]
+continue:
+; mov al, 0x04 ; Now we're in protected mode.
+; out 0x80, al
+
+ mov ax, 0x08 ; Set up segment selectors.
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+ mov esp, 0x1fffffff
+
+; mov al, 0x05
+; out 0x80, al
+
+ mov al, [(cstat + 0xA8000)]
+ add al, 1
+ out 0x80, al
+ mov [(cstat + 0xA8000)], al
+
+ mov eax, 0x11223344
+ mov dword [(status + 0xA8000)], eax
+
+ mov dx, 0xCF8 ; save off the old config value
+ in dword eax, dx
+ mov [esp-4], eax
+
+ mov eax, 0x80000070 ; load in smramc
+ out dx, eax
+ mov dx, 0xCFC
+ in byte al, dx
+ mov [esp-5], al
+ and al, 0xF3 ; Allow graphics access
+ or al, 0x08
+ out dx, al
+
+ xor eax, eax
+ mov dx, 0x3D4
+ in byte al, dx
+ mov [esp-6], al ; save off the old VGA command
+ mov al, 0xC
+ out dx, al
+ inc dx
+ in al, dx
+ mov ah, al
+ dec dx
+ mov al, 0xD
+ out dx, al
+ inc dx
+ in al, dx
+ shl eax, 1
+ add eax, 0xB8000 ; yay
+ mov byte [eax+0], '1'
+ mov byte [eax+1], 0xA0
+ mov byte [eax+2], '5'
+ mov byte [eax+3], 0xA0
+ mov byte [eax+4], '-'
+ mov byte [eax+5], 0xA0
+ mov byte [eax+6], '4'
+ mov byte [eax+7], 0xA0
+ mov byte [eax+8], '1'
+ mov byte [eax+9], 0xA0
+ mov byte [eax+10], '2'
+ mov byte [eax+11], 0xA0
+
+ mov dx, 0x3D4
+ mov al, [esp-6]
+ out dx, al
+
+
+ mov dx, 0xCFC ; restore smramc
+ mov al, [esp-5]
+ out dx, al
+
+ mov dx, 0xCF8 ; restore the old config value
+ mov eax, [esp-4]
+ out dx, eax
+
+ mov al, 0x40 ; ack the periodic IRQ
+ mov dx, 0x834
+ out dx, al
+
+ mov dx, 0x830
+ in al, dx
+ or al, 0x02 ; now ack the SMI itself
+ and al, 0xBF
+ out dx, al
+ or al, 0x40
+ out dx, al
+
+ rsm ; and leave SMM
+
+ align 0x4
+gdtr:
+ db 0x27, 0x00
+ dd (gdt + 0xA8000)
+ align 0x4
+gdt:
+ db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ db 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x93, 0xCF, 0x00 ; data segment
+ db 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9B, 0xCF, 0x00 ; code segment
+ db 0xFF, 0xFF, 0x00, 0x80, 0x0A, 0x9B, 0xCF, 0x00 ; code segment for trampoline
+
+TIMES 512-($-$$) DB 0
+status:
+ dd 0xAA55AA55
+cstat:
+ db 0x00
--- /dev/null
+/*
+ * devmem2.c: Simple program to read/write from/to any location in memory.
+ *
+ * Copyright (C) 2000, Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
+ *
+ *
+ * This software has been developed for the LART computing board
+ * (http://www.lart.tudelft.nl/). The development has been sponsored by
+ * the Mobile MultiMedia Communications (http://www.mmc.tudelft.nl/)
+ * and Ubiquitous Communications (http://www.ubicom.tudelft.nl/)
+ * projects.
+ *
+ * The author can be reached at:
+ *
+ * Jan-Derk Bakker
+ * Information and Communication Theory Group
+ * Faculty of Information Technology and Systems
+ * Delft University of Technology
+ * P.O. Box 5031
+ * 2600 GA Delft
+ * The Netherlands
+ *
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <termios.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+
+#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \
+ __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0)
+
+#define MAP_SIZE 4096UL
+#define MAP_MASK (MAP_SIZE - 1)
+
+int main(int argc, char **argv) {
+
+ int fd, input_fd;
+
+ void *map_base, *virt_addr;
+ unsigned long read_result, writeval;
+ off_t target;
+ int access_type = 'w';
+
+ if(argc < 3) {
+ fprintf(stderr, "\nUsage:\t%s { address } { file }\n"
+ "\taddress : memory address to act upon\n"
+ "\tfile : file to load\n\n", argv[0]);
+ exit(1);
+ }
+
+ input_fd = open(argv[2], O_RDONLY);
+ if (input_fd < 0) FATAL;
+
+ struct stat st;
+ if (fstat(input_fd, &st) < 0) FATAL;
+
+ char * buf = malloc(st.st_size);
+ if (!buf) FATAL;
+ if (read(input_fd, buf, st.st_size) != st.st_size) FATAL;
+
+ target = strtoul(argv[1], 0, 0);
+
+ fd = open("/dev/mem", O_RDWR | O_SYNC);
+ if (fd < 0) FATAL;
+
+ printf("/dev/mem opened.\n");
+ fflush(stdout);
+
+ /* Map one page */
+ map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, target & ~MAP_MASK);
+
+ if (map_base == (void *) -1) FATAL;
+
+ printf("Memory mapped at address %p.\n", map_base);
+ fflush(stdout);
+
+ virt_addr = map_base + (target & MAP_MASK);
+ memcpy(virt_addr, buf, st.st_size);
+
+ printf("Copied %d bytes.\n", st.st_size);
+
+ return 0;
+}