serial.S 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. /* https://github.com/cirosantilli/x86-bare-metal-examples#serial-uart */
  2. #include "common.h"
  3. #define PORT 0x3f8
  4. BEGIN
  5. /* Initialize the serial. */
  6. /* Disable all interrupts */
  7. mov 0x00, %al
  8. mov $(PORT + 1), %dx
  9. out %al, %dx
  10. /* Enable DLAB (set baud rate divisor) */
  11. mov 0x80, %al
  12. mov $(PORT + 3), %dx
  13. out %al, %dx
  14. /* Set divisor to 3 (lo byte) 38400 baud */
  15. mov 0x03, %al
  16. mov $(PORT + 0), %dx
  17. out %al, %dx
  18. /* Set divisor to 3 (hi byte) 38400 baud */
  19. mov 0x00, %al
  20. mov $(PORT + 1), %dx
  21. out %al, %dx
  22. /* 8 bits, no parity, one stop bit */
  23. mov 0x03, %al
  24. mov $(PORT + 3), %dx
  25. out %al, %dx
  26. /* Enable FIFO, clear them, with 14-byte threshold */
  27. mov 0xC7, %al
  28. mov $(PORT + 2), %dx
  29. out %al, %dx
  30. /* IRQs enabled, RTS/DSR set */
  31. mov 0x0B, %al
  32. mov $(PORT + 4), %dx
  33. out %al, %dx
  34. mov $(PORT + 0), %dx
  35. mov $msg, %si
  36. .Lloop:
  37. /* is_transmit_empty */
  38. mov $(PORT + 5), %dx
  39. inb %dx
  40. and $0x20, %al
  41. jz .Lloop
  42. /* Read value and check if NUL. */
  43. lodsb
  44. mov $0x01, %ah
  45. or %al, %al
  46. jz .Lhalt
  47. /* Send value to serial. */
  48. out %al, %dx
  49. /* Stop in infinite loop. */
  50. jmp .Lloop
  51. .Lhalt:
  52. hlt
  53. jmp .Lhalt
  54. msg:
  55. .asciz "hello world\n"